-package org.simantics.scl.runtime.tests;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.LinkedHashSet;\r
-import java.util.List;\r
-import java.util.Random;\r
-\r
-import org.junit.Assert;\r
-import org.junit.Before;\r
-import org.junit.Test;\r
-import org.simantics.scl.runtime.chr.CHRHashIndex;\r
-\r
-import gnu.trove.map.hash.TIntObjectHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class TestCHRHashIndex {\r
- \r
- Random random;\r
- Store store;\r
- Store2 store2;\r
- THashSet<Fact> aliveFacts = new THashSet<Fact>(); \r
- \r
- public static class Store {\r
- CHRHashIndex bfIndex = new CHRHashIndex() {\r
- @Override\r
- protected boolean keyEquals(Object a, Object b) {\r
- return ((Fact)a).a == ((Fact)b).a;\r
- }\r
- @Override\r
- protected int keyHashCode(Object key) {\r
- return ((Fact)key).a;\r
- }\r
- };\r
- }\r
- \r
- public static class Store2 {\r
- TIntObjectHashMap<LinkedHashSet<Fact>> bfIndex = new TIntObjectHashMap<LinkedHashSet<Fact>>(); \r
- }\r
- \r
- public static class Fact {\r
- public int a; // key\r
- public int b;\r
- public Fact bfPrev;\r
- public Fact bfNext;\r
- \r
- public Fact(int a, int b) {\r
- this.a = a;\r
- this.b = b;\r
- }\r
- \r
- public void add(Store store) {\r
- bfNext = (Fact)store.bfIndex.addFreshAndReturnOld(this);\r
- if(bfNext != null)\r
- bfNext.bfPrev = this;\r
- }\r
- \r
- public void remove(Store store) {\r
- if(bfPrev == null) {\r
- if(bfNext == null)\r
- store.bfIndex.removeKnownToExistKey(this);\r
- else {\r
- bfNext.bfPrev = null;\r
- store.bfIndex.replaceKnownToExistKey(this, bfNext);\r
- }\r
- }\r
- else {\r
- bfPrev.bfNext = bfNext;\r
- if(bfNext != null)\r
- bfNext.bfPrev = bfPrev;\r
- }\r
- }\r
- \r
- public List<Fact> get(Store store) {\r
- Object r = store.bfIndex.getEqual(this);\r
- if(r == null)\r
- return Collections.emptyList();\r
- else {\r
- ArrayList<Fact> result = new ArrayList<Fact>(); \r
- for(Fact cur=(Fact)r;cur!=null;cur=cur.bfNext)\r
- result.add(cur);\r
- Collections.reverse(result);\r
- return result;\r
- }\r
- }\r
- \r
- public void add(Store2 store) {\r
- LinkedHashSet<Fact> set = store.bfIndex.get(a);\r
- if(set == null) {\r
- set = new LinkedHashSet<>();\r
- store.bfIndex.put(a, set);\r
- }\r
- set.add(this);\r
- }\r
- \r
- public void remove(Store2 store) {\r
- store.bfIndex.get(a).remove(this);\r
- }\r
- \r
- public List<Fact> get(Store2 store) {\r
- LinkedHashSet<Fact> set = store.bfIndex.get(a);\r
- if(set == null)\r
- return Collections.emptyList();\r
- else\r
- return new ArrayList<Fact>(set);\r
- }\r
- }\r
- \r
- @Before\r
- public void init() {\r
- random = new Random(123L);\r
- store = new Store();\r
- store2 = new Store2();\r
- }\r
- \r
- public Fact createFact(int maxA, int maxB) {\r
- return new Fact(random.nextInt(maxA), random.nextInt(maxB));\r
- }\r
- \r
- public void add(Fact fact) {\r
- fact.add(store);\r
- fact.add(store2);\r
- aliveFacts.add(fact);\r
- }\r
- \r
- public void remove(Fact fact) {\r
- fact.remove(store);\r
- fact.remove(store2);\r
- aliveFacts.remove(fact);\r
- }\r
- \r
- public void checkConsistency() {\r
- TIntHashSet keys = new TIntHashSet();\r
- for(Fact fact : aliveFacts)\r
- keys.add(fact.a);\r
- Fact temp = new Fact(0, 0);\r
- for(int a : keys.toArray()) {\r
- temp.a = a;\r
- Assert.assertEquals(temp.get(store2), temp.get(store));\r
- }\r
- TIntHashSet keys2 = new TIntHashSet();\r
- for(Fact fact : store.bfIndex.toArray(new Fact[keys.size()]))\r
- keys2.add(fact.a);\r
- Assert.assertEquals(keys, keys2);\r
- }\r
- \r
- @Test\r
- public void testStore() {\r
- for(int i=0;;++i) {\r
- System.out.println("Run " + i);\r
- for(int j=0;j<1000000;++j)\r
- add(createFact(10000, 1000000));\r
- checkConsistency();\r
- ArrayList<Fact> factArray = new ArrayList<Fact>(aliveFacts);\r
- Collections.shuffle(factArray, random);\r
- for(Fact fact : factArray.subList(100000, factArray.size()))\r
- remove(fact);\r
- checkConsistency();\r
- }\r
- }\r
- \r
-}\r
+package org.simantics.scl.runtime.tests;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Random;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.simantics.scl.runtime.chr.CHRHashIndex;
+
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class TestCHRHashIndex {
+
+ Random random;
+ Store store;
+ Store2 store2;
+ THashSet<Fact> aliveFacts = new THashSet<Fact>();
+
+ public static class Store {
+ CHRHashIndex bfIndex = new CHRHashIndex() {
+ @Override
+ protected boolean keyEquals(Object a, Object b) {
+ return ((Fact)a).a == ((Fact)b).a;
+ }
+ @Override
+ protected int keyHashCode(Object key) {
+ return ((Fact)key).a;
+ }
+ };
+ }
+
+ public static class Store2 {
+ TIntObjectHashMap<LinkedHashSet<Fact>> bfIndex = new TIntObjectHashMap<LinkedHashSet<Fact>>();
+ }
+
+ public static class Fact {
+ public int a; // key
+ public int b;
+ public Fact bfPrev;
+ public Fact bfNext;
+
+ public Fact(int a, int b) {
+ this.a = a;
+ this.b = b;
+ }
+
+ public void add(Store store) {
+ bfNext = (Fact)store.bfIndex.addFreshAndReturnOld(this);
+ if(bfNext != null)
+ bfNext.bfPrev = this;
+ }
+
+ public void remove(Store store) {
+ if(bfPrev == null) {
+ if(bfNext == null)
+ store.bfIndex.removeKnownToExistKey(this);
+ else {
+ bfNext.bfPrev = null;
+ store.bfIndex.replaceKnownToExistKey(this, bfNext);
+ }
+ }
+ else {
+ bfPrev.bfNext = bfNext;
+ if(bfNext != null)
+ bfNext.bfPrev = bfPrev;
+ }
+ }
+
+ public List<Fact> get(Store store) {
+ Object r = store.bfIndex.getEqual(this);
+ if(r == null)
+ return Collections.emptyList();
+ else {
+ ArrayList<Fact> result = new ArrayList<Fact>();
+ for(Fact cur=(Fact)r;cur!=null;cur=cur.bfNext)
+ result.add(cur);
+ Collections.reverse(result);
+ return result;
+ }
+ }
+
+ public void add(Store2 store) {
+ LinkedHashSet<Fact> set = store.bfIndex.get(a);
+ if(set == null) {
+ set = new LinkedHashSet<>();
+ store.bfIndex.put(a, set);
+ }
+ set.add(this);
+ }
+
+ public void remove(Store2 store) {
+ store.bfIndex.get(a).remove(this);
+ }
+
+ public List<Fact> get(Store2 store) {
+ LinkedHashSet<Fact> set = store.bfIndex.get(a);
+ if(set == null)
+ return Collections.emptyList();
+ else
+ return new ArrayList<Fact>(set);
+ }
+ }
+
+ @Before
+ public void init() {
+ random = new Random(123L);
+ store = new Store();
+ store2 = new Store2();
+ }
+
+ public Fact createFact(int maxA, int maxB) {
+ return new Fact(random.nextInt(maxA), random.nextInt(maxB));
+ }
+
+ public void add(Fact fact) {
+ fact.add(store);
+ fact.add(store2);
+ aliveFacts.add(fact);
+ }
+
+ public void remove(Fact fact) {
+ fact.remove(store);
+ fact.remove(store2);
+ aliveFacts.remove(fact);
+ }
+
+ public void checkConsistency() {
+ TIntHashSet keys = new TIntHashSet();
+ for(Fact fact : aliveFacts)
+ keys.add(fact.a);
+ Fact temp = new Fact(0, 0);
+ for(int a : keys.toArray()) {
+ temp.a = a;
+ Assert.assertEquals(temp.get(store2), temp.get(store));
+ }
+ TIntHashSet keys2 = new TIntHashSet();
+ for(Fact fact : store.bfIndex.toArray(new Fact[keys.size()]))
+ keys2.add(fact.a);
+ Assert.assertEquals(keys, keys2);
+ }
+
+ @Test
+ public void testStore() {
+ for(int i=0;;++i) {
+ System.out.println("Run " + i);
+ for(int j=0;j<1000000;++j)
+ add(createFact(10000, 1000000));
+ checkConsistency();
+ ArrayList<Fact> factArray = new ArrayList<Fact>(aliveFacts);
+ Collections.shuffle(factArray, random);
+ for(Fact fact : factArray.subList(100000, factArray.size()))
+ remove(fact);
+ checkConsistency();
+ }
+ }
+
+}