Aaron Kruglikov
Committed by Madan Jampani

Updating multimap API and commands and providing implementation.

Change-Id: Iff49b429cfc7c0142f3ab2e1dde1a32e85f20e87
(cherry picked from commit 44a1fef9)
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
16 16
17 package org.onosproject.store.service; 17 package org.onosproject.store.service;
18 18
19 -import com.google.common.collect.Multimap;
20 import com.google.common.collect.Multiset; 19 import com.google.common.collect.Multiset;
21 20
22 import java.util.Collection; 21 import java.util.Collection;
...@@ -92,7 +91,7 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive { ...@@ -92,7 +91,7 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive {
92 * and others ignoring put requests for existing entries. 91 * and others ignoring put requests for existing entries.
93 * @param key the key to add 92 * @param key the key to add
94 * @param value the value to add 93 * @param value the value to add
95 - * @return a future whose value will betrue if the map has changed because 94 + * @return a future whose value will be true if the map has changed because
96 * of this call, false otherwise 95 * of this call, false otherwise
97 */ 96 */
98 CompletableFuture<Boolean> put(K key, V value); 97 CompletableFuture<Boolean> put(K key, V value);
...@@ -119,16 +118,18 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive { ...@@ -119,16 +118,18 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive {
119 * @return a future whose value will be true if the map changes because of 118 * @return a future whose value will be true if the map changes because of
120 * this call, false otherwise. 119 * this call, false otherwise.
121 */ 120 */
122 - CompletableFuture<Boolean> removeAll(K key, Iterable<? extends V> values); 121 + CompletableFuture<Boolean> removeAll(K key,
122 + Collection<? extends V> values);
123 123
124 /** 124 /**
125 * Removes all values associated with the specified key as well as the key 125 * Removes all values associated with the specified key as well as the key
126 * itself. 126 * itself.
127 * @param key the key whose key-value pairs will be removed 127 * @param key the key whose key-value pairs will be removed
128 * @return a future whose value is the set of values that were removed, 128 * @return a future whose value is the set of values that were removed,
129 - * which may be empty 129 + * which may be empty, if the values did not exist the version will be
130 + * less than one.
130 */ 131 */
131 - CompletableFuture<Versioned<Collection<byte[]>>> removeAll(K key); 132 + CompletableFuture<Versioned<Collection<? extends V>>> removeAll(K key);
132 133
133 /** 134 /**
134 * Adds the set of key-value pairs of the specified key with each of the 135 * Adds the set of key-value pairs of the specified key with each of the
...@@ -140,17 +141,8 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive { ...@@ -140,17 +141,8 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive {
140 * @return a future whose value will be true if any change in the map 141 * @return a future whose value will be true if any change in the map
141 * results from this call, false otherwise 142 * results from this call, false otherwise
142 */ 143 */
143 - CompletableFuture<Boolean> putAll(K key, Iterable<? extends V> values); 144 + CompletableFuture<Boolean> putAll(K key,
144 - 145 + Collection<? extends V> values);
145 - /**
146 - * Adds all entries from this multimap that are not already present, and
147 - * may or may not add duplicate entries depending on the implementation.
148 - * @param multiMap the map whose entries should be added
149 - * @return a future whose value will be true if any change results from
150 - * this call, false otherwise
151 - */
152 - CompletableFuture<Boolean> putAll(
153 - Multimap<? extends K, ? extends V> multiMap);
154 146
155 /** 147 /**
156 * Stores all the values in values associated with the key specified, 148 * Stores all the values in values associated with the key specified,
...@@ -161,7 +153,8 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive { ...@@ -161,7 +153,8 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive {
161 * @return a future whose value will be the collection of removed values, 153 * @return a future whose value will be the collection of removed values,
162 * which may be empty 154 * which may be empty
163 */ 155 */
164 - CompletableFuture<Collection<V>> replaceValues(K key, Iterable<V> values); 156 + CompletableFuture<Versioned<Collection<? extends V>>> replaceValues(
157 + K key, Collection<V> values);
165 158
166 /** 159 /**
167 * Removes all key-value pairs, after which it will be empty. 160 * Removes all key-value pairs, after which it will be empty.
...@@ -177,7 +170,7 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive { ...@@ -177,7 +170,7 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive {
177 * @return a future whose value will be the collection of the values 170 * @return a future whose value will be the collection of the values
178 * associated with the specified key, the collection may be empty 171 * associated with the specified key, the collection may be empty
179 */ 172 */
180 - CompletableFuture<Collection<V>> get(K key); 173 + CompletableFuture<Versioned<Collection<? extends V>>> get(K key);
181 174
182 /** 175 /**
183 * Returns a set of the keys contained in this multimap with one or more 176 * Returns a set of the keys contained in this multimap with one or more
...@@ -203,7 +196,7 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive { ...@@ -203,7 +196,7 @@ public interface AsyncConsistentMultimap<K, V> extends DistributedPrimitive {
203 * @return a future whose value will be a collection of values, this may be 196 * @return a future whose value will be a collection of values, this may be
204 * empty 197 * empty
205 */ 198 */
206 - CompletableFuture<Collection<V>> values(); 199 + CompletableFuture<Multiset<V>> values();
207 200
208 /** 201 /**
209 * Returns a collection of each key-value pair in this map. 202 * Returns a collection of each key-value pair in this map.
......
...@@ -25,6 +25,7 @@ COMPILE_DEPS = [ ...@@ -25,6 +25,7 @@ COMPILE_DEPS = [
25 TEST_DEPS = [ 25 TEST_DEPS = [
26 '//lib:TEST', 26 '//lib:TEST',
27 '//core/api:onos-api-tests', 27 '//core/api:onos-api-tests',
28 + '//lib:onos-atomix',
28 ] 29 ]
29 30
30 osgi_jar_with_tests ( 31 osgi_jar_with_tests (
......
...@@ -17,11 +17,10 @@ ...@@ -17,11 +17,10 @@
17 package org.onosproject.store.primitives.resources.impl; 17 package org.onosproject.store.primitives.resources.impl;
18 18
19 import com.google.common.collect.Lists; 19 import com.google.common.collect.Lists;
20 -import com.google.common.collect.Multimap;
21 import com.google.common.collect.Multiset; 20 import com.google.common.collect.Multiset;
22 import io.atomix.copycat.client.CopycatClient; 21 import io.atomix.copycat.client.CopycatClient;
23 import io.atomix.resource.AbstractResource; 22 import io.atomix.resource.AbstractResource;
24 -import org.onlab.util.Match; 23 +import io.atomix.resource.ResourceTypeInfo;
25 import org.onosproject.store.service.AsyncConsistentMultimap; 24 import org.onosproject.store.service.AsyncConsistentMultimap;
26 import org.onosproject.store.service.Versioned; 25 import org.onosproject.store.service.Versioned;
27 26
...@@ -32,13 +31,28 @@ import java.util.Properties; ...@@ -32,13 +31,28 @@ import java.util.Properties;
32 import java.util.Set; 31 import java.util.Set;
33 import java.util.concurrent.CompletableFuture; 32 import java.util.concurrent.CompletableFuture;
34 33
35 -import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.*; 34 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Clear;
35 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.ContainsEntry;
36 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.ContainsKey;
37 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.ContainsValue;
38 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Entries;
39 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Get;
40 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.IsEmpty;
41 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.KeySet;
42 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Keys;
43 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.MultiRemove;
44 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Put;
45 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.RemoveAll;
46 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Replace;
47 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Size;
48 +import static org.onosproject.store.primitives.resources.impl.AsyncConsistentMultimapCommands.Values;
36 49
37 /** 50 /**
38 * Set based implementation of the {@link AsyncConsistentMultimap}. 51 * Set based implementation of the {@link AsyncConsistentMultimap}.
39 * <p> 52 * <p>
40 * Note: this implementation does not allow null entries or duplicate entries. 53 * Note: this implementation does not allow null entries or duplicate entries.
41 */ 54 */
55 +@ResourceTypeInfo(id = -153, factory = AsyncConsistentSetMultimapFactory.class)
42 public class AsyncConsistentSetMultimap 56 public class AsyncConsistentSetMultimap
43 extends AbstractResource<AsyncConsistentSetMultimap> 57 extends AbstractResource<AsyncConsistentSetMultimap>
44 implements AsyncConsistentMultimap<String, byte[]> { 58 implements AsyncConsistentMultimap<String, byte[]> {
...@@ -81,68 +95,50 @@ public class AsyncConsistentSetMultimap ...@@ -81,68 +95,50 @@ public class AsyncConsistentSetMultimap
81 95
82 @Override 96 @Override
83 public CompletableFuture<Boolean> put(String key, byte[] value) { 97 public CompletableFuture<Boolean> put(String key, byte[] value) {
84 - return submit(new UpdateAndGet(key, Lists.newArrayList(value), 98 + return submit(new Put(key, Lists.newArrayList(value), null));
85 - Lists.newArrayList(Match.NULL),
86 - Lists.newArrayList(Match.NULL)))
87 - .whenComplete((result, e) -> throwIfLocked(result.status()))
88 - .thenApply(result ->
89 - result.status() == MapEntryUpdateResult.Status.OK);
90 } 99 }
91 100
92 @Override 101 @Override
93 public CompletableFuture<Boolean> remove(String key, byte[] value) { 102 public CompletableFuture<Boolean> remove(String key, byte[] value) {
94 - return submit(new UpdateAndGet(key, Lists.newArrayList(value), 103 + return submit(new MultiRemove(key,
95 - Lists.newArrayList(Match.ifValue(value)), 104 + Lists.newArrayList(value),
96 - Lists.newArrayList(Match.NULL))) 105 + null));
97 - .whenComplete((result, e) -> throwIfLocked(result.status()))
98 - .thenApply(result ->
99 - result.status() == MapEntryUpdateResult.Status.OK);
100 } 106 }
101 107
102 @Override 108 @Override
103 - public CompletableFuture<Boolean> removeAll(String key, Iterable<? extends byte[]> values) { 109 + public CompletableFuture<Boolean> removeAll(
104 - 110 + String key, Collection<? extends byte[]> values) {
105 - throw new UnsupportedOperationException("This operation cannot be " + 111 + return submit(new MultiRemove(key, (Collection<byte[]>) values, null));
106 - "used without support for " +
107 - "transactions.");
108 - }
109 -
110 - @Override
111 - public CompletableFuture<Versioned<Collection<byte[]>>> removeAll(String key) {
112 - return submit(new UpdateAndGet(key, null, null, null))
113 - .whenComplete((result, e) -> throwIfLocked(result.status()))
114 - .thenApply(result -> result.oldValue());
115 } 112 }
116 113
117 @Override 114 @Override
118 - public CompletableFuture<Boolean> putAll(String key, Iterable<? extends byte[]> values) { 115 + public CompletableFuture<
119 - throw new UnsupportedOperationException("This operation cannot be " + 116 + Versioned<Collection<? extends byte[]>>> removeAll(String key) {
120 - "used without support for " + 117 + return submit(new RemoveAll(key, null));
121 - "transactions.");
122 } 118 }
123 119
124 @Override 120 @Override
125 - public CompletableFuture<Boolean> putAll(Multimap<? extends String, ? extends byte[]> multiMap) { 121 + public CompletableFuture<Boolean> putAll(
126 - throw new UnsupportedOperationException("This operation cannot be " + 122 + String key, Collection<? extends byte[]> values) {
127 - "used without support for " + 123 + return submit(new Put(key, values, null));
128 - "transactions.");
129 } 124 }
130 125
131 @Override 126 @Override
132 - public CompletableFuture<Collection<byte[]>> replaceValues(String key, Iterable<byte[]> values) { 127 + public CompletableFuture<
133 - throw new UnsupportedOperationException("This operation cannot be " + 128 + Versioned<Collection<? extends byte[]>>> replaceValues(
134 - "used without support for " + 129 + String key, Collection<byte[]> values) {
135 - "transactions."); 130 + return submit(new Replace(key, values, null));
136 } 131 }
137 132
138 @Override 133 @Override
139 public CompletableFuture<Void> clear() { 134 public CompletableFuture<Void> clear() {
140 - return submit(new AsyncConsistentMultimapCommands.Clear()); 135 + return submit(new Clear());
141 } 136 }
142 137
143 @Override 138 @Override
144 - public CompletableFuture<Collection<byte[]>> get(String key) { 139 + public CompletableFuture<
145 - return submit(new Get()); 140 + Versioned<Collection<? extends byte[]>>> get(String key) {
141 + return submit(new Get(key));
146 } 142 }
147 143
148 @Override 144 @Override
...@@ -156,7 +152,7 @@ public class AsyncConsistentSetMultimap ...@@ -156,7 +152,7 @@ public class AsyncConsistentSetMultimap
156 } 152 }
157 153
158 @Override 154 @Override
159 - public CompletableFuture<Collection<byte[]>> values() { 155 + public CompletableFuture<Multiset<byte[]>> values() {
160 return submit(new Values()); 156 return submit(new Values());
161 } 157 }
162 158
...@@ -182,7 +178,9 @@ public class AsyncConsistentSetMultimap ...@@ -182,7 +178,9 @@ public class AsyncConsistentSetMultimap
182 */ 178 */
183 private void throwIfLocked(MapEntryUpdateResult.Status status) { 179 private void throwIfLocked(MapEntryUpdateResult.Status status) {
184 if (status == MapEntryUpdateResult.Status.WRITE_LOCK) { 180 if (status == MapEntryUpdateResult.Status.WRITE_LOCK) {
185 - throw new ConcurrentModificationException("Cannot update map: Another transaction in progress"); 181 + throw new ConcurrentModificationException("Cannot update map: " +
182 + "Another transaction " +
183 + "in progress");
186 } 184 }
187 } 185 }
188 } 186 }
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.store.primitives.resources.impl;
18 +
19 +import io.atomix.catalyst.serializer.SerializableTypeResolver;
20 +import io.atomix.copycat.client.CopycatClient;
21 +import io.atomix.resource.ResourceFactory;
22 +import io.atomix.resource.ResourceStateMachine;
23 +
24 +import java.util.Properties;
25 +
26 +/**
27 + * {@link AsyncConsistentSetMultimap} resource factory.
28 + */
29 +public class AsyncConsistentSetMultimapFactory implements
30 + ResourceFactory<AsyncConsistentSetMultimap> {
31 + @Override
32 + public SerializableTypeResolver createSerializableTypeResolver() {
33 + return new AsyncConsistentMultimapCommands.TypeResolver();
34 + }
35 +
36 + @Override
37 + public ResourceStateMachine createStateMachine(Properties config) {
38 + return new AsyncConsistentSetMultimapState(config);
39 + }
40 +
41 + @Override
42 + public AsyncConsistentSetMultimap createInstance(CopycatClient client,
43 + Properties properties) {
44 + return new AsyncConsistentSetMultimap(client, properties);
45 + }
46 +}