All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.permazen.core.util.ObjIdSet Maven / Gradle / Ivy


/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.core.util;

import com.google.common.base.Preconditions;

import io.permazen.core.ObjId;
import io.permazen.util.ImmutableNavigableSet;

import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;

import javax.annotation.concurrent.NotThreadSafe;

/**
 * A set of {@link ObjId}s.
 *
 * 

* This implementation is space optimized for the 64-bits of information contained in an {@link ObjId}. * Instances do not accept null values and are not thread safe. */ @NotThreadSafe public class ObjIdSet extends AbstractSet implements Cloneable, Serializable { private static final long serialVersionUID = -8245070561628904936L; private /*final*/ ObjIdMap map; // Constructors /** * Constructs an empty instance. */ public ObjIdSet() { this(0); } /** * Constructs an instance with the given initial capacity. * * @param capacity initial capacity * @throws IllegalArgumentException if {@code capacity} is negative */ public ObjIdSet(int capacity) { this(new ObjIdMap(capacity, false)); } /** * Constructs an instance initialized with the given ID's. * * @param ids initial contents for this instance * @throws IllegalArgumentException if {@code ids} is null * @throws NullPointerException if any ID in {@code ids} is null */ public ObjIdSet(Iterable ids) { this(0); Preconditions.checkArgument(ids != null, "null ids"); for (ObjId id : ids) this.add(id); } // Internal constructor ObjIdSet(ObjIdMap map) { this.map = map; } /** * Remove a single, arbitrary {@link ObjId} from this instance and return it. * * @return the removed {@link ObjId}, or null if this instance is empty */ public ObjId removeOne() { final Map.Entry entry = this.map.removeOne(); return entry != null ? entry.getKey() : null; } // Methods @Override public Iterator iterator() { return new Iterator() { private final ObjIdMap.EntrySetIterator entryIterator = ObjIdSet.this.map.new EntrySetIterator(); @Override public boolean hasNext() { return this.entryIterator.hasNext(); } @Override public ObjId next() { return this.entryIterator.next().getKey(); } @Override public void remove() { this.entryIterator.remove(); } }; } @Override public int size() { return this.map.size(); } @Override public boolean isEmpty() { return this.map.isEmpty(); } @Override public boolean contains(Object obj) { return this.map.containsKey(obj); } @Override public boolean add(ObjId id) { if (this.map.containsKey(id)) return false; this.map.put(id, null); return true; } @Override public boolean remove(Object obj) { if (!this.map.containsKey(obj)) return false; this.map.remove(obj); return true; } @Override public void clear() { this.map.clear(); } @Override public ObjId[] toArray() { return this.map.toKeysArray(); } /** * Create a sorted, immutable snapshot of this instance. * * @return sorted, immutable snapshot */ @SuppressWarnings("unchecked") public ImmutableNavigableSet sortedSnapshot() { final ObjId[] array = this.toArray(); Arrays.sort(array); return new ImmutableNavigableSet<>(array, ObjId::compareTo); } /** * Produce a debug dump of this instance. */ String debugDump() { return this.map.debugDump(); } // Object // This works because ObjId.hashCode() == ObjId.asLong().hashCode() @Override public int hashCode() { final long[] keyArray = this.map.getKeys(); int hash = 0; for (final long key : keyArray) { if (key != 0) hash += Long.hashCode(key); } return hash; } // Cloneable @Override public ObjIdSet clone() { final ObjIdSet clone; try { clone = (ObjIdSet)super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } clone.map = clone.map.clone(); return clone; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy