/*
* Copyright (c) 2002-2008 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
// use array for first few properties to decrease memory footprint (and
// to some extent boost performance) for nodes/rels with few properties
public class ArrayIntSet
{
private int maxRelSize = 256;
private int[] rels = new int[2];
// TODO: figure out if we need volatile here?
private int arrayCount = 0;
private Set<Integer> relationshipSet = null;
public boolean add( int id )
{
for ( int i = 0; i < arrayCount; i++ )
{
if ( rels[i] == id )
{
return false;
}
}
if ( arrayCount == rels.length && rels.length * 2 <= maxRelSize )
{
int newRels[] = new int[rels.length * 2];
System.arraycopy( rels, 0, newRels, 0, rels.length );
rels = newRels;
}
if ( arrayCount != -1 )
{
if ( arrayCount < rels.length )
{
rels[arrayCount++] = id;
return true;
}
relationshipSet = new HashSet<Integer>();
for ( int i = 0; i < arrayCount; i++ )
{
relationshipSet.add( rels[i] );
}
arrayCount = -1;
}
return relationshipSet.add( id );
}
public Iterator<Integer> iterator()
{
if ( arrayCount == -1 )
{
return relationshipSet.iterator();
}
return new ArrayIntIterator( rels, arrayCount );
}
public boolean remove( int id )
{
for ( int i = 0; i < arrayCount; i++ )
{
if ( rels[i] == id )
{
int[] dest = rels;
if ( arrayCount - 1 < rels.length / 3 )
{
dest = new int[rels.length / 2];
System.arraycopy( rels, 0, dest, 0, arrayCount );
}
if ( i + 1 < dest.length && (arrayCount - i - 1) > 0 )
{
System.arraycopy( rels, i + 1, dest, i, arrayCount - i - 1 );
rels = dest;
}
arrayCount--;
return true;
}
}
if ( arrayCount == -1 )
{
return relationshipSet.remove( id );
}
return false;
}
public Iterable<Integer> values()
{
if ( arrayCount == -1 )
{
return relationshipSet;
}
return new ArrayIntIterator( rels, arrayCount );
}
private static class ArrayIntIterator implements Iterator<Integer>,
Iterable<Integer>
{
private int[] intArray;
private int pos = -1;
private int arrayCount;
ArrayIntIterator( int[] array, int count )
{
this.intArray = array;
this.arrayCount = count;
}
public boolean hasNext()
{
return pos + 1 < arrayCount;
}
public Integer next()
{
return intArray[++pos];
}
public void remove()
{
throw new UnsupportedOperationException();
}
public Iterator<Integer> iterator()
{
return this;
}
}
public boolean contains( int id )
{
for ( int i = 0; i < arrayCount; i++ )
{
if ( rels[i] == id )
{
return true;
}
}
if ( arrayCount == -1 )
{
return relationshipSet.contains( id );
}
return false;
}
public int size()
{
if ( arrayCount != -1 )
{
return arrayCount;
}
return relationshipSet.size();
}
}
|