Adding interfaces for synchronous consistent multimaps.
Change-Id: Ie0bfc0b8317d7b1c0e0f50738ab4b05aa242e488
Showing
2 changed files
with
349 additions
and
0 deletions
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; | ||
18 | + | ||
19 | +import com.google.common.base.Throwables; | ||
20 | +import com.google.common.collect.Multiset; | ||
21 | +import org.onosproject.store.service.AsyncConsistentMultimap; | ||
22 | +import org.onosproject.store.service.ConsistentMapException; | ||
23 | +import org.onosproject.store.service.ConsistentMultimap; | ||
24 | +import org.onosproject.store.service.Synchronous; | ||
25 | +import org.onosproject.store.service.Versioned; | ||
26 | + | ||
27 | +import java.util.Collection; | ||
28 | +import java.util.Map; | ||
29 | +import java.util.Set; | ||
30 | +import java.util.concurrent.CompletableFuture; | ||
31 | +import java.util.concurrent.ExecutionException; | ||
32 | +import java.util.concurrent.TimeUnit; | ||
33 | +import java.util.concurrent.TimeoutException; | ||
34 | + | ||
35 | +/** | ||
36 | + * Implementation of {@link ConsistentMultimap} providing synchronous access to | ||
37 | + * {@link AsyncConsistentMultimap}. | ||
38 | + */ | ||
39 | +public class DefaultConsistentMultimap<K, V> | ||
40 | + extends Synchronous<AsyncConsistentMultimap<K, V>> | ||
41 | + implements ConsistentMultimap<K, V> { | ||
42 | + | ||
43 | + private final AsyncConsistentMultimap<K, V> asyncMultimap; | ||
44 | + private final long operationTimeoutMillis; | ||
45 | + | ||
46 | + public DefaultConsistentMultimap( | ||
47 | + AsyncConsistentMultimap<K, V> asyncMultimap, | ||
48 | + long operationTimeoutMillis) { | ||
49 | + super(asyncMultimap); | ||
50 | + this.asyncMultimap = asyncMultimap; | ||
51 | + this.operationTimeoutMillis = operationTimeoutMillis; | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public int size() { | ||
56 | + return complete(asyncMultimap.size()); | ||
57 | + } | ||
58 | + | ||
59 | + @Override | ||
60 | + public boolean isEmpty() { | ||
61 | + return complete(asyncMultimap.isEmpty()); | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
65 | + public boolean containsKey(K key) { | ||
66 | + return complete(asyncMultimap.containsKey(key)); | ||
67 | + } | ||
68 | + | ||
69 | + @Override | ||
70 | + public boolean containsValue(V value) { | ||
71 | + return complete(asyncMultimap.containsValue(value)); | ||
72 | + } | ||
73 | + | ||
74 | + @Override | ||
75 | + public boolean containsEntry(K key, V value) { | ||
76 | + return complete(asyncMultimap.containsEntry(key, value)); | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public boolean put(K key, V value) { | ||
81 | + return complete(asyncMultimap.put(key, value)); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public boolean remove(K key, V value) { | ||
86 | + return complete(asyncMultimap.remove(key, value)); | ||
87 | + } | ||
88 | + | ||
89 | + @Override | ||
90 | + public boolean removeAll(K key, Collection<? extends V> values) { | ||
91 | + return complete(asyncMultimap.removeAll(key, values)); | ||
92 | + } | ||
93 | + | ||
94 | + @Override | ||
95 | + public Versioned<Collection<? extends V>> removeAll(K key) { | ||
96 | + return complete(asyncMultimap.removeAll(key)); | ||
97 | + } | ||
98 | + | ||
99 | + @Override | ||
100 | + public boolean putAll(K key, Collection<? extends V> values) { | ||
101 | + return complete(asyncMultimap.putAll(key, values)); | ||
102 | + } | ||
103 | + | ||
104 | + @Override | ||
105 | + public Versioned<Collection<? extends V>> replaceValues( | ||
106 | + K key, Collection<V> values) { | ||
107 | + return complete(asyncMultimap.replaceValues(key, values)); | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + public void clear() { | ||
112 | + complete(asyncMultimap.clear()); | ||
113 | + } | ||
114 | + | ||
115 | + @Override | ||
116 | + public Versioned<Collection<? extends V>> get(K key) { | ||
117 | + return complete(asyncMultimap.get(key)); | ||
118 | + } | ||
119 | + | ||
120 | + @Override | ||
121 | + public Set<K> keySet() { | ||
122 | + return complete(asyncMultimap.keySet()); | ||
123 | + } | ||
124 | + | ||
125 | + @Override | ||
126 | + public Multiset<K> keys() { | ||
127 | + return complete(asyncMultimap.keys()); | ||
128 | + } | ||
129 | + | ||
130 | + @Override | ||
131 | + public Multiset<V> values() { | ||
132 | + return complete(asyncMultimap.values()); | ||
133 | + } | ||
134 | + | ||
135 | + @Override | ||
136 | + public Collection<Map.Entry<K, V>> entries() { | ||
137 | + return complete(asyncMultimap.entries()); | ||
138 | + } | ||
139 | + | ||
140 | + @Override | ||
141 | + public Map<K, Collection<V>> asMap() { | ||
142 | + throw new UnsupportedOperationException("This operation is not yet " + | ||
143 | + "supported."); | ||
144 | + //FIXME implement this when a new version of ConsistentMapBackedJavaMap is made for multimaps | ||
145 | + } | ||
146 | + | ||
147 | + private <T> T complete(CompletableFuture<T> future) { | ||
148 | + try { | ||
149 | + return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS); | ||
150 | + } catch (InterruptedException e) { | ||
151 | + Thread.currentThread().interrupt(); | ||
152 | + throw new ConsistentMapException.Interrupted(); | ||
153 | + } catch (TimeoutException e) { | ||
154 | + throw new ConsistentMapException.Timeout(); | ||
155 | + } catch (ExecutionException e) { | ||
156 | + Throwables.propagateIfPossible(e.getCause()); | ||
157 | + throw new ConsistentMapException(e.getCause()); | ||
158 | + } | ||
159 | + } | ||
160 | +} |
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.service; | ||
18 | + | ||
19 | +import com.google.common.collect.Multiset; | ||
20 | + | ||
21 | +import java.util.Collection; | ||
22 | +import java.util.Map; | ||
23 | +import java.util.Set; | ||
24 | + | ||
25 | +/** | ||
26 | + * This provides a synchronous version of the functionality provided by | ||
27 | + * {@link AsyncConsistentMultimap}. Instead of returning futures this map | ||
28 | + * blocks until the future completes then returns the result. | ||
29 | + */ | ||
30 | +public interface ConsistentMultimap<K, V> extends DistributedPrimitive { | ||
31 | + /** | ||
32 | + * Returns the number of key-value pairs in this multimap. | ||
33 | + * @return the number of key-value pairs | ||
34 | + */ | ||
35 | + int size(); | ||
36 | + | ||
37 | + /** | ||
38 | + * Returns if this multimap contains no key-value pairs. | ||
39 | + * @return true if no key-value pairs exist, false otherwise | ||
40 | + */ | ||
41 | + boolean isEmpty(); | ||
42 | + | ||
43 | + /** | ||
44 | + * Returns true if there is at lease one key-value pair with a key equal to | ||
45 | + * key. | ||
46 | + * @param key the key to query | ||
47 | + * @return true if the map contains a | ||
48 | + * key-value pair with key false otherwise | ||
49 | + */ | ||
50 | + boolean containsKey(K key); | ||
51 | + | ||
52 | + /** | ||
53 | + * Returns true if this map contains at lease one key-value pair with a | ||
54 | + * value equal to value. | ||
55 | + * @param value the value to query | ||
56 | + * @return true if there is a key-value pair with the specified value, | ||
57 | + * false otherwise. | ||
58 | + */ | ||
59 | + boolean containsValue(V value); | ||
60 | + | ||
61 | + /** | ||
62 | + * Returns true if this map contains at least one key-value pair with key | ||
63 | + * and value specified. | ||
64 | + * @return true if there is a key-value pair with the specified key and | ||
65 | + * value, false otherwise. | ||
66 | + */ | ||
67 | + boolean containsEntry(K key, V value); | ||
68 | + | ||
69 | + /** | ||
70 | + * If the key-value pair does not already exist adds either the key value | ||
71 | + * pair or the value to the set of values associated with the key and | ||
72 | + * returns true, if the key-value pair already exists then behavior is | ||
73 | + * implementation specific with some implementations allowing duplicates | ||
74 | + * and others ignoring put requests for existing entries. | ||
75 | + * @param key the key to add | ||
76 | + * @param value the value to add | ||
77 | + * @return true if the map has changed because of this call, | ||
78 | + * false otherwise | ||
79 | + */ | ||
80 | + boolean put(K key, V value); | ||
81 | + | ||
82 | + /** | ||
83 | + * Removes the key-value pair with the specified values if it exists. In | ||
84 | + * implementations that allow duplicates which matching entry will be | ||
85 | + * removed is undefined. | ||
86 | + * @param key the key of the pair to be removed | ||
87 | + * @param value the value of the pair to be removed | ||
88 | + * @return true if the map changed because of this call, false otherwise. | ||
89 | + */ | ||
90 | + boolean remove(K key, V value); | ||
91 | + | ||
92 | + /** | ||
93 | + * Removes the key-value pairs with the specified key and values if they | ||
94 | + * exist. In implementations that allow duplicates each instance of a key | ||
95 | + * will remove one matching entry, which one is not defined. Equivalent to | ||
96 | + * repeated calls to {@code remove()} for each key value pair but more | ||
97 | + * efficient. | ||
98 | + * @param key the key of the pair to be removed | ||
99 | + * @param values the set of values to be removed | ||
100 | + * @return true if the map changes because of this call, false otherwise. | ||
101 | + */ | ||
102 | + boolean removeAll(K key, Collection<? extends V> values); | ||
103 | + | ||
104 | + /** | ||
105 | + * Removes all values associated with the specified key as well as the key | ||
106 | + * itself. | ||
107 | + * @param key the key whose key-value pairs will be removed | ||
108 | + * @return the set of values that were removed, which may be empty, if the | ||
109 | + * values did not exist the version will be less than one. | ||
110 | + */ | ||
111 | + Versioned<Collection<? extends V>> removeAll(K key); | ||
112 | + | ||
113 | + /** | ||
114 | + * Adds the set of key-value pairs of the specified key with each of the | ||
115 | + * values in the iterable if each key-value pair does not already exist, | ||
116 | + * if the pair does exist the behavior is implementation specific. | ||
117 | + * (Same as repeated puts but with efficiency gains.) | ||
118 | + * @param key the key to use for all pairs to be added | ||
119 | + * @param values the set of values to be added in pairs with the key | ||
120 | + * @return true if any change in the map results from this call, | ||
121 | + * false otherwise | ||
122 | + */ | ||
123 | + boolean putAll(K key, Collection<? extends V> values); | ||
124 | + | ||
125 | + /** | ||
126 | + * Stores all the values in values associated with the key specified, | ||
127 | + * removes all preexisting values and returns a collection of the removed | ||
128 | + * values which may be empty if the entry did not exist. | ||
129 | + * @param key the key for all entries to be added | ||
130 | + * @param values the values to be associated with the key | ||
131 | + * @return the collection of removed values, which may be empty | ||
132 | + */ | ||
133 | + Versioned<Collection<? extends V>> replaceValues(K key, | ||
134 | + Collection<V> values); | ||
135 | + | ||
136 | + /** | ||
137 | + * Removes all key-value pairs, after which it will be empty. | ||
138 | + * @return irrelevant, simply used to determine if the call has completed | ||
139 | + */ | ||
140 | + void clear(); | ||
141 | + | ||
142 | + /** | ||
143 | + * Returns a collection of values associated with the specified key, if the | ||
144 | + * key is not in the map it will return an empty collection. | ||
145 | + * @param key the key whose associated values will be returned | ||
146 | + * @return the collection of the values | ||
147 | + * associated with the specified key, the collection may be empty | ||
148 | + */ | ||
149 | + Versioned<Collection<? extends V>> get(K key); | ||
150 | + | ||
151 | + /** | ||
152 | + * Returns a set of the keys contained in this multimap with one or more | ||
153 | + * associated values. | ||
154 | + * @return the collection of all keys with one or more associated values, | ||
155 | + * this may be empty | ||
156 | + */ | ||
157 | + Set<K> keySet(); | ||
158 | + | ||
159 | + /** | ||
160 | + * Returns a multiset of the keys present in this multimap with one or more | ||
161 | + * associated values each. Keys will appear once for each key-value pair | ||
162 | + * in which they participate. | ||
163 | + * @return a multiset of the keys, this may be empty | ||
164 | + */ | ||
165 | + Multiset<K> keys(); | ||
166 | + | ||
167 | + /** | ||
168 | + * Returns a collection of values in the set with duplicates permitted, the | ||
169 | + * size of this collection will equal the size of the map at the time of | ||
170 | + * creation. | ||
171 | + * @return a collection of values, this may be empty | ||
172 | + */ | ||
173 | + Multiset<V> values(); | ||
174 | + | ||
175 | + /** | ||
176 | + * Returns a collection of each key-value pair in this map. | ||
177 | + * @return a collection of all entries in the map, this may be empty | ||
178 | + */ | ||
179 | + Collection<Map.Entry<K, V>> entries(); | ||
180 | + | ||
181 | + /** | ||
182 | + * Returns a map of keys to collections of values that reflect the set of | ||
183 | + * key-value pairs contained in the multimap, where the key value pairs | ||
184 | + * would be the key paired with each of the values in the collection. | ||
185 | + * @return a map of keys to collections of values, the returned map may be | ||
186 | + * empty. | ||
187 | + */ | ||
188 | + Map<K, Collection<V>> asMap(); | ||
189 | +} |
-
Please register or login to post a comment