/*
* JacORB - a free Java ORB
*
* Copyright (C) 1999-2014 Gerald Brose / The JacORB Team.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
package org.jacorb.collection.util;
import java.util.Enumeration;
/**
* @author Gerald Brose
*/
public class SortedVector
{
private final DynArray data;
private final ObjectComparator cmpr;
/* -------------------------------------------------------------------------- */
public SortedVector( ObjectComparator cmpr )
{
data = new DynArray();
this.cmpr = cmpr;
}
/* -------------------------------------------------------------------------- */
public SortedVector( ObjectComparator cmpr, int capacity )
{
data = new DynArray( capacity );
this.cmpr = cmpr;
}
/* -------------------------------------------------------------------------- */
public int addElement( Object obj ) throws ObjectInvalid
{
cmpr.element( obj );
int pos = find_nearest();
if ( pos > -1 && cmpr.compare_with( data.elementAt(0) ) >= 0 )
{
while( pos < data.size() && cmpr.compare_with( data.elementAt(pos) ) >= 0 )
{
pos++;
}
}
else
{
pos = 0;
}
data.insertElementAt( obj, pos );
return pos;
}
/* -------------------------------------------------------------------------- */
public int size()
{
return data.size();
}
/* -------------------------------------------------------------------------- */
public Object elementAt( int index )
{
return data.elementAt( index );
}
/* -------------------------------------------------------------------------- */
public Enumeration elements()
{
return data.elements();
}
/* -------------------------------------------------------------------------- */
public Object removeElementAt( int index )
{
Object obj = data.elementAt( index );
data.removeElementAt( index );
return obj;
}
/* -------------------------------------------------------------------------- */
public void removeAllElements()
{
data.removeAllElements();
}
/* -------------------------------------------------------------------------- */
public int indexOf( Object obj ) throws ObjectInvalid
{
cmpr.element( obj );
int i = find_nearest();
if( i == data.size() )
{
i--;
}
if( i >= data.size() || i<0 )
{
return -1;
}
int j = i;
while( j >= 0 && cmpr.compare_with( data.elementAt(j) ) <= 0 )
{
if( cmpr.equal( data.elementAt( j ) ) )
{
return j;
}
j--;
}
j = i+1;
while( j < data.size() && cmpr.compare_with( data.elementAt(j) ) >= 0 )
{
if( cmpr.equal( data.elementAt( j ) ) )
{
return j;
}
j++;
}
return -1;
}
/* -------------------------------------------------------------------------- */
public void setElementAt( Object obj, int index ) throws ObjectInvalid
{
if( !isIndexValid( index, obj ) )
{
throw new ObjectInvalid();
}
data.setElementAt( obj, index );
}
/* -------------------------------------------------------------------------- */
public boolean isIndexValid( int index, Object obj ) throws ObjectInvalid
{
cmpr.element( obj );
if( data.size() == 0 )
{
return true;
}
int i = find_nearest();
if( cmpr.equal( data.elementAt(i) ) )
{
return true;
}
else if( ( i==0 || cmpr.compare_with( data.elementAt(i-1) ) >= 0 )
&& ( i==data.size() || cmpr.compare_with( data.elementAt(i) ) <= 0 ) )
{
return true;
}
return false;
}
/* -------------------------------------------------------------------------- */
public boolean insertElementAt( Object obj, int index ) throws ObjectInvalid
{
if( isIndexValid( index, obj ) )
{
data.insertElementAt( obj, index );
}
return false;
}
/* -------------------------------------------------------------------------- */
private int find_nearest() throws ObjectInvalid
{
if( data.size() == 0 )
{
return -1;
}
int first = 0;
if( cmpr.compare_with( data.elementAt(first) ) <= 0 )
{
return first;
}
int last = data.size()-1;
if( cmpr.compare_with( data.elementAt(last) ) >= 0 )
{
return data.size();
}
if ( first == last )
{
if ( cmpr.compare_with( data.elementAt(last) ) <= 0 )
{
return first;
}
return first+1;
}
int result = 0;
int pos = first;
while( first < last )
{
pos = (first+last)/2;
if ( pos == first )
{
return ++pos;
}
if ( pos == last )
{
return ++pos;
}
result = cmpr.compare_with( data.elementAt(pos) );
if( result == 0 )
{
return ++pos;
}
else if( result > 0 )
{
first = pos;
}
else
{
last = pos;
}
}
return pos;
}
}