blob: 600af28106f175f907f7e732a90bbf907f004536 [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
89 public boolean remove(K key, V value) {
90 return complete(asyncMultimap.remove(key, value));
91 }
92
93 @Override
94 public boolean removeAll(K key, Collection<? extends V> values) {
95 return complete(asyncMultimap.removeAll(key, values));
96 }
97
98 @Override
99 public Versioned<Collection<? extends V>> removeAll(K key) {
100 return complete(asyncMultimap.removeAll(key));
101 }
102
103 @Override
104 public boolean putAll(K key, Collection<? extends V> values) {
105 return complete(asyncMultimap.putAll(key, values));
106 }
107
108 @Override
109 public Versioned<Collection<? extends V>> replaceValues(
110 K key, Collection<V> values) {
111 return complete(asyncMultimap.replaceValues(key, values));
112 }
113
114 @Override
115 public void clear() {
116 complete(asyncMultimap.clear());
117 }
118
119 @Override
120 public Versioned<Collection<? extends V>> get(K key) {
121 return complete(asyncMultimap.get(key));
122 }
123
124 @Override
125 public Set<K> keySet() {
126 return complete(asyncMultimap.keySet());
127 }
128
129 @Override
130 public Multiset<K> keys() {
131 return complete(asyncMultimap.keys());
132 }
133
134 @Override
135 public Multiset<V> values() {
136 return complete(asyncMultimap.values());
137 }
138
139 @Override
140 public Collection<Map.Entry<K, V>> entries() {
141 return complete(asyncMultimap.entries());
142 }
143
144 @Override
Jordan Halterman5e884352018-05-21 22:11:07 -0700145 public Iterator<Map.Entry<K, V>> iterator() {
146 return new DefaultIterator<>(complete(asyncMultimap.iterator()));
147 }
148
149 @Override
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700150 public Map<K, Collection<V>> asMap() {
151 throw new UnsupportedOperationException("This operation is not yet " +
152 "supported.");
153 //FIXME implement this when a new version of ConsistentMapBackedJavaMap is made for multimaps
154 }
155
Jonathan Hart46bf89b2017-02-27 15:56:42 -0800156 @Override
157 public void addListener(MultimapEventListener<K, V> listener, Executor executor) {
158 complete(asyncMultimap.addListener(listener, executor));
159 }
160
161 @Override
162 public void removeListener(MultimapEventListener<K, V> listener) {
163 complete(asyncMultimap.removeListener(listener));
164 }
165
Jordan Halterman5e884352018-05-21 22:11:07 -0700166 private class DefaultIterator<K, V> implements Iterator<Map.Entry<K, V>> {
167 private final AsyncIterator<Map.Entry<K, V>> iterator;
168
169 public DefaultIterator(AsyncIterator<Map.Entry<K, V>> iterator) {
170 this.iterator = iterator;
171 }
172
173 @Override
174 public boolean hasNext() {
175 return complete(iterator.hasNext());
176 }
177
178 @Override
179 public Map.Entry<K, V> next() {
180 return complete(iterator.next());
181 }
182 }
183
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700184 private <T> T complete(CompletableFuture<T> future) {
185 try {
186 return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS);
187 } catch (InterruptedException e) {
188 Thread.currentThread().interrupt();
189 throw new ConsistentMapException.Interrupted();
190 } catch (TimeoutException e) {
191 throw new ConsistentMapException.Timeout();
192 } catch (ExecutionException e) {
Ray Milkey6a51cb92018-03-06 09:03:03 -0800193 Throwables.throwIfUnchecked(e.getCause());
Aaron Kruglikovb6ec9cd2016-07-25 16:01:10 -0700194 throw new ConsistentMapException(e.getCause());
195 }
196 }
197}