blob: 51f09346a85bd02d83e93ce9bdfd2962fbd8887f [file] [log] [blame]
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -07003 *
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
17package org.onosproject.store.primitives;
18
19import com.google.common.base.Throwables;
20import com.google.common.collect.Multiset;
21import org.onosproject.store.service.AsyncConsistentMultimap;
Jordan Halterman5e884352018-05-21 22:11:07 -070022import org.onosproject.store.service.AsyncIterator;
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -070023import org.onosproject.store.service.ConsistentMapException;
24import org.onosproject.store.service.ConsistentMultimap;
Jonathan Hart46bf89b2017-02-27 15:56:42 -080025import org.onosproject.store.service.MultimapEventListener;
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -070026import org.onosproject.store.service.Synchronous;
27import org.onosproject.store.service.Versioned;
28
29import java.util.Collection;
Jordan Halterman5e884352018-05-21 22:11:07 -070030import java.util.Iterator;
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -070031import java.util.Map;
32import java.util.Set;
33import java.util.concurrent.CompletableFuture;
34import java.util.concurrent.ExecutionException;
Jonathan Hart46bf89b2017-02-27 15:56:42 -080035import java.util.concurrent.Executor;
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -070036import java.util.concurrent.TimeUnit;
37import java.util.concurrent.TimeoutException;
38
39/**
40 * Implementation of {@link ConsistentMultimap} providing synchronous access to
41 * {@link AsyncConsistentMultimap}.
42 */
43public class DefaultConsistentMultimap<K, V>
44 extends Synchronous<AsyncConsistentMultimap<K, V>>
45 implements ConsistentMultimap<K, V> {
46
47 private final AsyncConsistentMultimap<K, V> asyncMultimap;
48 private final long operationTimeoutMillis;
49
50 public DefaultConsistentMultimap(
51 AsyncConsistentMultimap<K, V> asyncMultimap,
52 long operationTimeoutMillis) {
53 super(asyncMultimap);
54 this.asyncMultimap = asyncMultimap;
55 this.operationTimeoutMillis = operationTimeoutMillis;
56 }
57
58 @Override
59 public int size() {
60 return complete(asyncMultimap.size());
61 }
62
63 @Override
64 public boolean isEmpty() {
65 return complete(asyncMultimap.isEmpty());
66 }
67
68 @Override
69 public boolean containsKey(K key) {
70 return complete(asyncMultimap.containsKey(key));
71 }
72
73 @Override
74 public boolean containsValue(V value) {
75 return complete(asyncMultimap.containsValue(value));
76 }
77
78 @Override
79 public boolean containsEntry(K key, V value) {
80 return complete(asyncMultimap.containsEntry(key, value));
81 }
82
83 @Override
84 public boolean put(K key, V value) {
85 return complete(asyncMultimap.put(key, value));
86 }
87
88 @Override
Jordan Halterman8c57a092018-06-04 14:53:06 -070089 public Versioned<Collection<? extends V>> putAndGet(K key, V value) {
90 return complete(asyncMultimap.putAndGet(key, value));
91 }
92
93 @Override
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -070094 public boolean remove(K key, V value) {
95 return complete(asyncMultimap.remove(key, value));
96 }
97
98 @Override
Jordan Halterman8c57a092018-06-04 14:53:06 -070099 public Versioned<Collection<? extends V>> removeAndGet(K key, V value) {
100 return complete(asyncMultimap.removeAndGet(key, value));
101 }
102
103 @Override
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700104 public boolean removeAll(K key, Collection<? extends V> values) {
105 return complete(asyncMultimap.removeAll(key, values));
106 }
107
108 @Override
109 public Versioned<Collection<? extends V>> removeAll(K key) {
110 return complete(asyncMultimap.removeAll(key));
111 }
112
113 @Override
pier4fcb4b22019-10-11 18:19:59 +0200114 public boolean removeAll(Map<K, Collection<? extends V>> mapping) {
115 return complete(asyncMultimap.removeAll(mapping));
116 }
117
118 @Override
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700119 public boolean putAll(K key, Collection<? extends V> values) {
120 return complete(asyncMultimap.putAll(key, values));
121 }
122
123 @Override
pier4fcb4b22019-10-11 18:19:59 +0200124 public boolean putAll(Map<K, Collection<? extends V>> mapping) {
125 return complete(asyncMultimap.putAll(mapping));
126 }
127
128 @Override
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700129 public Versioned<Collection<? extends V>> replaceValues(
130 K key, Collection<V> values) {
131 return complete(asyncMultimap.replaceValues(key, values));
132 }
133
134 @Override
135 public void clear() {
136 complete(asyncMultimap.clear());
137 }
138
139 @Override
140 public Versioned<Collection<? extends V>> get(K key) {
141 return complete(asyncMultimap.get(key));
142 }
143
144 @Override
145 public Set<K> keySet() {
146 return complete(asyncMultimap.keySet());
147 }
148
149 @Override
150 public Multiset<K> keys() {
151 return complete(asyncMultimap.keys());
152 }
153
154 @Override
155 public Multiset<V> values() {
156 return complete(asyncMultimap.values());
157 }
158
159 @Override
160 public Collection<Map.Entry<K, V>> entries() {
161 return complete(asyncMultimap.entries());
162 }
163
164 @Override
Jordan Halterman5e884352018-05-21 22:11:07 -0700165 public Iterator<Map.Entry<K, V>> iterator() {
166 return new DefaultIterator<>(complete(asyncMultimap.iterator()));
167 }
168
169 @Override
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700170 public Map<K, Collection<V>> asMap() {
171 throw new UnsupportedOperationException("This operation is not yet " +
172 "supported.");
173 //FIXME implement this when a new version of ConsistentMapBackedJavaMap is made for multimaps
174 }
175
Jonathan Hart46bf89b2017-02-27 15:56:42 -0800176 @Override
177 public void addListener(MultimapEventListener<K, V> listener, Executor executor) {
178 complete(asyncMultimap.addListener(listener, executor));
179 }
180
181 @Override
182 public void removeListener(MultimapEventListener<K, V> listener) {
183 complete(asyncMultimap.removeListener(listener));
184 }
185
Jordan Halterman5e884352018-05-21 22:11:07 -0700186 private class DefaultIterator<K, V> implements Iterator<Map.Entry<K, V>> {
187 private final AsyncIterator<Map.Entry<K, V>> iterator;
188
189 public DefaultIterator(AsyncIterator<Map.Entry<K, V>> iterator) {
190 this.iterator = iterator;
191 }
192
193 @Override
194 public boolean hasNext() {
195 return complete(iterator.hasNext());
196 }
197
198 @Override
199 public Map.Entry<K, V> next() {
200 return complete(iterator.next());
201 }
202 }
203
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700204 private <T> T complete(CompletableFuture<T> future) {
205 try {
206 return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS);
207 } catch (InterruptedException e) {
208 Thread.currentThread().interrupt();
209 throw new ConsistentMapException.Interrupted();
210 } catch (TimeoutException e) {
211 throw new ConsistentMapException.Timeout();
212 } catch (ExecutionException e) {
Ray Milkey6a51cb92018-03-06 09:03:03 -0800213 Throwables.throwIfUnchecked(e.getCause());
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700214 throw new ConsistentMapException(e.getCause());
215 }
216 }
217}