diff options
Diffstat (limited to 'framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistentSet.java')
-rw-r--r-- | framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistentSet.java | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistentSet.java b/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistentSet.java new file mode 100644 index 00000000..26118cf6 --- /dev/null +++ b/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistentSet.java @@ -0,0 +1,194 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.persistence.impl; + +import com.google.common.collect.Iterators; +import org.mapdb.DB; +import org.mapdb.Hasher; +import org.mapdb.Serializer; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A set implementation that gets and receives all data from a serialized internal set. + */ +//TODO add locking for reads and writes +public class PersistentSet<E> implements Set<E> { + + private final org.onosproject.store.service.Serializer serializer; + + private final org.mapdb.DB database; + + private final Set<byte[]> items; + + private final String name; + + public PersistentSet(org.onosproject.store.service.Serializer serializer, DB database, String name) { + this.serializer = checkNotNull(serializer); + this.database = checkNotNull(database); + this.name = checkNotNull(name); + + items = database + .createHashSet(name) + .serializer(Serializer.BYTE_ARRAY) + .hasher(Hasher.BYTE_ARRAY) + .makeOrGet(); + } + + public void readInto(Set<E> items) { + this.items.forEach(item -> items.add(serializer.decode(item))); + } + + @Override + public int size() { + return items.size(); + } + + @Override + public boolean isEmpty() { + return items.isEmpty(); + } + + @Override + public boolean contains(Object o) { + checkNotNull(o, "The argument cannot be null"); + return items.contains(serializer.encode(o)); + } + + @Override + public Iterator<E> iterator() { + return Iterators.transform(items.iterator(), serializer::decode); + } + + @Override + public Object[] toArray() { + Object[] retArray = new Object[items.size()]; + int index = 0; + Iterator<byte[]> iterator = items.iterator(); + while (iterator.hasNext()) { + retArray[index] = serializer.decode(iterator.next()); + index++; + } + return retArray; + } + + @Override + public <T> T[] toArray(T[] a) { + checkNotNull(a, "The passed in array cannot be null."); + int index = 0; + Iterator<byte[]> iterator = items.iterator(); + T[] retArray; + if (a.length >= items.size()) { + retArray = a; + } else { + retArray = (T[]) new Object[items.size()]; + } + while (iterator.hasNext()) { + retArray[index++] = serializer.decode(iterator.next()); + } + if (retArray.length > items.size()) { + retArray[index] = null; + } + return retArray; + } + + @Override + public boolean add(E item) { + checkNotNull("Item to be added cannot be null."); + return items.add(serializer.encode(item)); + } + + @Override + public boolean remove(Object o) { + checkNotNull(o, "Item to be removed cannot be null."); + return items.remove(serializer.encode(o)); + } + + @Override + public boolean containsAll(Collection<?> c) { + checkNotNull(c, "Collection cannot be internal."); + for (Object item : c) { + if (!items.contains(serializer.encode(item))) { + return false; + } + } + return true; + } + + @Override + public boolean addAll(Collection<? extends E> c) { + checkNotNull(c, "The collection to be added cannot be null."); + boolean changed = false; + for (Object item : c) { + changed = items.add(serializer.encode(item)) || changed; + } + return changed; + } + + @Override + public boolean retainAll(Collection<?> c) { + boolean changed = false; + for (byte[] item : items) { + E deserialized = serializer.decode(item); + if (!c.contains(deserialized)) { + changed = items.remove(item) || changed; + } + } + return changed; + } + + @Override + public boolean removeAll(Collection<?> c) { + boolean changed = false; + for (Object item : c) { + changed = items.remove(serializer.encode(item)) || changed; + } + return changed; + } + + @Override + public void clear() { + items.clear(); + } + + @Override + public boolean equals(Object set) { + //This is not threadsafe and on larger sets incurs a significant processing cost + if (!(set instanceof Set)) { + return false; + } + Set asSet = (Set) set; + if (asSet.size() != this.size()) { + return false; + } + for (Object item : this) { + if (!asSet.contains(item)) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + return super.hashCode(); + } +}
\ No newline at end of file |