1 package org.simantics.scl.runtime.tests;
\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
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
14 import gnu.trove.map.hash.TIntObjectHashMap;
\r
15 import gnu.trove.set.hash.THashSet;
\r
16 import gnu.trove.set.hash.TIntHashSet;
\r
18 public class TestCHRHashIndex {
\r
23 THashSet<Fact> aliveFacts = new THashSet<Fact>();
\r
25 public static class Store {
\r
26 CHRHashIndex bfIndex = new CHRHashIndex() {
\r
28 protected boolean keyEquals(Object a, Object b) {
\r
29 return ((Fact)a).a == ((Fact)b).a;
\r
32 protected int keyHashCode(Object key) {
\r
33 return ((Fact)key).a;
\r
38 public static class Store2 {
\r
39 TIntObjectHashMap<LinkedHashSet<Fact>> bfIndex = new TIntObjectHashMap<LinkedHashSet<Fact>>();
\r
42 public static class Fact {
\r
43 public int a; // key
\r
48 public Fact(int a, int b) {
\r
53 public void add(Store store) {
\r
54 bfNext = (Fact)store.bfIndex.addFreshAndReturnOld(this);
\r
56 bfNext.bfPrev = this;
\r
59 public void remove(Store store) {
\r
60 if(bfPrev == null) {
\r
62 store.bfIndex.removeKnownToExistKey(this);
\r
64 bfNext.bfPrev = null;
\r
65 store.bfIndex.replaceKnownToExistKey(this, bfNext);
\r
69 bfPrev.bfNext = bfNext;
\r
71 bfNext.bfPrev = bfPrev;
\r
75 public List<Fact> get(Store store) {
\r
76 Object r = store.bfIndex.getEqual(this);
\r
78 return Collections.emptyList();
\r
80 ArrayList<Fact> result = new ArrayList<Fact>();
\r
81 for(Fact cur=(Fact)r;cur!=null;cur=cur.bfNext)
\r
83 Collections.reverse(result);
\r
88 public void add(Store2 store) {
\r
89 LinkedHashSet<Fact> set = store.bfIndex.get(a);
\r
91 set = new LinkedHashSet<>();
\r
92 store.bfIndex.put(a, set);
\r
97 public void remove(Store2 store) {
\r
98 store.bfIndex.get(a).remove(this);
\r
101 public List<Fact> get(Store2 store) {
\r
102 LinkedHashSet<Fact> set = store.bfIndex.get(a);
\r
104 return Collections.emptyList();
\r
106 return new ArrayList<Fact>(set);
\r
111 public void init() {
\r
112 random = new Random(123L);
\r
113 store = new Store();
\r
114 store2 = new Store2();
\r
117 public Fact createFact(int maxA, int maxB) {
\r
118 return new Fact(random.nextInt(maxA), random.nextInt(maxB));
\r
121 public void add(Fact fact) {
\r
124 aliveFacts.add(fact);
\r
127 public void remove(Fact fact) {
\r
128 fact.remove(store);
\r
129 fact.remove(store2);
\r
130 aliveFacts.remove(fact);
\r
133 public void checkConsistency() {
\r
134 TIntHashSet keys = new TIntHashSet();
\r
135 for(Fact fact : aliveFacts)
\r
137 Fact temp = new Fact(0, 0);
\r
138 for(int a : keys.toArray()) {
\r
140 Assert.assertEquals(temp.get(store2), temp.get(store));
\r
142 TIntHashSet keys2 = new TIntHashSet();
\r
143 for(Fact fact : store.bfIndex.toArray(new Fact[keys.size()]))
\r
145 Assert.assertEquals(keys, keys2);
\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
159 checkConsistency();
\r