EntryIDSet.java revision 763a75aeed1a7731ddb95b99496aa7c1bf206ed0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
* Portions Copyright 2014-2015 ForgeRock AS
*/
/**
* Represents a set of Entry IDs. It can represent a set where the IDs are
* not defined, for example when the index entry limit has been exceeded.
*/
{
/**
* The IDs are stored here in an array in ascending order.
* A null array implies not defined, rather than zero IDs.
*/
private long[] values;
/**
* The size of the set when it is not defined. This value is only maintained
* when the set is undefined.
*/
/**
* The database key containing this set, if the set was constructed
* directly from the database.
*/
private final ByteSequence key;
/** Create a new undefined set. */
public EntryIDSet()
{
}
/**
* Create a new undefined set with a initial size.
*
* @param size The undefined size for this set.
*/
EntryIDSet(long size)
{
this.undefinedSize = size;
}
/**
* Create a new entry ID set from the raw database value.
*
* @param key
* The database key that contains this value.
* @param bytes
* The database value, or null if there are no entry IDs.
*/
{
{
values = new long[0];
}
{
// Entry limit has exceeded and there is no encoded undefined set size.
}
{
// Entry limit has exceeded and there is an encoded undefined set size.
}
else
{
// Seems like entry limit has not been exceeded and the bytes is a
// list of entry IDs.
}
}
/**
* Decodes and returns the undefined size out of the provided byte string.
*
* @param bytes
* the encoded undefined size
* @return the undefined size
*/
{
}
/**
* Decodes and returns the entryID list out of the provided byte sequence.
*
* @param bytes
* the encoded entryID list
* @return a long array representing the entryID list
*/
{
final long[] entryIDList = new long[count];
for (int i = 0; i < count; i++)
{
}
return entryIDList;
}
/**
* Construct an EntryIDSet from an array of longs.
*
* @param values The array of IDs represented as longs.
* @param pos The position of the first ID to take from the array.
* @param len the number of IDs to take from the array.
*/
{
}
/**
* Create a new set of entry IDs that is the union of several entry ID sets.
*
* @param sets A list of entry ID sets.
* @param allowDuplicates true if duplicate IDs are allowed in the resulting
* set, or if the provided sets are sure not to overlap; false if
* duplicates should be eliminated.
* @return The union of the provided entry ID sets.
*/
boolean allowDuplicates)
{
int count = 0;
boolean undefined = false;
for (EntryIDSet l : sets)
{
if (!l.isDefined())
{
{
return new EntryIDSet();
}
undefined = true;
}
}
if(undefined)
{
return new EntryIDSet(count);
}
boolean needSort = false;
long[] n = new long[count];
int pos = 0;
for (EntryIDSet l : sets)
{
{
{
needSort = true;
}
}
}
if (needSort)
{
}
if (allowDuplicates)
{
return ret;
}
long last = -1;
int j = 0;
for (long l : n)
{
if (l != last)
{
}
}
{
return ret;
}
else
{
}
}
/**
* Get the size of this entry ID set.
*
* @return The number of IDs in the set.
*/
public long size()
{
{
}
return undefinedSize;
}
/**
* Get a string representation of this object.
* @return A string representation of this object.
*/
{
}
/**
* Convert to a short string to aid with debugging.
*
* @param buffer The string is appended to this string builder.
*/
{
if (!isDefined())
{
{
// The index entry limit was exceeded
{
}
else
{
}
}
else
{
// Not indexed
}
}
else
{
}
}
/**
* Determine whether this set of IDs is defined.
*
* @return true if the set of IDs is defined.
*/
boolean isDefined()
{
}
/**
* Get a database representation of this object.
* @return A database representation of this object as a byte array.
*/
{
if (isDefined())
{
{
}
return builder.toByteString();
}
else
{
// Set top bit.
}
}
/**
* Insert an ID into this set.
*
* @param entryID The ID to be inserted.
* @return true if the set was changed, false if it was not changed,
* for example if the set is undefined or the ID was already present.
*/
{
{
{
}
return true;
}
{
return true;
}
{
}
else
{
if (pos >= 0)
{
// The ID is already present.
return false;
}
// For a negative return value r, the index -(r+1) gives the array
// index at which the specified value can be inserted to maintain
// the sorted order of the array.
}
return true;
}
/**
* Remove an ID from this set.
*
* @param entryID The ID to be removed
* @return true if the set was changed, false if it was not changed,
* for example if the set was undefined or the ID was not present.
*/
{
{
{
}
return true;
}
{
return false;
}
// Binary search to locate the ID.
if (pos >= 0)
{
// Found it.
return true;
}
// Not found.
return false;
}
/**
* Check whether this set of entry IDs contains a given ID.
*
* @param entryID The ID to be checked.
* @return true if this set contains the given ID,
* or if the set is undefined.
*/
{
{
return true;
}
}
/**
* Takes the intersection of this set with another.
* Retain those IDs that appear in the given set.
*
* @param that The set of IDs that are to be retained from this object.
*/
{
if (!isDefined())
{
return;
}
{
return;
}
// TODO Perhaps Arrays.asList and retainAll list method are more efficient?
long[] a = this.values;
{
{
ai++;
bi++;
ci++;
}
{
bi++;
}
else
{
ai++;
}
}
{
}
else
{
values = c;
}
}
/**
* Add all the IDs from a given set that are not already present.
*
* @param that The set of IDs to be added. It MUST be defined
*/
{
{
return;
}
if (!isDefined())
{
// Assume there are no overlap between IDs in that set with this set
{
}
return;
}
long[] a = this.values;
if (a.length == 0)
{
values = b;
return;
}
if (b.length == 0)
{
return;
}
// Optimize for case where the two sets are sure to have no overlap.
{
// All IDs in 'b' are greater than those in 'a'.
values = n;
return;
}
{
// All IDs in 'a' are greater than those in 'b'.
values = n;
return;
}
long[] n;
n = a;
a = b;
b = n;
}
} else {
ai++;
bi++;
}
}
// Copy any remainder from the first array.
if (aRemain > 0)
{
}
// Copy any remainder from the second array.
if (bRemain > 0)
{
}
{
}
else
{
values = n;
}
}
/**
* Delete all IDs in this set that are in a given set.
*
* @param that The set of IDs to be deleted. It MUST be defined.
*/
{
{
return;
}
if (!isDefined())
{
// Assume all IDs in the given set exists in this set.
{
}
return;
}
long[] a = this.values;
// Optimize for cases where the two sets are sure to have no overlap.
{
return;
}
long[] n = new long[a.length];
bi++;
} else {
ai++;
bi++;
}
}
{
}
else
{
values = n;
}
}
/**
* Create an iterator over the set or an empty iterator
* if the set is not defined.
*
* @return An EntryID iterator.
*/
{
}
/**
* Create an iterator over the set or an empty iterator
* if the set is not defined.
*
* @param begin The entry ID of the first entry to return in the list.
*
* @return An EntryID iterator.
*/
{
{
// The set is defined.
}
// The set is not defined.
return new IDSetIterator(new long[0]);
}
}