// This file is part of OpenTSDB. // Copyright (C) 2015 The OpenTSDB Authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 2.1 of the License, or (at your // option) any later version. This program is distributed in the hope that it // will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser // General Public License for more details. You should have received a copy // of the GNU Lesser General Public License along with this program. If not, // see <http://www.gnu.org/licenses/>. package net.opentsdb.utils; import java.util.AbstractSet; import java.util.Arrays; import java.util.Iterator; import java.util.Set; import org.hbase.async.Bytes.ByteMap; /** * An implementation of a set based on the AsyncHBase ByteMap. This provides * a unique set implementation of byte arrays, matching on the contents of * the arrays, not on the hash codes. */ public class ByteSet extends AbstractSet<byte[]> implements Set<byte[]>, Cloneable, java.io.Serializable { private static final long serialVersionUID = -496061795957902656L; // Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); private transient ByteMap<Object> map; /** * Instantiates a unique set of byte arrays based on the array contents. */ public ByteSet() { map = new ByteMap<Object>(); } @Override public Iterator<byte[]> iterator() { return map.keySet().iterator(); } @Override public int size() { return map.size(); } @Override public boolean isEmpty() { return map.isEmpty(); } @Override public boolean contains(final Object key) { return map.containsKey(key); } @Override public boolean add(final byte[] key) { return map.put(key, PRESENT) == null; } @Override public boolean remove(final Object key) { return map.remove(key) == PRESENT; } @Override public void clear() { map.clear(); } @Override public ByteSet clone() { try { ByteSet new_set = (ByteSet) super.clone(); new_set.map = (ByteMap<Object>) map.clone(); return new_set; } catch (CloneNotSupportedException e) { throw new InternalError(); } } @Override public String toString() { final Iterator<byte[]> it = map.keySet().iterator(); if (!it.hasNext()) { return "[]"; } final StringBuilder buf = new StringBuilder(); buf.append('['); for (;;) { final byte[] array = it.next(); buf.append(Arrays.toString(array)); if (!it.hasNext()) { return buf.append(']').toString(); } buf.append(','); } } // TODO - writeObject, readObject }