aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-27 02:08:44 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-10-03 20:06:52 +0200
commit7a310819cbbdd70767a9ed17e1bf84c2add9faed (patch)
treea381add842a69115d778ac902b47b40159a7feaf /subprojects/store
parentrefactor: remove viatra dependency from store (diff)
downloadrefinery-7a310819cbbdd70767a9ed17e1bf84c2add9faed.tar.gz
refinery-7a310819cbbdd70767a9ed17e1bf84c2add9faed.tar.zst
refinery-7a310819cbbdd70767a9ed17e1bf84c2add9faed.zip
refactor: tuples in QueryableModel
Diffstat (limited to 'subprojects/store')
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java1
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/Tuple.java148
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProvider.java3
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProviderBitMagic.java7
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java2
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java16
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java6
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java2
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java6
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java2
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java2
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple.java29
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple0.java25
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple1.java54
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple2.java27
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/tuple/TupleLike.java25
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/tuple/TupleN.java52
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java2
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/model/hashTests/HashEfficiencyTest.java18
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java2
22 files changed, 255 insertions, 187 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
index 97406cbb..b5e1c453 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
@@ -16,6 +16,7 @@ import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass;
16import tools.refinery.store.model.representation.AuxilaryData; 16import tools.refinery.store.model.representation.AuxilaryData;
17import tools.refinery.store.model.representation.DataRepresentation; 17import tools.refinery.store.model.representation.DataRepresentation;
18import tools.refinery.store.model.representation.Relation; 18import tools.refinery.store.model.representation.Relation;
19import tools.refinery.store.tuple.Tuple;
19 20
20import java.util.Set; 21import java.util.Set;
21 22
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/Tuple.java b/subprojects/store/src/main/java/tools/refinery/store/model/Tuple.java
deleted file mode 100644
index 0aae3727..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/model/Tuple.java
+++ /dev/null
@@ -1,148 +0,0 @@
1package tools.refinery.store.model;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.List;
6
7public abstract class Tuple {
8 private static final int CUSTOMTUPLESIZE = 2;
9 protected static final List<Tuple1> tuple1Cash = new ArrayList<>(1024);
10
11 public abstract int getSize();
12 public abstract int get(int element);
13 public abstract int[] toArray();
14
15 @Override
16 public String toString() {
17 StringBuilder b = new StringBuilder();
18 b.append("[");
19 for(int i = 0; i<getSize(); i++) {
20 if(i!=0) {
21 b.append(",");
22 }
23 b.append(get(i));
24 }
25 b.append("]");
26 return b.toString();
27 }
28
29 public static Tuple1 of1(int value) {
30 if(value < tuple1Cash.size()) {
31 return tuple1Cash.get(value);
32 } else {
33 Tuple1 newlyCreated = null;
34 while(value >= tuple1Cash.size()) {
35 newlyCreated = new Tuple1(tuple1Cash.size());
36 tuple1Cash.add(newlyCreated);
37 }
38 return newlyCreated;
39 }
40 }
41
42 public static Tuple of(int... values) {
43 if(values.length == 0) {
44 return new Tuple0();
45 } else if(values.length == 1) {
46 return of1(values[0]);
47 } else if(values.length == 2) {
48 return new Tuple2(values[0],values[1]);
49 } else return new TupleN(values);
50 }
51
52 protected IllegalArgumentException doesNotContain(int element) {
53 return new IllegalArgumentException("Tuple does not contain element "+element);
54 }
55
56 public static class Tuple0 extends Tuple{
57 protected Tuple0() { }
58 @Override public int getSize() { return 0; }
59 @Override public int get(int element) {
60 throw doesNotContain(element);
61 }
62 @Override public int[] toArray() {return new int[]{};}
63 @Override public int hashCode() { return TupleHashProvider.singleton().getHash(this, 0); }
64 @Override
65 public boolean equals(Object obj) {
66 if (this == obj)
67 return true;
68 if (obj == null)
69 return false;
70 if (getClass() != obj.getClass())
71 return false;
72 return true;
73 }
74 }
75 public static class Tuple1 extends Tuple{
76 final int value0;
77 protected Tuple1(int value0) { this.value0 = value0; }
78 @Override public int getSize() { return 1; }
79 @Override public int get(int element) {
80 if(element == 0) return value0;
81 throw doesNotContain(element);
82 }
83 @Override public int[] toArray() {return new int[]{ value0 };}
84 @Override public int hashCode() { return TupleHashProvider.singleton().getHash(this, 0); }
85 @Override
86 public boolean equals(Object obj) {
87 if (this == obj)
88 return true;
89 if (obj == null)
90 return false;
91 if (getClass() != obj.getClass())
92 return false;
93 Tuple1 other = (Tuple1) obj;
94 return value0 == other.value0;
95 }
96 }
97 public static class Tuple2 extends Tuple{
98 final int value0;
99 final int value1;
100 protected Tuple2(int value0, int value1) { this.value0 = value0; this.value1 = value1; }
101 @Override public int getSize() { return 2; }
102 @Override public int get(int element) {
103 if(element == 0) return value0;
104 else if(element == 1) return value1;
105 throw doesNotContain(element);
106 }
107 @Override public int[] toArray() {return new int[]{ value0,value1 };}
108 @Override public int hashCode() { return TupleHashProvider.singleton().getHash(this, 0); }
109 @Override
110 public boolean equals(Object obj) {
111 if (this == obj)
112 return true;
113 if (obj == null)
114 return false;
115 if (getClass() != obj.getClass())
116 return false;
117 Tuple2 other = (Tuple2) obj;
118 return value0 == other.value0 && value1 == other.value1;
119 }
120 }
121 public static class TupleN extends Tuple{
122 final int[] values;
123 protected TupleN(int[] values) {
124 if(values.length<CUSTOMTUPLESIZE)
125 throw new IllegalArgumentException();
126 this.values = Arrays.copyOf(values, values.length);
127 }
128 @Override public int getSize() { return values.length; }
129 @Override public int get(int element) {
130 if(0<=element && element < values.length) {
131 return values[element];
132 } else throw doesNotContain(element);
133 }
134 @Override public int[] toArray() { return values; }
135 @Override public int hashCode() { return TupleHashProvider.singleton().getHash(this, 0); }
136 @Override
137 public boolean equals(Object obj) {
138 if (this == obj)
139 return true;
140 if (obj == null)
141 return false;
142 if (getClass() != obj.getClass())
143 return false;
144 TupleN other = (TupleN) obj;
145 return Arrays.equals(values, other.values);
146 }
147 }
148}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProvider.java b/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProvider.java
index 7a01311a..988ce423 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProvider.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProvider.java
@@ -1,6 +1,7 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4import tools.refinery.store.tuple.Tuple;
4 5
5public class TupleHashProvider implements ContinousHashProvider<Tuple> { 6public class TupleHashProvider implements ContinousHashProvider<Tuple> {
6 protected static TupleHashProvider instance; 7 protected static TupleHashProvider instance;
@@ -39,7 +40,7 @@ public class TupleHashProvider implements ContinousHashProvider<Tuple> {
39 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 40 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637,
40 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 41 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793,
41 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911 }; 42 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911 };
42 43
43 protected static final long LARGESTPRIME30BITS = 1073741789; 44 protected static final long LARGESTPRIME30BITS = 1073741789;
44 45
45 public TupleHashProvider() { 46 public TupleHashProvider() {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProviderBitMagic.java b/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProviderBitMagic.java
index 5b053229..33059a1b 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProviderBitMagic.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/TupleHashProviderBitMagic.java
@@ -1,6 +1,7 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4import tools.refinery.store.tuple.Tuple;
4 5
5public class TupleHashProviderBitMagic implements ContinousHashProvider<Tuple> { 6public class TupleHashProviderBitMagic implements ContinousHashProvider<Tuple> {
6 7
@@ -9,12 +10,12 @@ public class TupleHashProviderBitMagic implements ContinousHashProvider<Tuple> {
9 if(key.getSize() == 1) { 10 if(key.getSize() == 1) {
10 return key.get(0); 11 return key.get(0);
11 } 12 }
12 13
13 int result = 0; 14 int result = 0;
14 final int startBitIndex = index*30; 15 final int startBitIndex = index*30;
15 final int finalBitIndex = startBitIndex+30; 16 final int finalBitIndex = startBitIndex+30;
16 final int arity = key.getSize(); 17 final int arity = key.getSize();
17 18
18 for(int i = startBitIndex; i<=finalBitIndex; i++) { 19 for(int i = startBitIndex; i<=finalBitIndex; i++) {
19 final int selectedKey = key.get(i%arity); 20 final int selectedKey = key.get(i%arity);
20 final int selectedPosition = 1<<(i/arity); 21 final int selectedPosition = 1<<(i/arity);
@@ -22,7 +23,7 @@ public class TupleHashProviderBitMagic implements ContinousHashProvider<Tuple> {
22 result |= 1<<(i%30); 23 result |= 1<<(i%30);
23 } 24 }
24 } 25 }
25 26
26 return result; 27 return result;
27 } 28 }
28} 29}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
index 9d1b1dd0..9939f17e 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
@@ -3,7 +3,7 @@ package tools.refinery.store.model.internal;
3import java.util.Objects; 3import java.util.Objects;
4 4
5import tools.refinery.store.map.ContinousHashProvider; 5import tools.refinery.store.map.ContinousHashProvider;
6import tools.refinery.store.model.Tuple; 6import tools.refinery.store.tuple.Tuple;
7import tools.refinery.store.model.representation.Relation; 7import tools.refinery.store.model.representation.Relation;
8 8
9public class SimilarRelationEquivalenceClass { 9public class SimilarRelationEquivalenceClass {
@@ -29,5 +29,5 @@ public class SimilarRelationEquivalenceClass {
29 return arity == other.arity && Objects.equals(defaultValue, other.defaultValue) 29 return arity == other.arity && Objects.equals(defaultValue, other.defaultValue)
30 && Objects.equals(hashProvider, other.hashProvider); 30 && Objects.equals(hashProvider, other.hashProvider);
31 } 31 }
32 32
33} 33}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
index fc2a3185..c0f31d08 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
@@ -1,6 +1,6 @@
1package tools.refinery.store.model.representation; 1package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.model.Tuple; 3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.TupleHashProvider; 4import tools.refinery.store.model.TupleHashProvider;
5 5
6public class Relation<D> extends DataRepresentation<Tuple, D> { 6public class Relation<D> extends DataRepresentation<Tuple, D> {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
index 187abbc2..648c3a36 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
@@ -2,12 +2,14 @@ package tools.refinery.store.query;
2 2
3import tools.refinery.store.model.Model; 3import tools.refinery.store.model.Model;
4import tools.refinery.store.query.building.DNFPredicate; 4import tools.refinery.store.query.building.DNFPredicate;
5import tools.refinery.store.tuple.Tuple;
6import tools.refinery.store.tuple.TupleLike;
5 7
6import java.util.Optional; 8import java.util.Optional;
7import java.util.Set; 9import java.util.Set;
8import java.util.stream.Stream; 10import java.util.stream.Stream;
9 11
10public interface QueryableModel extends Model{ 12public interface QueryableModel extends Model {
11 Set<DNFPredicate> getPredicates(); 13 Set<DNFPredicate> getPredicates();
12 14
13 boolean hasChanges(); 15 boolean hasChanges();
@@ -16,17 +18,17 @@ public interface QueryableModel extends Model{
16 18
17 boolean hasResult(DNFPredicate predicate); 19 boolean hasResult(DNFPredicate predicate);
18 20
19 boolean hasResult(DNFPredicate predicate, Object[] parameters); 21 boolean hasResult(DNFPredicate predicate, Tuple parameters);
20 22
21 Optional<Object[]> oneResult(DNFPredicate predicate); 23 Optional<TupleLike> oneResult(DNFPredicate predicate);
22 24
23 Optional<Object[]> oneResult(DNFPredicate predicate, Object[] parameters); 25 Optional<TupleLike> oneResult(DNFPredicate predicate, Tuple parameters);
24 26
25 Stream<Object[]> allResults(DNFPredicate predicate); 27 Stream<TupleLike> allResults(DNFPredicate predicate);
26 28
27 Stream<Object[]> allResults(DNFPredicate predicate, Object[] parameters); 29 Stream<TupleLike> allResults(DNFPredicate predicate, Tuple parameters);
28 30
29 int countResults(DNFPredicate predicate); 31 int countResults(DNFPredicate predicate);
30 32
31 int countResults(DNFPredicate predicate, Object[] parameters); 33 int countResults(DNFPredicate predicate, Tuple parameters);
32} 34}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
index 08efe17c..878e1058 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
@@ -1,6 +1,5 @@
1package tools.refinery.store.query; 1package tools.refinery.store.query;
2 2
3import tools.refinery.store.model.ModelDiffCursor;
4import tools.refinery.store.model.ModelStore; 3import tools.refinery.store.model.ModelStore;
5import tools.refinery.store.model.representation.DataRepresentation; 4import tools.refinery.store.model.representation.DataRepresentation;
6import tools.refinery.store.query.building.DNFPredicate; 5import tools.refinery.store.query.building.DNFPredicate;
@@ -8,16 +7,16 @@ import tools.refinery.store.query.view.RelationView;
8 7
9import java.util.Set; 8import java.util.Set;
10 9
11public interface QueryableModelStore extends ModelStore{ 10public interface QueryableModelStore extends ModelStore {
12 @SuppressWarnings("squid:S1452") 11 @SuppressWarnings("squid:S1452")
13 Set<DataRepresentation<?, ?>> getDataRepresentations(); 12 Set<DataRepresentation<?, ?>> getDataRepresentations();
13
14 @SuppressWarnings("squid:S1452") 14 @SuppressWarnings("squid:S1452")
15 Set<RelationView<?>> getViews(); 15 Set<RelationView<?>> getViews();
16
16 Set<DNFPredicate> getPredicates(); 17 Set<DNFPredicate> getPredicates();
17 18
18 QueryableModel createModel(); 19 QueryableModel createModel();
19 QueryableModel createModel(long state);
20 20
21 Set<Long> getStates(); 21 QueryableModel createModel(long state);
22 ModelDiffCursor getDiffCursor(long from, long to);
23} 22}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java
index a21a38ba..79de1c4d 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java
@@ -1,8 +1,8 @@
1package tools.refinery.store.query.view; 1package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.model.Model; 3import tools.refinery.store.model.Model;
4import tools.refinery.store.model.Tuple; 4import tools.refinery.store.tuple.Tuple;
5import tools.refinery.store.model.Tuple.Tuple1; 5import tools.refinery.store.tuple.Tuple1;
6import tools.refinery.store.model.representation.Relation; 6import tools.refinery.store.model.representation.Relation;
7 7
8public abstract class AbstractFilteredRelationView<D> extends RelationView<D> { 8public abstract class AbstractFilteredRelationView<D> extends RelationView<D> {
@@ -23,7 +23,7 @@ public abstract class AbstractFilteredRelationView<D> extends RelationView<D> {
23 public boolean get(Model model, Object[] tuple) { 23 public boolean get(Model model, Object[] tuple) {
24 int[] content = new int[tuple.length]; 24 int[] content = new int[tuple.length];
25 for (int i = 0; i < tuple.length; i++) { 25 for (int i = 0; i < tuple.length; i++) {
26 content[i] = ((Tuple1) tuple[i]).get(0); 26 content[i] = ((Tuple1) tuple[i]).value0();
27 } 27 }
28 Tuple key = Tuple.of(content); 28 Tuple key = Tuple.of(content);
29 D value = model.get(getRepresentation(), key); 29 D value = model.get(getRepresentation(), key);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
index bb5d0237..3b639979 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
@@ -1,6 +1,6 @@
1package tools.refinery.store.query.view; 1package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.model.Tuple; 3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5 5
6import java.util.function.BiPredicate; 6import java.util.function.BiPredicate;
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java
index 54baa050..ef3954a4 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java
@@ -1,8 +1,8 @@
1package tools.refinery.store.query.view; 1package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.model.Model; 3import tools.refinery.store.model.Model;
4import tools.refinery.store.model.Tuple; 4import tools.refinery.store.tuple.Tuple;
5import tools.refinery.store.model.Tuple.Tuple1; 5import tools.refinery.store.tuple.Tuple1;
6import tools.refinery.store.model.representation.Relation; 6import tools.refinery.store.model.representation.Relation;
7 7
8public class FunctionalRelationView<D> extends RelationView<D> { 8public class FunctionalRelationView<D> extends RelationView<D> {
@@ -28,7 +28,7 @@ public class FunctionalRelationView<D> extends RelationView<D> {
28 public boolean get(Model model, Object[] tuple) { 28 public boolean get(Model model, Object[] tuple) {
29 int[] content = new int[tuple.length - 1]; 29 int[] content = new int[tuple.length - 1];
30 for (int i = 0; i < tuple.length - 1; i++) { 30 for (int i = 0; i < tuple.length - 1; i++) {
31 content[i] = ((Tuple1) tuple[i]).get(0); 31 content[i] = ((Tuple1) tuple[i]).value0();
32 } 32 }
33 Tuple key = Tuple.of(content); 33 Tuple key = Tuple.of(content);
34 @SuppressWarnings("unchecked") 34 @SuppressWarnings("unchecked")
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
index b9a9ed9f..c88af5a4 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
@@ -1,6 +1,6 @@
1package tools.refinery.store.query.view; 1package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.model.Tuple; 3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5 5
6public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> { 6public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
index b8a54046..ceaf7d55 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
@@ -2,7 +2,7 @@ package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.map.CursorAsIterator; 3import tools.refinery.store.map.CursorAsIterator;
4import tools.refinery.store.model.Model; 4import tools.refinery.store.model.Model;
5import tools.refinery.store.model.Tuple; 5import tools.refinery.store.tuple.Tuple;
6import tools.refinery.store.model.representation.Relation; 6import tools.refinery.store.model.representation.Relation;
7 7
8import java.util.Objects; 8import java.util.Objects;
diff --git a/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple.java b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple.java
new file mode 100644
index 00000000..bf844c6d
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple.java
@@ -0,0 +1,29 @@
1package tools.refinery.store.tuple;
2
3public sealed interface Tuple extends TupleLike permits Tuple0, Tuple1, Tuple2, TupleN {
4 @Override
5 default Tuple toTuple() {
6 return this;
7 }
8
9 static Tuple of() {
10 return Tuple0.INSTANCE;
11 }
12
13 static Tuple of(int value) {
14 return Tuple1.Cache.INSTANCE.getOrCreate(value);
15 }
16
17 static Tuple of(int value1, int value2) {
18 return new Tuple2(value1, value2);
19 }
20
21 static Tuple of(int... values) {
22 return switch (values.length) {
23 case 0 -> of();
24 case 1 -> of(values[0]);
25 case 2 -> of(values[0], values[1]);
26 default -> new TupleN(values);
27 };
28 }
29}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple0.java b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple0.java
new file mode 100644
index 00000000..8eea5c3a
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple0.java
@@ -0,0 +1,25 @@
1package tools.refinery.store.tuple;
2
3public record Tuple0() implements Tuple {
4 public static Tuple0 INSTANCE = new Tuple0();
5
6 @Override
7 public int getSize() {
8 return 0;
9 }
10
11 @Override
12 public int get(int element) {
13 throw new IndexOutOfBoundsException(element);
14 }
15
16 @Override
17 public int[] toArray() {
18 return new int[]{};
19 }
20
21 @Override
22 public String toString() {
23 return "[]";
24 }
25}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple1.java b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple1.java
new file mode 100644
index 00000000..95907ee1
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple1.java
@@ -0,0 +1,54 @@
1package tools.refinery.store.tuple;
2
3import java.util.ArrayList;
4
5public record Tuple1(int value0) implements Tuple {
6 @Override
7 public int getSize() {
8 return 1;
9 }
10
11 @Override
12 public int get(int element) {
13 if (element == 0) {
14 return value0;
15 }
16 throw new IndexOutOfBoundsException(element);
17 }
18
19 @Override
20 public int[] toArray() {
21 return new int[]{value0};
22 }
23
24 @Override
25 public String toString() {
26 return "[" + value0 + "]";
27 }
28
29 public static class Cache {
30 public static final Cache INSTANCE = new Cache();
31
32 private final ArrayList<Tuple1> tuple1Cache = new ArrayList<>(1024);
33
34 private Cache() {
35 }
36
37 public Tuple1 getOrCreate(int value) {
38 if (value < 0) {
39 // Mask tuple for QueryableModelStore, doesn't refer to a model node.
40 return new Tuple1(value);
41 }
42 if (value < tuple1Cache.size()) {
43 return tuple1Cache.get(value);
44 }
45 Tuple1 newlyCreated = null;
46 tuple1Cache.ensureCapacity(value);
47 while (value >= tuple1Cache.size()) {
48 newlyCreated = new Tuple1(tuple1Cache.size());
49 tuple1Cache.add(newlyCreated);
50 }
51 return newlyCreated;
52 }
53 }
54}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple2.java b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple2.java
new file mode 100644
index 00000000..0836a32d
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/tuple/Tuple2.java
@@ -0,0 +1,27 @@
1package tools.refinery.store.tuple;
2
3public record Tuple2(int value0, int value1) implements Tuple {
4 @Override
5 public int getSize() {
6 return 2;
7 }
8
9 @Override
10 public int get(int element) {
11 return switch (element) {
12 case 0 -> value0;
13 case 1 -> value1;
14 default -> throw new ArrayIndexOutOfBoundsException(element);
15 };
16 }
17
18 @Override
19 public int[] toArray() {
20 return new int[]{value0, value1};
21 }
22
23 @Override
24 public String toString() {
25 return "[" + value0 + ", " + value1 + "]";
26 }
27}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/tuple/TupleLike.java b/subprojects/store/src/main/java/tools/refinery/store/tuple/TupleLike.java
new file mode 100644
index 00000000..470ca298
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/tuple/TupleLike.java
@@ -0,0 +1,25 @@
1package tools.refinery.store.tuple;
2
3public interface TupleLike {
4 int getSize();
5
6 int get(int element);
7
8 default int[] toArray() {
9 int size = getSize();
10 var array = new int[size];
11 for (int i = 0; i < size; i++) {
12 array[i] = get(i);
13 }
14 return array;
15 }
16
17 default Tuple toTuple() {
18 return switch (getSize()) {
19 case 0 -> Tuple.of();
20 case 1 -> Tuple.of(get(0));
21 case 2 -> Tuple.of(get(0), get(1));
22 default -> Tuple.of(toArray());
23 };
24 }
25}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/tuple/TupleN.java b/subprojects/store/src/main/java/tools/refinery/store/tuple/TupleN.java
new file mode 100644
index 00000000..15fd063b
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/tuple/TupleN.java
@@ -0,0 +1,52 @@
1package tools.refinery.store.tuple;
2
3import java.util.Arrays;
4import java.util.stream.Collectors;
5
6public record TupleN(int[] values) implements Tuple {
7 static final int CUSTOM_TUPLE_SIZE = 2;
8
9 public TupleN(int[] values) {
10 if (values.length < CUSTOM_TUPLE_SIZE)
11 throw new IllegalArgumentException();
12 this.values = Arrays.copyOf(values, values.length);
13 }
14
15 @Override
16 public int getSize() {
17 return values.length;
18 }
19
20 @Override
21 public int get(int element) {
22 return values[element];
23 }
24
25 @Override
26 public int[] toArray() {
27 return values;
28 }
29
30 @Override
31 public String toString() {
32 var valuesString = Arrays.stream(values).mapToObj(Integer::toString).collect(Collectors.joining(", "));
33 return "[" + valuesString + "]";
34 }
35
36 @Override
37 public int hashCode() {
38 return Arrays.hashCode(values);
39 }
40
41 @Override
42 public boolean equals(Object obj) {
43 if (this == obj)
44 return true;
45 if (obj == null)
46 return false;
47 if (getClass() != obj.getClass())
48 return false;
49 TupleN other = (TupleN) obj;
50 return Arrays.equals(values, other.values);
51 }
52}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java
index f0d5d927..081112cc 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java
@@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test;
6 6
7import tools.refinery.store.map.VersionedMapStore; 7import tools.refinery.store.map.VersionedMapStore;
8import tools.refinery.store.map.VersionedMapStoreImpl; 8import tools.refinery.store.map.VersionedMapStoreImpl;
9import tools.refinery.store.model.Tuple; 9import tools.refinery.store.tuple.Tuple;
10import tools.refinery.store.model.TupleHashProvider; 10import tools.refinery.store.model.TupleHashProvider;
11 11
12class MapUnitTests { 12class MapUnitTests {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/hashTests/HashEfficiencyTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/hashTests/HashEfficiencyTest.java
index 7d070380..ceec40f5 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/model/hashTests/HashEfficiencyTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/model/hashTests/HashEfficiencyTest.java
@@ -10,7 +10,7 @@ import java.util.Random;
10import org.junit.jupiter.api.Test; 10import org.junit.jupiter.api.Test;
11 11
12import tools.refinery.store.map.ContinousHashProvider; 12import tools.refinery.store.map.ContinousHashProvider;
13import tools.refinery.store.model.Tuple; 13import tools.refinery.store.tuple.Tuple;
14import tools.refinery.store.model.TupleHashProvider; 14import tools.refinery.store.model.TupleHashProvider;
15import tools.refinery.store.model.TupleHashProviderBitMagic; 15import tools.refinery.store.model.TupleHashProviderBitMagic;
16 16
@@ -39,7 +39,7 @@ class HashEfficiencyTest {
39 return result; 39 return result;
40 } else throw new IllegalArgumentException(); 40 } else throw new IllegalArgumentException();
41 } 41 }
42 42
43 private static int amountToRange(int arity, int n) { 43 private static int amountToRange(int arity, int n) {
44 int range = 1; 44 int range = 1;
45 while(Math.pow(range,arity)<n+0.1) { 45 while(Math.pow(range,arity)<n+0.1) {
@@ -47,7 +47,7 @@ class HashEfficiencyTest {
47 } 47 }
48 return 1024; 48 return 1024;
49 } 49 }
50 50
51 public static List<Tuple> nPermutations(int arity, int n) { 51 public static List<Tuple> nPermutations(int arity, int n) {
52 int range = amountToRange(arity, n); 52 int range = amountToRange(arity, n);
53 List<Tuple> permutations = permutations(range, arity); 53 List<Tuple> permutations = permutations(range, arity);
@@ -67,7 +67,7 @@ class HashEfficiencyTest {
67 } 67 }
68 return permutations; 68 return permutations;
69 } 69 }
70 70
71 @Test 71 @Test
72 void permutationTest() { 72 void permutationTest() {
73 List<Tuple> p = permutations(10, 2); 73 List<Tuple> p = permutations(10, 2);
@@ -92,7 +92,7 @@ class HashEfficiencyTest {
92 } 92 }
93 private static double calculateHashClashes(List<Tuple> tuples, ContinousHashProvider<Tuple> chp) { 93 private static double calculateHashClashes(List<Tuple> tuples, ContinousHashProvider<Tuple> chp) {
94 int sumClashes = 0; 94 int sumClashes = 0;
95 95
96 for(int i = 0; i<tuples.size(); i++) { 96 for(int i = 0; i<tuples.size(); i++) {
97 int height = 0; 97 int height = 0;
98 for(int j=0; j<tuples.size(); j++) { 98 for(int j=0; j<tuples.size(); j++) {
@@ -131,22 +131,22 @@ class HashEfficiencyTest {
131 hashes.add(new TupleHashProvider()); 131 hashes.add(new TupleHashProvider());
132 hashNames.add("BitMagic"); 132 hashNames.add("BitMagic");
133 hashes.add(new TupleHashProviderBitMagic()); 133 hashes.add(new TupleHashProviderBitMagic());
134 134
135 int[] arities = new int[] {2,3,4,5}; 135 int[] arities = new int[] {2,3,4,5};
136 int[] sizes = new int[] {32*32,32*32*8}; 136 int[] sizes = new int[] {32*32,32*32*8};
137 137
138 System.out.println("Size,Arity,DataSource,Hash,Chashes,Optimal,Badness"); 138 System.out.println("Size,Arity,DataSource,Hash,Chashes,Optimal,Badness");
139 for(int size : sizes) { 139 for(int size : sizes) {
140 double optimalClashes = caclulateOptimalHashClash(size); 140 double optimalClashes = caclulateOptimalHashClash(size);
141 for(int arity : arities) { 141 for(int arity : arities) {
142 List<String> dataSourceNames = new LinkedList<>(); 142 List<String> dataSourceNames = new LinkedList<>();
143 List<List<Tuple>> dataSources = new LinkedList<>(); 143 List<List<Tuple>> dataSources = new LinkedList<>();
144 144
145// dataSourceNames.add("Permutation"); 145// dataSourceNames.add("Permutation");
146// dataSources.add(nPermutations(arity, size)); 146// dataSources.add(nPermutations(arity, size));
147 dataSourceNames.add("Random"); 147 dataSourceNames.add("Random");
148 dataSources.add(nRandoms(arity, size, 0)); 148 dataSources.add(nRandoms(arity, size, 0));
149 149
150 for(int dataSourceIndex = 0; dataSourceIndex<dataSourceNames.size(); dataSourceIndex++) { 150 for(int dataSourceIndex = 0; dataSourceIndex<dataSourceNames.size(); dataSourceIndex++) {
151 for(int hashIndex = 0; hashIndex<hashNames.size(); hashIndex++) { 151 for(int hashIndex = 0; hashIndex<hashNames.size(); hashIndex++) {
152 double clashes = calculateHashClashes(dataSources.get(dataSourceIndex),hashes.get(hashIndex)); 152 double clashes = calculateHashClashes(dataSources.get(dataSourceIndex),hashes.get(hashIndex));
diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java
index 9d90b1e1..61dd7c74 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/model/tests/ModelTest.java
@@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test;
12import tools.refinery.store.model.Model; 12import tools.refinery.store.model.Model;
13import tools.refinery.store.model.ModelStore; 13import tools.refinery.store.model.ModelStore;
14import tools.refinery.store.model.ModelStoreImpl; 14import tools.refinery.store.model.ModelStoreImpl;
15import tools.refinery.store.model.Tuple; 15import tools.refinery.store.tuple.Tuple;
16import tools.refinery.store.model.representation.Relation; 16import tools.refinery.store.model.representation.Relation;
17 17
18class ModelTest { 18class ModelTest {