blob: ba5ff95b4096aa425db2c97ffef6071f0bbd115c [file] [log] [blame]
Madan Jampani08706ce2015-04-01 14:49:28 -07001/*
2 * Copyright 2015 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 */
16package org.onosproject.store.consistent.impl;
17
18import java.util.Collection;
19import java.util.Iterator;
Madan Jampani4c281cd2015-06-08 11:38:46 -070020import java.util.Map;
Madan Jampani08706ce2015-04-01 14:49:28 -070021import java.util.Set;
Madan Jampanibff6d8f2015-03-31 16:53:47 -070022
Madan Jampani08706ce2015-04-01 14:49:28 -070023import org.onosproject.store.service.ConsistentMap;
Madan Jampani4c281cd2015-06-08 11:38:46 -070024import org.onosproject.store.service.DistributedSet;
25import org.onosproject.store.service.MapEvent;
26import org.onosproject.store.service.MapEventListener;
27import org.onosproject.store.service.SetEvent;
28import org.onosproject.store.service.SetEventListener;
Madan Jampani08706ce2015-04-01 14:49:28 -070029
Madan Jampani4c281cd2015-06-08 11:38:46 -070030import com.google.common.collect.Maps;
Madan Jampani08706ce2015-04-01 14:49:28 -070031import com.google.common.collect.Sets;
32
33/**
34 * Implementation of distributed set that is backed by a ConsistentMap.
35
36 * @param <E> set element type
37 */
Madan Jampani4c281cd2015-06-08 11:38:46 -070038public class DefaultDistributedSet<E> implements DistributedSet<E> {
Madan Jampani08706ce2015-04-01 14:49:28 -070039
Madan Jampani4c281cd2015-06-08 11:38:46 -070040 private final String name;
Madan Jampani08706ce2015-04-01 14:49:28 -070041 private final ConsistentMap<E, Boolean> backingMap;
Madan Jampani4c281cd2015-06-08 11:38:46 -070042 private final Map<SetEventListener<E>, MapEventListener<E, Boolean>> listenerMapping = Maps.newIdentityHashMap();
Madan Jampani08706ce2015-04-01 14:49:28 -070043
Madan Jampani4c281cd2015-06-08 11:38:46 -070044 public DefaultDistributedSet(String name, ConsistentMap<E, Boolean> backingMap) {
45 this.name = name;
46 this.backingMap = backingMap;
Madan Jampani08706ce2015-04-01 14:49:28 -070047 }
48
49 @Override
50 public int size() {
51 return backingMap.size();
52 }
53
54 @Override
55 public boolean isEmpty() {
56 return backingMap.isEmpty();
57 }
58
Madan Jampanibff6d8f2015-03-31 16:53:47 -070059 @SuppressWarnings("unchecked")
Madan Jampani08706ce2015-04-01 14:49:28 -070060 @Override
61 public boolean contains(Object o) {
62 return backingMap.containsKey((E) o);
63 }
64
65 @Override
66 public Iterator<E> iterator() {
67 return backingMap.keySet().iterator();
68 }
69
70 @Override
71 public Object[] toArray() {
72 return backingMap.keySet().stream().toArray();
73 }
74
75 @Override
76 public <T> T[] toArray(T[] a) {
77 return backingMap.keySet().stream().toArray(size -> a);
78 }
79
80 @Override
81 public boolean add(E e) {
82 return backingMap.putIfAbsent(e, true) == null;
83 }
84
Madan Jampanibff6d8f2015-03-31 16:53:47 -070085 @SuppressWarnings("unchecked")
Madan Jampani08706ce2015-04-01 14:49:28 -070086 @Override
87 public boolean remove(Object o) {
Madan Jampani4c281cd2015-06-08 11:38:46 -070088 return backingMap.remove((E) o) != null;
Madan Jampani08706ce2015-04-01 14:49:28 -070089 }
90
91 @Override
92 public boolean containsAll(Collection<?> c) {
93 return c.stream()
94 .allMatch(this::contains);
95 }
96
97 @Override
98 public boolean addAll(Collection<? extends E> c) {
99 return c.stream()
100 .map(this::add)
101 .reduce(Boolean::logicalOr)
102 .orElse(false);
103 }
104
105 @Override
106 public boolean retainAll(Collection<?> c) {
107 Set<?> retainSet = Sets.newHashSet(c);
108 return backingMap.keySet()
109 .stream()
110 .filter(k -> !retainSet.contains(k))
111 .map(this::remove)
112 .reduce(Boolean::logicalOr)
113 .orElse(false);
114 }
115
116 @Override
117 public boolean removeAll(Collection<?> c) {
118 Set<?> removeSet = Sets.newHashSet(c);
119 return backingMap.keySet()
120 .stream()
121 .filter(removeSet::contains)
122 .map(this::remove)
123 .reduce(Boolean::logicalOr)
124 .orElse(false);
125 }
126
127 @Override
128 public void clear() {
129 backingMap.clear();
130 }
Madan Jampani4c281cd2015-06-08 11:38:46 -0700131
132 @Override
133 public void addListener(SetEventListener<E> listener) {
134 MapEventListener<E, Boolean> mapEventListener = mapEvent -> {
135 if (mapEvent.type() == MapEvent.Type.INSERT) {
136 listener.event(new SetEvent<>(name, SetEvent.Type.ADD, mapEvent.key()));
137 } else if (mapEvent.type() == MapEvent.Type.REMOVE) {
138 listener.event(new SetEvent<>(name, SetEvent.Type.REMOVE, mapEvent.key()));
139 }
140 };
141 if (listenerMapping.putIfAbsent(listener, mapEventListener) == null) {
142 backingMap.addListener(mapEventListener);
143 }
144 }
145
146 @Override
147 public void removeListener(SetEventListener<E> listener) {
148 MapEventListener<E, Boolean> mapEventListener = listenerMapping.remove(listener);
149 if (mapEventListener != null) {
150 backingMap.removeListener(mapEventListener);
151 }
152 }
Madan Jampani08706ce2015-04-01 14:49:28 -0700153}