/*
* eXist Open Source Native XML Database
* Copyright (C) 2010 The eXist Project
* http://exist-db.org
*
* 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
* 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package org.exist.util.hashtable;
import net.jcip.annotations.NotThreadSafe;
import java.util.Iterator;
/**
* Abstract base class for all hashset implementations.
*/
@NotThreadSafe
public abstract class AbstractHashSet<K> implements Iterable<K> {
private static final int DEFAULT_SIZE = 1031; // must be a prime number
// marker for removed objects
protected final static Object REMOVED = new Object();
protected int tabSize;
protected int items;
private int maxRehash = 0;
/**
* Create a new hashset with default size (1031).
*/
AbstractHashSet() {
items = 0;
tabSize = DEFAULT_SIZE;
}
/**
* Create a new hashtable using the specified size.
*
* The actual size will be next prime number following
* iSize * 1.5.
*
* @param iSize Initial size of the hash set
*/
public AbstractHashSet(int iSize) {
items = 0;
if (iSize < 1) {
tabSize = DEFAULT_SIZE;
} else {
if (!isPrime(iSize)) {
iSize = (iSize * 3) / 2;
iSize = (int) nextPrime((long) iSize);
}
tabSize = iSize;
}
}
public int size() {
return items;
}
public boolean isEmpty() {
return items == 0;
}
private static boolean isPrime(final long number) {
if (number < 2) {
return false;
} else if (number == 2) {
return true;
} else if (number % 2 == 0) {
return false;
} else if (number == 3) {
return true;
} else if (number % 3 == 0) {
return false;
}
int y = 2;
final int x = (int) Math.sqrt(number);
for (int i = 5; i <= x; i += y, y = 6 - y) {
if (number % i == 0) {
return false;
}
}
return true;
}
static long nextPrime(final long iVal) {
long retval = iVal;
for (; ; ) {
++retval;
if (isPrime(retval)) {
return retval;
}
}
}
public int getMaxRehash() {
return maxRehash;
}
enum IteratorType {KEYS, VALUES}
abstract class AbstractHashSetIterator<T> implements Iterator<T> {
protected final IteratorType returnType;
AbstractHashSetIterator(final IteratorType type) {
this.returnType = type;
}
}
public final static class HashSetOverflowException extends Exception {
private static final long serialVersionUID = -4679763007424266920L;
public HashSetOverflowException() {
super();
}
}
}