1. Refactored ConsistentMap and StorageServive (renamed from DatabaseService) to api bundle.
2. Misc bug fixes uncovered during testing Change-Id: I1219c5264831bcfa93565f764511f89de35a949d
Showing
15 changed files
with
190 additions
and
37 deletions
1 | +package org.onosproject.store.service; | ||
2 | + | ||
3 | +/** | ||
4 | + * Interface for serialization for store artifacts. | ||
5 | + */ | ||
6 | +public interface Serializer { | ||
7 | + /** | ||
8 | + * Serialize the specified object. | ||
9 | + * @param object object to serialize. | ||
10 | + * @return serialized bytes. | ||
11 | + * @param <T> encoded type | ||
12 | + */ | ||
13 | + <T> byte[] encode(T object); | ||
14 | + | ||
15 | + /** | ||
16 | + * Deserialize the specified bytes. | ||
17 | + * @param bytes byte array to deserialize. | ||
18 | + * @return deserialized object. | ||
19 | + * @param <T> decoded type | ||
20 | + */ | ||
21 | + <T> T decode(byte[] bytes); | ||
22 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -package org.onosproject.store.consistent.impl; | 1 | +package org.onosproject.store.service; |
2 | - | ||
3 | -import org.onosproject.store.serializers.StoreSerializer; | ||
4 | 2 | ||
5 | /** | 3 | /** |
6 | - * Database service. | 4 | + * Storage service. |
5 | + * <p> | ||
6 | + * This service provides operations for creating key-value stores. | ||
7 | + * One can chose to create key-value stores with varying properties such | ||
8 | + * as strongly consistent vs eventually consistent, durable vs volatile. | ||
9 | + * <p> | ||
10 | + * Various store implementations should leverage the data structures provided | ||
11 | + * by this service | ||
7 | */ | 12 | */ |
8 | -public interface DatabaseService { | 13 | +public interface StorageService { |
9 | 14 | ||
10 | /** | 15 | /** |
11 | * Creates a ConsistentMap. | 16 | * Creates a ConsistentMap. |
12 | * | 17 | * |
13 | - * @param <K> Key type | ||
14 | - * @param <V> value type | ||
15 | * @param name map name | 18 | * @param name map name |
16 | * @param serializer serializer to use for serializing keys and values. | 19 | * @param serializer serializer to use for serializing keys and values. |
17 | * @return consistent map. | 20 | * @return consistent map. |
21 | + * @param <K> key type | ||
22 | + * @param <V> value type | ||
18 | */ | 23 | */ |
19 | - <K, V> ConsistentMap<K , V> createConsistentMap(String name, StoreSerializer serializer); | 24 | + <K, V> ConsistentMap<K , V> createConsistentMap(String name, Serializer serializer); |
20 | -} | 25 | + |
26 | + // TODO: add API for creating Eventually Consistent Map. | ||
27 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -2,7 +2,6 @@ package org.onosproject.store.consistent.impl; | ... | @@ -2,7 +2,6 @@ package org.onosproject.store.consistent.impl; |
2 | 2 | ||
3 | import static com.google.common.base.Preconditions.*; | 3 | import static com.google.common.base.Preconditions.*; |
4 | 4 | ||
5 | -import java.util.AbstractMap; | ||
6 | import java.util.Collection; | 5 | import java.util.Collection; |
7 | import java.util.Collections; | 6 | import java.util.Collections; |
8 | import java.util.List; | 7 | import java.util.List; |
... | @@ -15,8 +14,13 @@ import java.util.concurrent.TimeoutException; | ... | @@ -15,8 +14,13 @@ import java.util.concurrent.TimeoutException; |
15 | import java.util.stream.Collectors; | 14 | import java.util.stream.Collectors; |
16 | import java.util.Set; | 15 | import java.util.Set; |
17 | 16 | ||
17 | +import org.apache.commons.lang3.tuple.Pair; | ||
18 | import org.onlab.util.HexString; | 18 | import org.onlab.util.HexString; |
19 | -import org.onosproject.store.serializers.StoreSerializer; | 19 | +import org.onosproject.store.service.ConsistentMap; |
20 | +import org.onosproject.store.service.ConsistentMapException; | ||
21 | +import org.onosproject.store.service.Serializer; | ||
22 | +import org.onosproject.store.service.UpdateOperation; | ||
23 | +import org.onosproject.store.service.Versioned; | ||
20 | 24 | ||
21 | import com.google.common.cache.CacheBuilder; | 25 | import com.google.common.cache.CacheBuilder; |
22 | import com.google.common.cache.CacheLoader; | 26 | import com.google.common.cache.CacheLoader; |
... | @@ -33,7 +37,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { | ... | @@ -33,7 +37,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { |
33 | 37 | ||
34 | private final String name; | 38 | private final String name; |
35 | private final DatabaseProxy<String, byte[]> proxy; | 39 | private final DatabaseProxy<String, byte[]> proxy; |
36 | - private final StoreSerializer serializer; | 40 | + private final Serializer serializer; |
37 | 41 | ||
38 | private static final int OPERATION_TIMEOUT_MILLIS = 1000; | 42 | private static final int OPERATION_TIMEOUT_MILLIS = 1000; |
39 | private static final String ERROR_NULL_KEY = "Key cannot be null"; | 43 | private static final String ERROR_NULL_KEY = "Key cannot be null"; |
... | @@ -55,7 +59,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { | ... | @@ -55,7 +59,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { |
55 | 59 | ||
56 | ConsistentMapImpl(String name, | 60 | ConsistentMapImpl(String name, |
57 | DatabaseProxy<String, byte[]> proxy, | 61 | DatabaseProxy<String, byte[]> proxy, |
58 | - StoreSerializer serializer) { | 62 | + Serializer serializer) { |
59 | this.name = checkNotNull(name, "map name cannot be null"); | 63 | this.name = checkNotNull(name, "map name cannot be null"); |
60 | this.proxy = checkNotNull(proxy, "database proxy cannot be null"); | 64 | this.proxy = checkNotNull(proxy, "database proxy cannot be null"); |
61 | this.serializer = checkNotNull(serializer, "serializer cannot be null"); | 65 | this.serializer = checkNotNull(serializer, "serializer cannot be null"); |
... | @@ -87,14 +91,15 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { | ... | @@ -87,14 +91,15 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { |
87 | public Versioned<V> get(K key) { | 91 | public Versioned<V> get(K key) { |
88 | checkNotNull(key, ERROR_NULL_KEY); | 92 | checkNotNull(key, ERROR_NULL_KEY); |
89 | Versioned<byte[]> value = complete(proxy.get(name, keyCache.getUnchecked(key))); | 93 | Versioned<byte[]> value = complete(proxy.get(name, keyCache.getUnchecked(key))); |
90 | - return new Versioned<>(serializer.decode(value.value()), value.version()); | 94 | + return (value != null) ? new Versioned<>(serializer.decode(value.value()), value.version()) : null; |
91 | } | 95 | } |
92 | 96 | ||
93 | @Override | 97 | @Override |
94 | public Versioned<V> put(K key, V value) { | 98 | public Versioned<V> put(K key, V value) { |
95 | checkNotNull(key, ERROR_NULL_KEY); | 99 | checkNotNull(key, ERROR_NULL_KEY); |
96 | checkNotNull(value, ERROR_NULL_VALUE); | 100 | checkNotNull(value, ERROR_NULL_VALUE); |
97 | - Versioned<byte[]> previousValue = complete(proxy.get(name, keyCache.getUnchecked(key))); | 101 | + Versioned<byte[]> previousValue = |
102 | + complete(proxy.put(name, keyCache.getUnchecked(key), serializer.encode(value))); | ||
98 | return (previousValue != null) ? | 103 | return (previousValue != null) ? |
99 | new Versioned<>(serializer.decode(previousValue.value()), previousValue.version()) : null; | 104 | new Versioned<>(serializer.decode(previousValue.value()), previousValue.version()) : null; |
100 | 105 | ||
... | @@ -103,7 +108,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { | ... | @@ -103,7 +108,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { |
103 | @Override | 108 | @Override |
104 | public Versioned<V> remove(K key) { | 109 | public Versioned<V> remove(K key) { |
105 | checkNotNull(key, ERROR_NULL_KEY); | 110 | checkNotNull(key, ERROR_NULL_KEY); |
106 | - Versioned<byte[]> value = complete(proxy.get(name, keyCache.getUnchecked(key))); | 111 | + Versioned<byte[]> value = complete(proxy.remove(name, keyCache.getUnchecked(key))); |
107 | return (value != null) ? new Versioned<>(serializer.decode(value.value()), value.version()) : null; | 112 | return (value != null) ? new Versioned<>(serializer.decode(value.value()), value.version()) : null; |
108 | } | 113 | } |
109 | 114 | ||
... | @@ -198,7 +203,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { | ... | @@ -198,7 +203,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { |
198 | } | 203 | } |
199 | 204 | ||
200 | private Map.Entry<K, Versioned<V>> fromRawEntry(Map.Entry<String, Versioned<byte[]>> e) { | 205 | private Map.Entry<K, Versioned<V>> fromRawEntry(Map.Entry<String, Versioned<byte[]>> e) { |
201 | - return new AbstractMap.SimpleEntry<>( | 206 | + return Pair.of( |
202 | dK(e.getKey()), | 207 | dK(e.getKey()), |
203 | new Versioned<>( | 208 | new Versioned<>( |
204 | serializer.decode(e.getValue().value()), | 209 | serializer.decode(e.getValue().value()), | ... | ... |
... | @@ -22,7 +22,9 @@ import org.apache.felix.scr.annotations.Service; | ... | @@ -22,7 +22,9 @@ import org.apache.felix.scr.annotations.Service; |
22 | import org.onosproject.cluster.ClusterService; | 22 | import org.onosproject.cluster.ClusterService; |
23 | import org.onosproject.cluster.ControllerNode; | 23 | import org.onosproject.cluster.ControllerNode; |
24 | import org.onosproject.cluster.DefaultControllerNode; | 24 | import org.onosproject.cluster.DefaultControllerNode; |
25 | -import org.onosproject.store.serializers.StoreSerializer; | 25 | +import org.onosproject.store.service.ConsistentMap; |
26 | +import org.onosproject.store.service.Serializer; | ||
27 | +import org.onosproject.store.service.StorageService; | ||
26 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
27 | 29 | ||
28 | import com.google.common.collect.Sets; | 30 | import com.google.common.collect.Sets; |
... | @@ -32,7 +34,7 @@ import com.google.common.collect.Sets; | ... | @@ -32,7 +34,7 @@ import com.google.common.collect.Sets; |
32 | */ | 34 | */ |
33 | @Component(immediate = true, enabled = true) | 35 | @Component(immediate = true, enabled = true) |
34 | @Service | 36 | @Service |
35 | -public class DatabaseManager implements DatabaseService { | 37 | +public class DatabaseManager implements StorageService { |
36 | 38 | ||
37 | private final Logger log = getLogger(getClass()); | 39 | private final Logger log = getLogger(getClass()); |
38 | private PartitionedDatabase partitionedDatabase; | 40 | private PartitionedDatabase partitionedDatabase; |
... | @@ -44,7 +46,7 @@ public class DatabaseManager implements DatabaseService { | ... | @@ -44,7 +46,7 @@ public class DatabaseManager implements DatabaseService { |
44 | protected ClusterService clusterService; | 46 | protected ClusterService clusterService; |
45 | 47 | ||
46 | protected String nodeToUri(ControllerNode node) { | 48 | protected String nodeToUri(ControllerNode node) { |
47 | - return "tcp://" + node.ip() + ":" + COPYCAT_TCP_PORT; | 49 | + return String.format("tcp://%s:%d", node.ip(), COPYCAT_TCP_PORT); |
48 | } | 50 | } |
49 | 51 | ||
50 | @Activate | 52 | @Activate |
... | @@ -76,7 +78,17 @@ public class DatabaseManager implements DatabaseService { | ... | @@ -76,7 +78,17 @@ public class DatabaseManager implements DatabaseService { |
76 | String localNodeUri = nodeToUri(clusterService.getLocalNode()); | 78 | String localNodeUri = nodeToUri(clusterService.getLocalNode()); |
77 | 79 | ||
78 | ClusterConfig clusterConfig = new ClusterConfig() | 80 | ClusterConfig clusterConfig = new ClusterConfig() |
79 | - .withProtocol(new NettyTcpProtocol()) | 81 | + .withProtocol(new NettyTcpProtocol() |
82 | + .withSsl(false) | ||
83 | + .withConnectTimeout(60000) | ||
84 | + .withAcceptBacklog(1024) | ||
85 | + .withTrafficClass(-1) | ||
86 | + .withSoLinger(-1) | ||
87 | + .withReceiveBufferSize(32768) | ||
88 | + .withSendBufferSize(8192) | ||
89 | + .withThreads(1)) | ||
90 | + .withElectionTimeout(300) | ||
91 | + .withHeartbeatInterval(150) | ||
80 | .withMembers(activeNodeUris) | 92 | .withMembers(activeNodeUris) |
81 | .withLocalMember(localNodeUri); | 93 | .withLocalMember(localNodeUri); |
82 | 94 | ||
... | @@ -85,8 +97,15 @@ public class DatabaseManager implements DatabaseService { | ... | @@ -85,8 +97,15 @@ public class DatabaseManager implements DatabaseService { |
85 | partitionMap.forEach((name, nodes) -> { | 97 | partitionMap.forEach((name, nodes) -> { |
86 | Set<String> replicas = nodes.stream().map(this::nodeToUri).collect(Collectors.toSet()); | 98 | Set<String> replicas = nodes.stream().map(this::nodeToUri).collect(Collectors.toSet()); |
87 | DatabaseConfig partitionConfig = new DatabaseConfig() | 99 | DatabaseConfig partitionConfig = new DatabaseConfig() |
100 | + .withElectionTimeout(300) | ||
101 | + .withHeartbeatInterval(150) | ||
88 | .withConsistency(Consistency.STRONG) | 102 | .withConsistency(Consistency.STRONG) |
89 | - .withLog(new FileLog(logDir)) | 103 | + .withLog(new FileLog() |
104 | + .withDirectory(logDir) | ||
105 | + .withSegmentSize(1073741824) // 1GB | ||
106 | + .withFlushOnWrite(true) | ||
107 | + .withSegmentInterval(Long.MAX_VALUE)) | ||
108 | + .withDefaultSerializer(new DatabaseSerializer()) | ||
90 | .withReplicas(replicas); | 109 | .withReplicas(replicas); |
91 | databaseConfig.addPartition(name, partitionConfig); | 110 | databaseConfig.addPartition(name, partitionConfig); |
92 | }); | 111 | }); |
... | @@ -116,7 +135,7 @@ public class DatabaseManager implements DatabaseService { | ... | @@ -116,7 +135,7 @@ public class DatabaseManager implements DatabaseService { |
116 | } | 135 | } |
117 | 136 | ||
118 | @Override | 137 | @Override |
119 | - public <K, V> ConsistentMap<K , V> createConsistentMap(String name, StoreSerializer serializer) { | 138 | + public <K, V> ConsistentMap<K , V> createConsistentMap(String name, Serializer serializer) { |
120 | return new ConsistentMapImpl<K, V>(name, partitionedDatabase, serializer); | 139 | return new ConsistentMapImpl<K, V>(name, partitionedDatabase, serializer); |
121 | } | 140 | } |
122 | } | 141 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -6,6 +6,9 @@ import java.util.Map; | ... | @@ -6,6 +6,9 @@ import java.util.Map; |
6 | import java.util.Set; | 6 | import java.util.Set; |
7 | import java.util.concurrent.CompletableFuture; | 7 | import java.util.concurrent.CompletableFuture; |
8 | 8 | ||
9 | +import org.onosproject.store.service.UpdateOperation; | ||
10 | +import org.onosproject.store.service.Versioned; | ||
11 | + | ||
9 | /** | 12 | /** |
10 | * Database proxy. | 13 | * Database proxy. |
11 | */ | 14 | */ | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DatabaseSerializer.java
0 → 100644
1 | +package org.onosproject.store.consistent.impl; | ||
2 | + | ||
3 | +import java.nio.ByteBuffer; | ||
4 | + | ||
5 | +import org.apache.commons.lang3.tuple.ImmutablePair; | ||
6 | +import org.apache.commons.lang3.tuple.Pair; | ||
7 | +import org.onlab.util.KryoNamespace; | ||
8 | +import org.onosproject.store.serializers.KryoNamespaces; | ||
9 | +import org.onosproject.store.serializers.KryoSerializer; | ||
10 | +import org.onosproject.store.service.Versioned; | ||
11 | + | ||
12 | +import net.kuujo.copycat.cluster.internal.MemberInfo; | ||
13 | +import net.kuujo.copycat.protocol.rpc.AppendRequest; | ||
14 | +import net.kuujo.copycat.protocol.rpc.AppendResponse; | ||
15 | +import net.kuujo.copycat.protocol.rpc.CommitRequest; | ||
16 | +import net.kuujo.copycat.protocol.rpc.CommitResponse; | ||
17 | +import net.kuujo.copycat.protocol.rpc.PollRequest; | ||
18 | +import net.kuujo.copycat.protocol.rpc.PollResponse; | ||
19 | +import net.kuujo.copycat.protocol.rpc.QueryRequest; | ||
20 | +import net.kuujo.copycat.protocol.rpc.QueryResponse; | ||
21 | +import net.kuujo.copycat.protocol.rpc.ReplicaInfo; | ||
22 | +import net.kuujo.copycat.protocol.rpc.SyncRequest; | ||
23 | +import net.kuujo.copycat.protocol.rpc.SyncResponse; | ||
24 | +import net.kuujo.copycat.util.serializer.SerializerConfig; | ||
25 | + | ||
26 | +/** | ||
27 | + * Serializer for DatabaseManager's interaction with Copycat. | ||
28 | + */ | ||
29 | +public class DatabaseSerializer extends SerializerConfig { | ||
30 | + | ||
31 | + private static final KryoNamespace COPYCAT = KryoNamespace.newBuilder() | ||
32 | + .nextId(KryoNamespace.FLOATING_ID) | ||
33 | + .register(AppendRequest.class) | ||
34 | + .register(AppendResponse.class) | ||
35 | + .register(SyncRequest.class) | ||
36 | + .register(SyncResponse.class) | ||
37 | + .register(PollRequest.class) | ||
38 | + .register(PollResponse.class) | ||
39 | + .register(QueryRequest.class) | ||
40 | + .register(QueryResponse.class) | ||
41 | + .register(CommitRequest.class) | ||
42 | + .register(CommitResponse.class) | ||
43 | + .register(ReplicaInfo.class) | ||
44 | + .register(MemberInfo.class) | ||
45 | + .build(); | ||
46 | + | ||
47 | + private static final KryoNamespace ONOS_STORE = KryoNamespace.newBuilder() | ||
48 | + .nextId(KryoNamespace.FLOATING_ID) | ||
49 | + .register(Versioned.class) | ||
50 | + .register(Pair.class) | ||
51 | + .register(ImmutablePair.class) | ||
52 | + .build(); | ||
53 | + | ||
54 | + private static final KryoSerializer SERIALIZER = new KryoSerializer() { | ||
55 | + @Override | ||
56 | + protected void setupKryoPool() { | ||
57 | + serializerPool = KryoNamespace.newBuilder() | ||
58 | + .register(KryoNamespaces.BASIC) | ||
59 | + .register(COPYCAT) | ||
60 | + .register(ONOS_STORE) | ||
61 | + .build(); | ||
62 | + } | ||
63 | + }; | ||
64 | + | ||
65 | + @Override | ||
66 | + public ByteBuffer writeObject(Object object) { | ||
67 | + return ByteBuffer.wrap(SERIALIZER.encode(object)); | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public <T> T readObject(ByteBuffer buffer) { | ||
72 | + return SERIALIZER.decode(buffer); | ||
73 | + } | ||
74 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -5,6 +5,9 @@ import java.util.List; | ... | @@ -5,6 +5,9 @@ import java.util.List; |
5 | import java.util.Map.Entry; | 5 | import java.util.Map.Entry; |
6 | import java.util.Set; | 6 | import java.util.Set; |
7 | 7 | ||
8 | +import org.onosproject.store.service.UpdateOperation; | ||
9 | +import org.onosproject.store.service.Versioned; | ||
10 | + | ||
8 | import net.kuujo.copycat.state.Command; | 11 | import net.kuujo.copycat.state.Command; |
9 | import net.kuujo.copycat.state.Initializer; | 12 | import net.kuujo.copycat.state.Initializer; |
10 | import net.kuujo.copycat.state.Query; | 13 | import net.kuujo.copycat.state.Query; | ... | ... |
... | @@ -13,6 +13,9 @@ import java.util.Set; | ... | @@ -13,6 +13,9 @@ import java.util.Set; |
13 | import java.util.concurrent.CompletableFuture; | 13 | import java.util.concurrent.CompletableFuture; |
14 | import java.util.function.Supplier; | 14 | import java.util.function.Supplier; |
15 | 15 | ||
16 | +import org.onosproject.store.service.UpdateOperation; | ||
17 | +import org.onosproject.store.service.Versioned; | ||
18 | + | ||
16 | /** | 19 | /** |
17 | * Default database. | 20 | * Default database. |
18 | */ | 21 | */ |
... | @@ -132,7 +135,7 @@ public class DefaultDatabase extends AbstractResource<Database> implements Datab | ... | @@ -132,7 +135,7 @@ public class DefaultDatabase extends AbstractResource<Database> implements Datab |
132 | return runStartupTasks() | 135 | return runStartupTasks() |
133 | .thenCompose(v -> stateMachine.open()) | 136 | .thenCompose(v -> stateMachine.open()) |
134 | .thenRun(() -> { | 137 | .thenRun(() -> { |
135 | - this.proxy = stateMachine.createProxy(DatabaseProxy.class); | 138 | + this.proxy = stateMachine.createProxy(DatabaseProxy.class, this.getClass().getClassLoader()); |
136 | }) | 139 | }) |
137 | .thenApply(v -> null); | 140 | .thenApply(v -> null); |
138 | } | 141 | } | ... | ... |
... | @@ -6,8 +6,16 @@ import java.util.HashMap; | ... | @@ -6,8 +6,16 @@ import java.util.HashMap; |
6 | import java.util.List; | 6 | import java.util.List; |
7 | import java.util.Map; | 7 | import java.util.Map; |
8 | import java.util.Map.Entry; | 8 | import java.util.Map.Entry; |
9 | +import java.util.stream.Collectors; | ||
9 | import java.util.Set; | 10 | import java.util.Set; |
10 | 11 | ||
12 | +import org.apache.commons.lang3.tuple.Pair; | ||
13 | +import org.onosproject.store.service.UpdateOperation; | ||
14 | +import org.onosproject.store.service.Versioned; | ||
15 | + | ||
16 | +import com.google.common.collect.ImmutableList; | ||
17 | +import com.google.common.collect.ImmutableSet; | ||
18 | + | ||
11 | import net.kuujo.copycat.state.Initializer; | 19 | import net.kuujo.copycat.state.Initializer; |
12 | import net.kuujo.copycat.state.StateContext; | 20 | import net.kuujo.copycat.state.StateContext; |
13 | 21 | ||
... | @@ -88,17 +96,21 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { | ... | @@ -88,17 +96,21 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { |
88 | 96 | ||
89 | @Override | 97 | @Override |
90 | public Set<K> keySet(String tableName) { | 98 | public Set<K> keySet(String tableName) { |
91 | - return getTableMap(tableName).keySet(); | 99 | + return ImmutableSet.copyOf(getTableMap(tableName).keySet()); |
92 | } | 100 | } |
93 | 101 | ||
94 | @Override | 102 | @Override |
95 | public Collection<Versioned<V>> values(String tableName) { | 103 | public Collection<Versioned<V>> values(String tableName) { |
96 | - return getTableMap(tableName).values(); | 104 | + return ImmutableList.copyOf(getTableMap(tableName).values()); |
97 | } | 105 | } |
98 | 106 | ||
99 | @Override | 107 | @Override |
100 | public Set<Entry<K, Versioned<V>>> entrySet(String tableName) { | 108 | public Set<Entry<K, Versioned<V>>> entrySet(String tableName) { |
101 | - return getTableMap(tableName).entrySet(); | 109 | + return ImmutableSet.copyOf(getTableMap(tableName) |
110 | + .entrySet() | ||
111 | + .stream() | ||
112 | + .map(entry -> Pair.of(entry.getKey(), entry.getValue())) | ||
113 | + .collect(Collectors.toSet())); | ||
102 | } | 114 | } |
103 | 115 | ||
104 | @Override | 116 | @Override |
... | @@ -110,7 +122,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { | ... | @@ -110,7 +122,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { |
110 | @Override | 122 | @Override |
111 | public boolean remove(String tableName, K key, V value) { | 123 | public boolean remove(String tableName, K key, V value) { |
112 | Versioned<V> existing = getTableMap(tableName).get(key); | 124 | Versioned<V> existing = getTableMap(tableName).get(key); |
113 | - if (existing != null && existing.value().equals(value)) { | 125 | + if (existing != null && checkEquality(existing.value(), value)) { |
114 | getTableMap(tableName).remove(key); | 126 | getTableMap(tableName).remove(key); |
115 | return true; | 127 | return true; |
116 | } | 128 | } |
... | @@ -130,7 +142,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { | ... | @@ -130,7 +142,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { |
130 | @Override | 142 | @Override |
131 | public boolean replace(String tableName, K key, V oldValue, V newValue) { | 143 | public boolean replace(String tableName, K key, V oldValue, V newValue) { |
132 | Versioned<V> existing = getTableMap(tableName).get(key); | 144 | Versioned<V> existing = getTableMap(tableName).get(key); |
133 | - if (existing != null && existing.value().equals(oldValue)) { | 145 | + if (existing != null && checkEquality(existing.value(), oldValue)) { |
134 | put(tableName, key, newValue); | 146 | put(tableName, key, newValue); |
135 | return true; | 147 | return true; |
136 | } | 148 | } |
... | @@ -198,11 +210,11 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { | ... | @@ -198,11 +210,11 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { |
198 | case PUT_IF_VERSION_MATCH: | 210 | case PUT_IF_VERSION_MATCH: |
199 | return existingEntry != null && existingEntry.version() == update.currentVersion(); | 211 | return existingEntry != null && existingEntry.version() == update.currentVersion(); |
200 | case PUT_IF_VALUE_MATCH: | 212 | case PUT_IF_VALUE_MATCH: |
201 | - return existingEntry != null && existingEntry.value().equals(update.currentValue()); | 213 | + return existingEntry != null && checkEquality(existingEntry.value(), update.currentValue()); |
202 | case REMOVE_IF_VERSION_MATCH: | 214 | case REMOVE_IF_VERSION_MATCH: |
203 | return existingEntry == null || existingEntry.version() == update.currentVersion(); | 215 | return existingEntry == null || existingEntry.version() == update.currentVersion(); |
204 | case REMOVE_IF_VALUE_MATCH: | 216 | case REMOVE_IF_VALUE_MATCH: |
205 | - return existingEntry == null || existingEntry.value().equals(update.currentValue()); | 217 | + return existingEntry == null || checkEquality(existingEntry.value(), update.currentValue()); |
206 | default: | 218 | default: |
207 | throw new IllegalStateException("Unsupported type: " + update.type()); | 219 | throw new IllegalStateException("Unsupported type: " + update.type()); |
208 | } | 220 | } | ... | ... |
... | @@ -9,6 +9,10 @@ import java.util.concurrent.CompletableFuture; | ... | @@ -9,6 +9,10 @@ import java.util.concurrent.CompletableFuture; |
9 | import java.util.concurrent.CopyOnWriteArrayList; | 9 | import java.util.concurrent.CopyOnWriteArrayList; |
10 | import java.util.concurrent.atomic.AtomicBoolean; | 10 | import java.util.concurrent.atomic.AtomicBoolean; |
11 | import java.util.concurrent.atomic.AtomicInteger; | 11 | import java.util.concurrent.atomic.AtomicInteger; |
12 | + | ||
13 | +import org.onosproject.store.service.UpdateOperation; | ||
14 | +import org.onosproject.store.service.Versioned; | ||
15 | + | ||
12 | import com.google.common.collect.ImmutableMap; | 16 | import com.google.common.collect.ImmutableMap; |
13 | import com.google.common.collect.Lists; | 17 | import com.google.common.collect.Lists; |
14 | import com.google.common.collect.Maps; | 18 | import com.google.common.collect.Maps; |
... | @@ -112,7 +116,7 @@ public class PartitionedDatabase implements DatabaseProxy<String, byte[]>, Parti | ... | @@ -112,7 +116,7 @@ public class PartitionedDatabase implements DatabaseProxy<String, byte[]>, Parti |
112 | return CompletableFuture.allOf(partitions | 116 | return CompletableFuture.allOf(partitions |
113 | .values() | 117 | .values() |
114 | .stream() | 118 | .stream() |
115 | - .map(p -> p.values(tableName)) | 119 | + .map(p -> p.values(tableName).thenApply(values::addAll)) |
116 | .toArray(CompletableFuture[]::new)) | 120 | .toArray(CompletableFuture[]::new)) |
117 | .thenApply(v -> values); | 121 | .thenApply(v -> values); |
118 | } | 122 | } | ... | ... |
... | @@ -67,13 +67,14 @@ public interface PartitionedDatabaseManager { | ... | @@ -67,13 +67,14 @@ public interface PartitionedDatabaseManager { |
67 | CopycatConfig copycatConfig = new CopycatConfig() | 67 | CopycatConfig copycatConfig = new CopycatConfig() |
68 | .withName(name) | 68 | .withName(name) |
69 | .withClusterConfig(clusterConfig) | 69 | .withClusterConfig(clusterConfig) |
70 | + .withDefaultSerializer(new DatabaseSerializer()) | ||
70 | .withDefaultExecutor(Executors.newSingleThreadExecutor(new NamedThreadFactory("copycat-coordinator-%d"))); | 71 | .withDefaultExecutor(Executors.newSingleThreadExecutor(new NamedThreadFactory("copycat-coordinator-%d"))); |
71 | ClusterCoordinator coordinator = new DefaultClusterCoordinator(copycatConfig.resolve()); | 72 | ClusterCoordinator coordinator = new DefaultClusterCoordinator(copycatConfig.resolve()); |
72 | PartitionedDatabase partitionedDatabase = new PartitionedDatabase(coordinator); | 73 | PartitionedDatabase partitionedDatabase = new PartitionedDatabase(coordinator); |
73 | partitionedDatabaseConfig.partitions().forEach((partitionName, partitionConfig) -> | 74 | partitionedDatabaseConfig.partitions().forEach((partitionName, partitionConfig) -> |
74 | partitionedDatabase.registerPartition(partitionName , | 75 | partitionedDatabase.registerPartition(partitionName , |
75 | coordinator.getResource(partitionName, partitionConfig.resolve(clusterConfig) | 76 | coordinator.getResource(partitionName, partitionConfig.resolve(clusterConfig) |
76 | - .withDefaultSerializer(copycatConfig.getDefaultSerializer().copy()) | 77 | + .withSerializer(copycatConfig.getDefaultSerializer()) |
77 | .withDefaultExecutor(copycatConfig.getDefaultExecutor())))); | 78 | .withDefaultExecutor(copycatConfig.getDefaultExecutor())))); |
78 | partitionedDatabase.setPartitioner( | 79 | partitionedDatabase.setPartitioner( |
79 | new SimpleKeyHashPartitioner(partitionedDatabase.getRegisteredPartitions())); | 80 | new SimpleKeyHashPartitioner(partitionedDatabase.getRegisteredPartitions())); | ... | ... |
-
Please register or login to post a comment