blob: c14b187178acbe0470e3d01dd6272c177f84094e [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
114 public boolean putAll(K key, Collection<? extends V> values) {
115 return complete(asyncMultimap.putAll(key, values));
116 }
117
118 @Override
119 public Versioned<Collection<? extends V>> replaceValues(
120 K key, Collection<V> values) {
121 return complete(asyncMultimap.replaceValues(key, values));
122 }
123
124 @Override
125 public void clear() {
126 complete(asyncMultimap.clear());
127 }
128
129 @Override
130 public Versioned<Collection<? extends V>> get(K key) {
131 return complete(asyncMultimap.get(key));
132 }
133
134 @Override
135 public Set<K> keySet() {
136 return complete(asyncMultimap.keySet());
137 }
138
139 @Override
140 public Multiset<K> keys() {
141 return complete(asyncMultimap.keys());
142 }
143
144 @Override
145 public Multiset<V> values() {
146 return complete(asyncMultimap.values());
147 }
148
149 @Override
150 public Collection<Map.Entry<K, V>> entries() {
151 return complete(asyncMultimap.entries());
152 }
153
154 @Override
Jordan Halterman5e884352018-05-21 22:11:07 -0700155 public Iterator<Map.Entry<K, V>> iterator() {
156 return new DefaultIterator<>(complete(asyncMultimap.iterator()));
157 }
158
159 @Override
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700160 public Map<K, Collection<V>> asMap() {
161 throw new UnsupportedOperationException("This operation is not yet " +
162 "supported.");
163 //FIXME implement this when a new version of ConsistentMapBackedJavaMap is made for multimaps
164 }
165
Jonathan Hart46bf89b2017-02-27 15:56:42 -0800166 @Override
167 public void addListener(MultimapEventListener<K, V> listener, Executor executor) {
168 complete(asyncMultimap.addListener(listener, executor));
169 }
170
171 @Override
172 public void removeListener(MultimapEventListener<K, V> listener) {
173 complete(asyncMultimap.removeListener(listener));
174 }
175
Jordan Halterman5e884352018-05-21 22:11:07 -0700176 private class DefaultIterator<K, V> implements Iterator<Map.Entry<K, V>> {
177 private final AsyncIterator<Map.Entry<K, V>> iterator;
178
179 public DefaultIterator(AsyncIterator<Map.Entry<K, V>> iterator) {
180 this.iterator = iterator;
181 }
182
183 @Override
184 public boolean hasNext() {
185 return complete(iterator.hasNext());
186 }
187
188 @Override
189 public Map.Entry<K, V> next() {
190 return complete(iterator.next());
191 }
192 }
193
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700194 private <T> T complete(CompletableFuture<T> future) {
195 try {
196 return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS);
197 } catch (InterruptedException e) {
198 Thread.currentThread().interrupt();
199 throw new ConsistentMapException.Interrupted();
200 } catch (TimeoutException e) {
201 throw new ConsistentMapException.Timeout();
202 } catch (ExecutionException e) {
Ray Milkey6a51cb92018-03-06 09:03:03 -0800203 Throwables.throwIfUnchecked(e.getCause());
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700204 throw new ConsistentMapException(e.getCause());
205 }
206 }
207}