diff options
author | 2023-07-21 20:27:30 +0200 | |
---|---|---|
committer | 2023-07-21 20:27:30 +0200 | |
commit | a6dcff6293e960b420e26c57374a281467821556 (patch) | |
tree | 76fe949d03cc2603febb3057261ef365d476e52c /subprojects/store/src/main/java/tools | |
parent | Fixing long-standing bug with state based diff cursor. (diff) | |
download | refinery-a6dcff6293e960b420e26c57374a281467821556.tar.gz refinery-a6dcff6293e960b420e26c57374a281467821556.tar.zst refinery-a6dcff6293e960b420e26c57374a281467821556.zip |
VersionedMapStoreFactoryBuilder.java is introduced, all tests are updated.
VersionedMapStoreBuilder.java is removed.
Diffstat (limited to 'subprojects/store/src/main/java/tools')
7 files changed, 255 insertions, 137 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStore.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStore.java index a8d7fb1a..7768287a 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStore.java +++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStore.java | |||
@@ -1,14 +1,20 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | import tools.refinery.store.map.internal.VersionedMapStoreFactoryBuilderImpl; | ||
4 | |||
3 | import java.util.Set; | 5 | import java.util.Set; |
4 | 6 | ||
5 | public interface VersionedMapStore<K, V> { | 7 | public interface VersionedMapStore<K, V> { |
6 | |||
7 | public VersionedMap<K, V> createMap(); | ||
8 | 8 | ||
9 | public VersionedMap<K, V> createMap(long state); | 9 | VersionedMap<K, V> createMap(); |
10 | 10 | ||
11 | public Set<Long> getStates(); | 11 | VersionedMap<K, V> createMap(long state); |
12 | |||
13 | Set<Long> getStates(); | ||
14 | |||
15 | DiffCursor<K,V> getDiffCursor(long fromState, long toState); | ||
12 | 16 | ||
13 | public DiffCursor<K,V> getDiffCursor(long fromState, long toState); | 17 | static <K,V> VersionedMapStoreFactoryBuilder<K,V> builder() { |
14 | } \ No newline at end of file | 18 | return new VersionedMapStoreFactoryBuilderImpl<>(); |
19 | } | ||
20 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreBuilder.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreBuilder.java deleted file mode 100644 index 1a9aa0b3..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreBuilder.java +++ /dev/null | |||
@@ -1,130 +0,0 @@ | |||
1 | package tools.refinery.store.map; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.List; | ||
5 | |||
6 | public class VersionedMapStoreBuilder<K, V> { | ||
7 | public enum StoreStrategy { | ||
8 | STATE, DELTA | ||
9 | } | ||
10 | |||
11 | public enum DeltaStorageStrategy { | ||
12 | LIST, SET | ||
13 | } | ||
14 | |||
15 | public enum StateStorageStrategy { | ||
16 | NO_NODE_CACHE, SHARED_NODE_CACHE, SHARED_NODE_CACHE_IN_GROUP | ||
17 | } | ||
18 | |||
19 | public static <K, V> VersionedMapStoreBuilder<K, V> builder() { | ||
20 | return new VersionedMapStoreBuilder<>(); | ||
21 | } | ||
22 | protected VersionedMapStoreBuilder() { | ||
23 | } | ||
24 | protected VersionedMapStoreBuilder(VersionedMapStoreBuilder<K, V> other) { | ||
25 | this.defaultValue = other.defaultValue; | ||
26 | this.defaultSet = other.defaultSet; | ||
27 | this.strategy = other.strategy; | ||
28 | this.stateBasedImmutableWhenCommitting = other.stateBasedImmutableWhenCommitting; | ||
29 | this.stateBasedNodeSharingStrategy = other.stateBasedNodeSharingStrategy; | ||
30 | this.hashProvider = other.hashProvider; | ||
31 | this.deltaStorageStrategy = other.deltaStorageStrategy; | ||
32 | } | ||
33 | protected boolean defaultSet = false; | ||
34 | protected V defaultValue = null; | ||
35 | protected StoreStrategy strategy = StoreStrategy.DELTA; | ||
36 | protected Boolean stateBasedImmutableWhenCommitting = false; | ||
37 | protected StateStorageStrategy stateBasedNodeSharingStrategy = StateStorageStrategy.SHARED_NODE_CACHE_IN_GROUP; | ||
38 | protected ContinousHashProvider<K> hashProvider = null; | ||
39 | protected DeltaStorageStrategy deltaStorageStrategy = DeltaStorageStrategy.LIST; | ||
40 | |||
41 | public VersionedMapStoreBuilder<K, V> setDefaultValue(V defaultValue) { | ||
42 | var result = new VersionedMapStoreBuilder<>(this); | ||
43 | result.defaultValue = defaultValue; | ||
44 | result.defaultSet = true; | ||
45 | return result; | ||
46 | } | ||
47 | |||
48 | public VersionedMapStoreBuilder<K, V> setStrategy(StoreStrategy strategy) { | ||
49 | var result = new VersionedMapStoreBuilder<>(this); | ||
50 | result.strategy = strategy; | ||
51 | return result; | ||
52 | } | ||
53 | |||
54 | public VersionedMapStoreBuilder<K, V> setHashProvider(ContinousHashProvider<K> hashProvider) { | ||
55 | var result = new VersionedMapStoreBuilder<>(this); | ||
56 | result.hashProvider = hashProvider; | ||
57 | return result; | ||
58 | } | ||
59 | |||
60 | public VersionedMapStoreBuilder<K, V> setStateBasedImmutableWhenCommitting(boolean toImmutableWhenCommitting) { | ||
61 | var result = new VersionedMapStoreBuilder<>(this); | ||
62 | result.stateBasedImmutableWhenCommitting = toImmutableWhenCommitting; | ||
63 | return result; | ||
64 | } | ||
65 | |||
66 | public VersionedMapStoreBuilder<K, V> setStateBasedNodeSharingStrategy(StateStorageStrategy strategy) { | ||
67 | var result = new VersionedMapStoreBuilder<>(this); | ||
68 | result.stateBasedNodeSharingStrategy = strategy; | ||
69 | return result; | ||
70 | } | ||
71 | |||
72 | public VersionedMapStoreBuilder<K, V> setDeltaStorageStrategy(DeltaStorageStrategy deltaStorageStrategy) { | ||
73 | var result = new VersionedMapStoreBuilder<>(this); | ||
74 | result.deltaStorageStrategy = deltaStorageStrategy; | ||
75 | return result; | ||
76 | } | ||
77 | |||
78 | public VersionedMapStore<K, V> buildOne() { | ||
79 | if(!defaultSet) { | ||
80 | throw new IllegalStateException("Default value is missing!"); | ||
81 | } | ||
82 | return switch (strategy) { | ||
83 | case DELTA -> new VersionedMapStoreDeltaImpl<>( | ||
84 | this.deltaStorageStrategy == DeltaStorageStrategy.SET, | ||
85 | this.defaultValue); | ||
86 | case STATE -> new VersionedMapStoreImpl<>( | ||
87 | this.hashProvider, | ||
88 | this.defaultValue, | ||
89 | new VersionedMapStoreConfiguration( | ||
90 | this.stateBasedImmutableWhenCommitting, | ||
91 | this.stateBasedNodeSharingStrategy != StateStorageStrategy.NO_NODE_CACHE, | ||
92 | this.stateBasedNodeSharingStrategy == StateStorageStrategy.SHARED_NODE_CACHE_IN_GROUP)); | ||
93 | }; | ||
94 | } | ||
95 | |||
96 | public List<VersionedMapStore<K, V>> buildGroup(int amount) { | ||
97 | if(!defaultSet) { | ||
98 | throw new IllegalStateException("Default value is missing!"); | ||
99 | } | ||
100 | if (this.strategy == StoreStrategy.STATE && | ||
101 | this.stateBasedNodeSharingStrategy == StateStorageStrategy.SHARED_NODE_CACHE_IN_GROUP) { | ||
102 | return VersionedMapStoreImpl.createSharedVersionedMapStores( | ||
103 | amount, | ||
104 | this.hashProvider, | ||
105 | this.defaultValue, | ||
106 | new VersionedMapStoreConfiguration( | ||
107 | this.stateBasedImmutableWhenCommitting, | ||
108 | true, | ||
109 | true)); | ||
110 | } else { | ||
111 | List<VersionedMapStore<K, V>> result = new ArrayList<>(amount); | ||
112 | for (int i = 0; i < amount; i++) { | ||
113 | result.add(buildOne()); | ||
114 | } | ||
115 | return result; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | @Override | ||
120 | public String toString() { | ||
121 | return "VersionedMapStoreBuilder{" + | ||
122 | "defaultValue=" + defaultValue + | ||
123 | ", strategy=" + strategy + | ||
124 | ", stateBasedImmutableWhenCommitting=" + stateBasedImmutableWhenCommitting + | ||
125 | ", stateBasedNodeSharingStrategy=" + stateBasedNodeSharingStrategy + | ||
126 | ", hashProvider=" + hashProvider + | ||
127 | ", deltaStorageStrategy=" + deltaStorageStrategy + | ||
128 | '}'; | ||
129 | } | ||
130 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreFactory.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreFactory.java new file mode 100644 index 00000000..5f882a3a --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreFactory.java | |||
@@ -0,0 +1,19 @@ | |||
1 | package tools.refinery.store.map; | ||
2 | |||
3 | import java.util.List; | ||
4 | |||
5 | public interface VersionedMapStoreFactory<K,V> { | ||
6 | /** | ||
7 | * Constructs a new instance of {@link VersionedMap}. | ||
8 | * @return The new instance. | ||
9 | */ | ||
10 | VersionedMapStore<K,V> createOne(); | ||
11 | |||
12 | /** | ||
13 | * Constructs a group of {@link VersionedMap}s with the same configuration. If possible, the stores share | ||
14 | * resources with each other. | ||
15 | * @param amount The amount of new instances to be created. | ||
16 | * @return A list of new stores with the given number of elements. | ||
17 | */ | ||
18 | List<VersionedMapStore<K, V>> createGroup(int amount); | ||
19 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreFactoryBuilder.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreFactoryBuilder.java new file mode 100644 index 00000000..9cf17b49 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreFactoryBuilder.java | |||
@@ -0,0 +1,24 @@ | |||
1 | package tools.refinery.store.map; | ||
2 | |||
3 | public interface VersionedMapStoreFactoryBuilder<K,V> { | ||
4 | enum StoreStrategy { | ||
5 | STATE, DELTA | ||
6 | } | ||
7 | |||
8 | enum DeltaTransactionStrategy { | ||
9 | LIST, SET | ||
10 | } | ||
11 | |||
12 | enum SharingStrategy { | ||
13 | NO_NODE_CACHE, SHARED_NODE_CACHE, SHARED_NODE_CACHE_IN_GROUP | ||
14 | } | ||
15 | |||
16 | VersionedMapStoreFactoryBuilder<K,V> defaultValue(V defaultValue); | ||
17 | VersionedMapStoreFactoryBuilder<K,V> strategy(StoreStrategy strategy); | ||
18 | VersionedMapStoreFactoryBuilder<K,V> stateBasedImmutableWhenCommitting(boolean transformToImmutable); | ||
19 | VersionedMapStoreFactoryBuilder<K,V> stateBasedSharingStrategy(SharingStrategy sharingStrategy); | ||
20 | VersionedMapStoreFactoryBuilder<K,V> stateBasedHashProvider(ContinousHashProvider<K> hashProvider); | ||
21 | VersionedMapStoreFactoryBuilder<K,V> deltaTransactionStrategy(DeltaTransactionStrategy deltaStrategy); | ||
22 | |||
23 | VersionedMapStoreFactory<K,V> build(); | ||
24 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/DeltaBasedVersionedMapStoreFactory.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/DeltaBasedVersionedMapStoreFactory.java new file mode 100644 index 00000000..29ec0da1 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/DeltaBasedVersionedMapStoreFactory.java | |||
@@ -0,0 +1,34 @@ | |||
1 | package tools.refinery.store.map.internal; | ||
2 | |||
3 | import tools.refinery.store.map.VersionedMapStore; | ||
4 | import tools.refinery.store.map.VersionedMapStoreDeltaImpl; | ||
5 | import tools.refinery.store.map.VersionedMapStoreFactory; | ||
6 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; | ||
7 | |||
8 | import java.util.ArrayList; | ||
9 | import java.util.List; | ||
10 | |||
11 | public class DeltaBasedVersionedMapStoreFactory<K, V> implements VersionedMapStoreFactory<K, V> { | ||
12 | private final V defaultValue; | ||
13 | private final boolean summarizeChanges; | ||
14 | |||
15 | public DeltaBasedVersionedMapStoreFactory(V defaultValue, | ||
16 | VersionedMapStoreFactoryBuilder.DeltaTransactionStrategy deltaTransactionStrategy) { | ||
17 | this.defaultValue = defaultValue; | ||
18 | this.summarizeChanges = deltaTransactionStrategy == VersionedMapStoreFactoryBuilder.DeltaTransactionStrategy.SET; | ||
19 | } | ||
20 | |||
21 | @Override | ||
22 | public VersionedMapStore<K, V> createOne() { | ||
23 | return new VersionedMapStoreDeltaImpl<>(summarizeChanges, defaultValue); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public List<VersionedMapStore<K, V>> createGroup(int amount) { | ||
28 | List<VersionedMapStore<K, V>> result = new ArrayList<>(amount); | ||
29 | for(int i=0; i<amount; i++) { | ||
30 | result.add(new VersionedMapStoreDeltaImpl<>(summarizeChanges,defaultValue)); | ||
31 | } | ||
32 | return result; | ||
33 | } | ||
34 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/StateBasedVersionedMapStoreFactory.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/StateBasedVersionedMapStoreFactory.java new file mode 100644 index 00000000..80dc347f --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/StateBasedVersionedMapStoreFactory.java | |||
@@ -0,0 +1,33 @@ | |||
1 | package tools.refinery.store.map.internal; | ||
2 | |||
3 | import tools.refinery.store.map.*; | ||
4 | |||
5 | import java.util.List; | ||
6 | |||
7 | public class StateBasedVersionedMapStoreFactory<K, V> implements VersionedMapStoreFactory<K, V> { | ||
8 | private final V defaultValue; | ||
9 | private final ContinousHashProvider<K> continousHashProvider; | ||
10 | private final VersionedMapStoreConfiguration config; | ||
11 | |||
12 | public StateBasedVersionedMapStoreFactory(V defaultValue, Boolean transformToImmutable, VersionedMapStoreFactoryBuilder.SharingStrategy sharingStrategy, ContinousHashProvider<K> continousHashProvider) { | ||
13 | this.defaultValue = defaultValue; | ||
14 | this.continousHashProvider = continousHashProvider; | ||
15 | |||
16 | this.config = new VersionedMapStoreConfiguration( | ||
17 | transformToImmutable, | ||
18 | sharingStrategy == VersionedMapStoreFactoryBuilder.SharingStrategy.SHARED_NODE_CACHE || sharingStrategy == VersionedMapStoreFactoryBuilder.SharingStrategy.SHARED_NODE_CACHE_IN_GROUP, | ||
19 | sharingStrategy == VersionedMapStoreFactoryBuilder.SharingStrategy.SHARED_NODE_CACHE_IN_GROUP); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public VersionedMapStore<K, V> createOne() { | ||
24 | return new VersionedMapStoreImpl<>(continousHashProvider, defaultValue, config); | ||
25 | |||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public List<VersionedMapStore<K, V>> createGroup(int amount) { | ||
30 | return VersionedMapStoreImpl.createSharedVersionedMapStores(amount, continousHashProvider, defaultValue, | ||
31 | config); | ||
32 | } | ||
33 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapStoreFactoryBuilderImpl.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapStoreFactoryBuilderImpl.java new file mode 100644 index 00000000..3719eef5 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapStoreFactoryBuilderImpl.java | |||
@@ -0,0 +1,132 @@ | |||
1 | package tools.refinery.store.map.internal; | ||
2 | |||
3 | import tools.refinery.store.map.ContinousHashProvider; | ||
4 | import tools.refinery.store.map.VersionedMapStoreFactory; | ||
5 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; | ||
6 | |||
7 | public class VersionedMapStoreFactoryBuilderImpl<K, V> implements VersionedMapStoreFactoryBuilder<K, V> { | ||
8 | |||
9 | private boolean defaultSet = false; | ||
10 | private V defaultValue; | ||
11 | private StoreStrategy strategy = null; | ||
12 | private Boolean transformToImmutable = null; | ||
13 | private SharingStrategy sharingStrategy = null; | ||
14 | private ContinousHashProvider<K> continousHashProvider = null; | ||
15 | private DeltaTransactionStrategy deltaTransactionStrategy = null; | ||
16 | |||
17 | private StoreStrategy checkStrategy() { | ||
18 | StoreStrategy currentStrategy = strategy; | ||
19 | currentStrategy = mergeStrategies(currentStrategy, transformToImmutable, StoreStrategy.STATE); | ||
20 | currentStrategy = mergeStrategies(currentStrategy, sharingStrategy, StoreStrategy.STATE); | ||
21 | currentStrategy = mergeStrategies(currentStrategy, continousHashProvider, StoreStrategy.STATE); | ||
22 | currentStrategy = mergeStrategies(currentStrategy, deltaTransactionStrategy, StoreStrategy.DELTA); | ||
23 | return currentStrategy; | ||
24 | } | ||
25 | |||
26 | private StoreStrategy mergeStrategies(StoreStrategy old, StoreStrategy newStrategy) { | ||
27 | if (old != null && newStrategy != null && old != newStrategy) { | ||
28 | throw new IllegalArgumentException("Mixed strategy parametrization in VersionedMap builder!"); | ||
29 | } | ||
30 | |||
31 | if (old != null) { | ||
32 | return old; | ||
33 | } else { | ||
34 | return newStrategy; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | private StoreStrategy mergeStrategies(StoreStrategy old, Object parameter, StoreStrategy newStrategy) { | ||
39 | if (parameter != null) { | ||
40 | return mergeStrategies(old, newStrategy); | ||
41 | } else { | ||
42 | return old; | ||
43 | } | ||
44 | } | ||
45 | |||
46 | @Override | ||
47 | public VersionedMapStoreFactoryBuilder<K, V> defaultValue(V defaultValue) { | ||
48 | this.defaultSet = true; | ||
49 | this.defaultValue = defaultValue; | ||
50 | return this; | ||
51 | } | ||
52 | |||
53 | @Override | ||
54 | public VersionedMapStoreFactoryBuilder<K, V> strategy(StoreStrategy strategy) { | ||
55 | this.strategy = strategy; | ||
56 | checkStrategy(); | ||
57 | return this; | ||
58 | } | ||
59 | |||
60 | @Override | ||
61 | public VersionedMapStoreFactoryBuilder<K, V> stateBasedImmutableWhenCommitting(boolean transformToImmutable) { | ||
62 | this.transformToImmutable = transformToImmutable; | ||
63 | checkStrategy(); | ||
64 | return this; | ||
65 | } | ||
66 | |||
67 | @Override | ||
68 | public VersionedMapStoreFactoryBuilder<K, V> stateBasedSharingStrategy(SharingStrategy sharingStrategy) { | ||
69 | this.sharingStrategy = sharingStrategy; | ||
70 | checkStrategy(); | ||
71 | return this; | ||
72 | } | ||
73 | |||
74 | @Override | ||
75 | public VersionedMapStoreFactoryBuilder<K, V> stateBasedHashProvider(ContinousHashProvider<K> hashProvider) { | ||
76 | this.continousHashProvider = hashProvider; | ||
77 | checkStrategy(); | ||
78 | return this; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public VersionedMapStoreFactoryBuilder<K, V> deltaTransactionStrategy(DeltaTransactionStrategy deltaTransactionStrategy) { | ||
83 | this.deltaTransactionStrategy = deltaTransactionStrategy; | ||
84 | checkStrategy(); | ||
85 | return this; | ||
86 | } | ||
87 | |||
88 | private <T> T getOrDefault(T value, T defaultValue) { | ||
89 | if(value != null) { | ||
90 | return value; | ||
91 | } else { | ||
92 | return defaultValue; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | @Override | ||
97 | public VersionedMapStoreFactory<K, V> build() { | ||
98 | if (!defaultSet) { | ||
99 | throw new IllegalArgumentException("Default value is missing!"); | ||
100 | } | ||
101 | var strategyToUse = checkStrategy(); | ||
102 | if (strategyToUse == null) { | ||
103 | return new DeltaBasedVersionedMapStoreFactory<>(defaultValue, | ||
104 | getOrDefault(deltaTransactionStrategy, DeltaTransactionStrategy.LIST)); | ||
105 | } | ||
106 | return switch (strategyToUse) { | ||
107 | case STATE -> { | ||
108 | if(continousHashProvider == null) { | ||
109 | throw new IllegalArgumentException("Continuous hash provider is missing!"); | ||
110 | } | ||
111 | yield new StateBasedVersionedMapStoreFactory<>(defaultValue, | ||
112 | getOrDefault(transformToImmutable,true), | ||
113 | getOrDefault(sharingStrategy, SharingStrategy.SHARED_NODE_CACHE_IN_GROUP), | ||
114 | continousHashProvider); | ||
115 | } | ||
116 | case DELTA -> new DeltaBasedVersionedMapStoreFactory<>(defaultValue, | ||
117 | getOrDefault(deltaTransactionStrategy, DeltaTransactionStrategy.LIST)); | ||
118 | }; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public String toString() { | ||
123 | return "VersionedMapStoreBuilder{" + | ||
124 | "defaultValue=" + defaultValue + | ||
125 | ", strategy=" + strategy + | ||
126 | ", stateBasedImmutableWhenCommitting=" + transformToImmutable + | ||
127 | ", stateBasedNodeSharingStrategy=" + sharingStrategy + | ||
128 | ", hashProvider=" + continousHashProvider + | ||
129 | ", deltaStorageStrategy=" + deltaTransactionStrategy + | ||
130 | '}'; | ||
131 | } | ||
132 | } | ||