From ffb9044301d1c169f934e0adf4f473e99da39a47 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Mon, 27 Aug 2007 18:58:10 +0000
Subject: [PATCH] This adds the numSubordinates and hasSubordinates operational attribute support in OpenDS. - Implemented as virtual attributes - They are enabled by default - numSubordinates and hasSubordinates methods added to the backend API and implemented for all existing backends - JE implementation uses the id2children index to keep count of the number of subordinates for each entry. - The behavior of exceeding the index-entry-limit (ALL-IDs) has changed to store a 8 byte entry ID set count with the most significant bit set to 1 instead of a 0 byte array to signify the index-entry-limit has been exceeded. The previous format is still compatible but all requests for numSubordinates will return undefined (-1). - The DBTest tool is also included in this fix. This can be used to list root containers, entry containers, database containers, index status, as well as dumping a database with or without decoding the data.
---
opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 112 insertions(+), 8 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java b/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java
index 76ec3e1..ffa7a74 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java
@@ -45,6 +45,12 @@
private long[] values = null;
/**
+ * The size of the set when it is not defined. This value is only maintained
+ * when the set is undefined.
+ */
+ private long undefinedSize = Long.MAX_VALUE;
+
+ /**
* The database key containing this set, if the set was constructed
* directly from the database.
*/
@@ -56,6 +62,18 @@
public EntryIDSet()
{
values = null;
+ undefinedSize = Long.MAX_VALUE;
+ }
+
+ /**
+ * Create a new undefined set with a initial size.
+ *
+ * @param size The undefined size for this set.
+ */
+ public EntryIDSet(long size)
+ {
+ values = null;
+ undefinedSize = size;
}
/**
@@ -74,7 +92,25 @@
return;
}
- values = JebFormat.entryIDListFromDatabase(bytes);
+ if (bytes.length == 0)
+ {
+ // Entry limit has exceeded and there is no encoded undefined set size.
+ values = null;
+ undefinedSize = Long.MAX_VALUE;
+ }
+ else if ((bytes[0] & 0x80) == 0x80)
+ {
+ // Entry limit has exceeded and there is an encoded undefined set size.
+ values = null;
+ undefinedSize = JebFormat.entryIDUndefinedSizeFromDatabase(bytes);
+ }
+ else
+ {
+ // Seems like entry limit has not been exceeded and the bytes is a
+ // list of entry IDs.
+ values = JebFormat.entryIDListFromDatabase(bytes);
+ }
+
}
/**
@@ -105,15 +141,28 @@
boolean needSort = false;
int count = 0;
+ boolean undefined = false;
for (EntryIDSet l : sets)
{
if (!l.isDefined())
{
- return new EntryIDSet();
+ if(l.undefinedSize == Long.MAX_VALUE)
+ {
+ return new EntryIDSet();
+ }
+ else
+ {
+ undefined = true;
+ }
}
count += l.size();
}
+ if(undefined)
+ {
+ return new EntryIDSet(count);
+ }
+
long[] n = new long[count];
int pos = 0;
for (EntryIDSet l : sets)
@@ -165,11 +214,11 @@
*
* @return The number of IDs in the set.
*/
- public int size()
+ public long size()
{
if (values == null)
{
- return Integer.MAX_VALUE;
+ return undefinedSize;
}
else
{
@@ -200,7 +249,16 @@
if (keyBytes != null)
{
// The index entry limit was exceeded
- buffer.append("[LIMIT-EXCEEDED]");
+ if(undefinedSize == Long.MAX_VALUE)
+ {
+ buffer.append("[LIMIT-EXCEEDED]");
+ }
+ else
+ {
+ buffer.append("[LIMIT-EXCEEDED:");
+ buffer.append(undefinedSize);
+ buffer.append("]");
+ }
}
else
{
@@ -232,7 +290,14 @@
*/
public byte[] toDatabase()
{
- return JebFormat.entryIDListToDatabase(values);
+ if(isDefined())
+ {
+ return JebFormat.entryIDListToDatabase(values);
+ }
+ else
+ {
+ return JebFormat.entryIDUndefinedSizeToDatabase(undefinedSize);
+ }
}
/**
@@ -246,7 +311,11 @@
{
if (values == null)
{
- return false;
+ if(undefinedSize != Long.MAX_VALUE)
+ {
+ undefinedSize++;
+ }
+ return true;
}
long id = entryID.longValue();
@@ -299,7 +368,11 @@
{
if (values == null)
{
- return false;
+ if(undefinedSize != Long.MAX_VALUE)
+ {
+ undefinedSize--;
+ }
+ return true;
}
if (values.length == 0)
@@ -376,6 +449,7 @@
if (!this.isDefined())
{
this.values = that.values;
+ this.undefinedSize = that.undefinedSize;
return;
}
@@ -430,11 +504,26 @@
{
if (!this.isDefined())
{
+ // Can't simply add the undefined size of this set to that set since
+ // we don't know if there are any duplicates. In this case, we can't
+ // maintain the undefined size anymore.
+ if(undefinedSize != Long.MAX_VALUE && that.size() > 0)
+ {
+ undefinedSize = Long.MAX_VALUE;
+ }
return;
}
if (!that.isDefined())
{
+ if(that.size() == 0)
+ {
+ undefinedSize = values.length;
+ }
+ else
+ {
+ undefinedSize = Long.MAX_VALUE;
+ }
values = null;
return;
}
@@ -533,11 +622,26 @@
{
if (!this.isDefined())
{
+ // Can't simply subtract the undefined size of this set to that set since
+ // we don't know if there are any duplicates. In this case, we can't
+ // maintain the undefined size anymore.
+ if(undefinedSize != Long.MAX_VALUE && that.size() > 0)
+ {
+ undefinedSize = Long.MAX_VALUE;
+ }
return;
}
if (!that.isDefined())
{
+ if(that.size() == 0)
+ {
+ undefinedSize = values.length;
+ }
+ else
+ {
+ undefinedSize = Long.MAX_VALUE;
+ }
values = null;
return;
}
--
Gitblit v1.10.0