1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.impl.query;
14 import java.util.Arrays;
15 import java.util.Iterator;
19 * An implementation of the <tt>Set</tt> interface that uses an
20 * open-addressed hash table to store its contents.
22 * Created: Sat Nov 3 10:38:17 2001
24 * @author Eric D. Friedman
25 * @version $Id: QueryIdentityHashSet.java,v 1.1 2008/03/14 11:32:01 tuoksk Exp $
28 final public class QueryIdentityHashSet extends QueryIdentityHash implements Iterable<CacheEntry> {
31 * Creates a new <code>THashSet</code> instance with a prime
32 * capacity equal to or greater than <tt>initialCapacity</tt> and
33 * with the default load factor.
35 * @param initialCapacity an <code>int</code> value
37 public QueryIdentityHashSet(int initialCapacity) {
38 super(initialCapacity);
42 * Inserts a value into the set.
44 * @param obj an <code>Object</code> value
45 * @return true if the set was modified by the add operation
47 final public boolean add(final CacheEntry obj) {
49 final int index = insertionIndex(obj);
52 return false; // already present in set, nothing to add
55 final CacheEntry old = _set[index];
58 postInsertHook(old == null);
59 return true; // yes, we added something
64 * Expands the set to accomodate new values.
66 * @param newCapacity an <code>int</code> value
68 final protected void rehash(int newCapacity) {
70 final int oldCapacity = _set.length;
71 final CacheEntry oldSet[] = _set;
73 _set = new CacheEntry[newCapacity];
75 for (int i = oldCapacity; i-- > 0;) {
76 if(oldSet[i] != null && oldSet[i] != REMOVED) {
77 final CacheEntry o = oldSet[i];
78 //if(o.isDiscarded()) continue;
79 final int index = insertionIndex(o);
81 new Exception().printStackTrace();
82 System.out.println("rehash " + i + " " + o);
83 for (int j = oldCapacity; j-- > 0;) {
84 System.out.println("rehash " + j+ " " + oldSet[j] + " " + System.identityHashCode(oldSet[j]));
94 * Removes <tt>obj</tt> from the set.
96 * @param obj an <code>Object</code> value
97 * @return true if the set was modified by the remove operation.
99 final public boolean remove(Object obj) {
100 int index = index(obj);
108 private int knownBound = 10;
110 final public void purge() {
112 if(size() > (knownBound<<1)) {
115 for(int i=0;i<_set.length;i++) {
116 CacheEntry entry = _set[i];
117 if(entry != null && REMOVED != entry) {
118 if(entry.isDiscarded()) {
130 final public CacheEntry removeDiscarded() {
132 tempDisableAutoCompaction();
135 for(int i=0;i<_set.length;i++) {
136 CacheEntry entry = _set[i];
137 if(entry != null && REMOVED != entry) {
139 if(!entry.isDiscarded()) return entry;
146 reenableAutoCompaction(false);
152 * Creates an iterator over the values of the set. The iterator
153 * supports element deletion.
155 * @return an <code>Iterator</code> value
157 final public Iterator<CacheEntry> iterator() {
159 class Iter implements Iterator<CacheEntry> {
161 private int index = capacity();
167 private void advance() {
168 while (index-- > 0 && (_set[index] == null || _set[index] == QueryIdentityHash.REMOVED)) ;
172 public boolean hasNext() {
177 public CacheEntry next() {
179 CacheEntry result = (CacheEntry)_set[index];
187 public void remove() {
188 throw new Error("Not supported.");
197 public void clear() {
200 Arrays.fill(_set, 0, _set.length, null);