]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.runtime/tests/org/simantics/scl/runtime/tests/TestCHRHashIndex.java
Merge "List the unsatisfied dependencies in CanvasContext"
[simantics/platform.git] / bundles / org.simantics.scl.runtime / tests / org / simantics / scl / runtime / tests / TestCHRHashIndex.java
1 package org.simantics.scl.runtime.tests;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collections;\r
5 import java.util.LinkedHashSet;\r
6 import java.util.List;\r
7 import java.util.Random;\r
8 \r
9 import org.junit.Assert;\r
10 import org.junit.Before;\r
11 import org.junit.Test;\r
12 import org.simantics.scl.runtime.chr.CHRHashIndex;\r
13 \r
14 import gnu.trove.map.hash.TIntObjectHashMap;\r
15 import gnu.trove.set.hash.THashSet;\r
16 import gnu.trove.set.hash.TIntHashSet;\r
17 \r
18 public class TestCHRHashIndex {\r
19     \r
20     Random random;\r
21     Store store;\r
22     Store2 store2;\r
23     THashSet<Fact> aliveFacts = new THashSet<Fact>(); \r
24     \r
25     public static class Store {\r
26         CHRHashIndex bfIndex = new CHRHashIndex() {\r
27             @Override\r
28             protected boolean keyEquals(Object a, Object b) {\r
29                 return ((Fact)a).a == ((Fact)b).a;\r
30             }\r
31             @Override\r
32             protected int keyHashCode(Object key) {\r
33                 return ((Fact)key).a;\r
34             }\r
35         };\r
36     }\r
37     \r
38     public static class Store2 {\r
39         TIntObjectHashMap<LinkedHashSet<Fact>> bfIndex = new TIntObjectHashMap<LinkedHashSet<Fact>>(); \r
40     }\r
41     \r
42     public static class Fact {\r
43         public int a; // key\r
44         public int b;\r
45         public Fact bfPrev;\r
46         public Fact bfNext;\r
47         \r
48         public Fact(int a, int b) {\r
49             this.a = a;\r
50             this.b = b;\r
51         }\r
52         \r
53         public void add(Store store) {\r
54             bfNext = (Fact)store.bfIndex.addFreshAndReturnOld(this);\r
55             if(bfNext != null)\r
56                 bfNext.bfPrev = this;\r
57         }\r
58         \r
59         public void remove(Store store) {\r
60             if(bfPrev == null) {\r
61                 if(bfNext == null)\r
62                     store.bfIndex.removeKnownToExistKey(this);\r
63                 else {\r
64                     bfNext.bfPrev = null;\r
65                     store.bfIndex.replaceKnownToExistKey(this, bfNext);\r
66                 }\r
67             }\r
68             else {\r
69                 bfPrev.bfNext = bfNext;\r
70                 if(bfNext != null)\r
71                     bfNext.bfPrev = bfPrev;\r
72             }\r
73         }\r
74         \r
75         public List<Fact> get(Store store) {\r
76             Object r = store.bfIndex.getEqual(this);\r
77             if(r == null)\r
78                 return Collections.emptyList();\r
79             else {\r
80                 ArrayList<Fact> result = new ArrayList<Fact>(); \r
81                 for(Fact cur=(Fact)r;cur!=null;cur=cur.bfNext)\r
82                     result.add(cur);\r
83                 Collections.reverse(result);\r
84                 return result;\r
85             }\r
86         }\r
87         \r
88         public void add(Store2 store) {\r
89             LinkedHashSet<Fact> set = store.bfIndex.get(a);\r
90             if(set == null) {\r
91                 set = new LinkedHashSet<>();\r
92                 store.bfIndex.put(a, set);\r
93             }\r
94             set.add(this);\r
95         }\r
96         \r
97         public void remove(Store2 store) {\r
98             store.bfIndex.get(a).remove(this);\r
99         }\r
100         \r
101         public List<Fact> get(Store2 store) {\r
102             LinkedHashSet<Fact> set = store.bfIndex.get(a);\r
103             if(set == null)\r
104                 return Collections.emptyList();\r
105             else\r
106                 return new ArrayList<Fact>(set);\r
107         }\r
108     }\r
109     \r
110     @Before\r
111     public void init() {\r
112         random = new Random(123L);\r
113         store = new Store();\r
114         store2 = new Store2();\r
115     }\r
116     \r
117     public Fact createFact(int maxA, int maxB) {\r
118         return new Fact(random.nextInt(maxA), random.nextInt(maxB));\r
119     }\r
120     \r
121     public void add(Fact fact) {\r
122         fact.add(store);\r
123         fact.add(store2);\r
124         aliveFacts.add(fact);\r
125     }\r
126     \r
127     public void remove(Fact fact) {\r
128         fact.remove(store);\r
129         fact.remove(store2);\r
130         aliveFacts.remove(fact);\r
131     }\r
132     \r
133     public void checkConsistency() {\r
134         TIntHashSet keys = new TIntHashSet();\r
135         for(Fact fact : aliveFacts)\r
136             keys.add(fact.a);\r
137         Fact temp = new Fact(0, 0);\r
138         for(int a : keys.toArray()) {\r
139             temp.a = a;\r
140             Assert.assertEquals(temp.get(store2), temp.get(store));\r
141         }\r
142         TIntHashSet keys2 = new TIntHashSet();\r
143         for(Fact fact : store.bfIndex.toArray(new Fact[keys.size()]))\r
144             keys2.add(fact.a);\r
145         Assert.assertEquals(keys, keys2);\r
146     }\r
147     \r
148     @Test\r
149     public void testStore() {\r
150         for(int i=0;;++i) {\r
151             System.out.println("Run " + i);\r
152             for(int j=0;j<1000000;++j)\r
153                 add(createFact(10000, 1000000));\r
154             checkConsistency();\r
155             ArrayList<Fact> factArray = new ArrayList<Fact>(aliveFacts);\r
156             Collections.shuffle(factArray, random);\r
157             for(Fact fact : factArray.subList(100000, factArray.size()))\r
158                 remove(fact);\r
159             checkConsistency();\r
160         }\r
161     }\r
162     \r
163 }\r