From ddcb0381c8b26eb560fdf920aefeb03cbb2739d1 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Tue, 22 Apr 2008 13:43:03 +0000
Subject: [PATCH] The new IndexBuffer class was accidentally left out in the commit for revision 4180.

---
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexBuffer.java |  236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 236 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexBuffer.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexBuffer.java
new file mode 100644
index 0000000..839d87d
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/IndexBuffer.java
@@ -0,0 +1,236 @@
+/*
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  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.
+ */
+package org.opends.server.backends.jeb;
+
+import com.sleepycat.je.Transaction;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.DatabaseEntry;
+
+import java.util.*;
+
+import org.opends.server.types.DirectoryException;
+
+/**
+ * A buffered index is used to buffer multiple reads or writes to the
+ * same index key into a single read or write.
+ * It can only be used to buffer multiple reads and writes under
+ * the same transaction. The transaction may be null if it is known
+ * that there are no other concurrent updates to the index.
+ */
+public class IndexBuffer
+{
+  private EntryContainer entryContainer;
+
+  /**
+   * The buffered records stored as a map from the record key to the
+   * buffered value for that key for each index.
+   */
+  private LinkedHashMap<Index,
+      TreeMap<byte[], BufferedIndexValues>> bufferedIndexes;
+
+  /**
+   * The buffered records stored as a set of buffered VLV values
+   * for each index.
+   */
+  private LinkedHashMap<VLVIndex, BufferedVLVValues> bufferedVLVIndexes;
+
+  /**
+   * A simple class representing a pair of added and deleted indexed IDs.
+   */
+  public static class BufferedIndexValues {
+    EntryIDSet addedIDs;
+    EntryIDSet deletedIDs;
+  }
+
+  /**
+   * A simple class representing a pair of added and deleted VLV values.
+   */
+  public static class BufferedVLVValues {
+    TreeSet<SortValues> addedValues;
+    TreeSet<SortValues> deletedValues;
+  }
+
+  /**
+   * Construct a new empty index buffer object.
+   *
+   * @param entryContainer The database entryContainer using this
+   * index buffer.
+   */
+  public IndexBuffer(EntryContainer entryContainer)
+  {
+    bufferedIndexes =
+        new LinkedHashMap<Index, TreeMap<byte[], BufferedIndexValues>>();
+    bufferedVLVIndexes = new LinkedHashMap<VLVIndex, BufferedVLVValues>();
+    this.entryContainer = entryContainer;
+  }
+
+  /**
+   * Get the buffered values for the given index.
+   *
+   * @param index The index with the buffered values to retrieve.
+   * @return The buffered values or <code>null</code> if there are
+   * no buffered values for the specified index.
+   */
+  public TreeMap<byte[], BufferedIndexValues> getBufferedIndex(Index index)
+  {
+    return bufferedIndexes.get(index);
+  }
+
+  /**
+   * Put the specified buffered index values for the given index.
+   *
+   * @param index The index affected by the buffered values.
+   * @param bufferedValues The buffered values for the index.
+   */
+  public void putBufferedIndex(Index index, TreeMap<byte[],
+      BufferedIndexValues> bufferedValues)
+  {
+    bufferedIndexes.put(index, bufferedValues);
+  }
+
+  /**
+   * Get the buffered VLV values for the given VLV index.
+   *
+   * @param vlvIndex The VLV index with the buffered values to retrieve.
+   * @return The buffered VLV values or <code>null</code> if there are
+   * no buffered VLV values for the specified VLV index.
+   */
+  public BufferedVLVValues getVLVIndex(VLVIndex vlvIndex)
+  {
+    return bufferedVLVIndexes.get(vlvIndex);
+  }
+
+  /**
+   * Put the specified buffered VLV values for the given VLV index.
+   *
+   * @param vlvIndex The VLV index affected by the buffered values.
+   * @param bufferedVLVValues The buffered values for the VLV index.
+   */
+  public void putBufferedVLVIndex(VLVIndex vlvIndex,
+                          BufferedVLVValues bufferedVLVValues)
+  {
+    bufferedVLVIndexes.put(vlvIndex, bufferedVLVValues);
+  }
+
+  /**
+   * Flush the buffered index changes until the given transaction to
+   * the database.
+   *
+   * @param txn The database transaction to be used for the updates.
+   * @throws DatabaseException If an error occurs in the JE database.
+   * @throws DirectoryException If a Directory Server error occurs.
+   * @throws JebException If an error occurs in the JE backend.
+   */
+  public void flush(Transaction txn)
+      throws DatabaseException, DirectoryException, JebException
+  {
+    TreeMap<byte[], BufferedIndexValues> bufferedValues;
+    BufferedVLVValues bufferedVLVValues;
+    byte[] keyBytes;
+    DatabaseEntry key = new DatabaseEntry();
+
+    for(AttributeIndex attributeIndex :
+        entryContainer.getAttributeIndexes())
+    {
+      for(Index index : attributeIndex.getAllIndexes())
+      {
+        bufferedValues = bufferedIndexes.remove(index);
+
+        if(bufferedValues != null)
+        {
+          Iterator<Map.Entry<byte[], BufferedIndexValues>> keyIterator =
+              bufferedValues.entrySet().iterator();
+          while(keyIterator.hasNext())
+          {
+            Map.Entry<byte[], BufferedIndexValues> bufferedKey =
+                keyIterator.next();
+            keyBytes = bufferedKey.getKey();
+            key.setData(keyBytes);
+
+            index.updateKey(txn, key, bufferedKey.getValue().deletedIDs,
+                bufferedKey.getValue().addedIDs);
+
+            keyIterator.remove();
+          }
+        }
+      }
+    }
+
+    for(VLVIndex vlvIndex : entryContainer.getVLVIndexes())
+    {
+      bufferedVLVValues = bufferedVLVIndexes.remove(vlvIndex);
+
+      if(bufferedVLVValues != null)
+      {
+        vlvIndex.updateIndex(txn, bufferedVLVValues.addedValues,
+            bufferedVLVValues.deletedValues);
+      }
+    }
+
+    Index id2children = entryContainer.getID2Children();
+    bufferedValues = bufferedIndexes.remove(id2children);
+
+    if(bufferedValues != null)
+    {
+      Iterator<Map.Entry<byte[], BufferedIndexValues>> keyIterator =
+          bufferedValues.entrySet().iterator();
+      while(keyIterator.hasNext())
+      {
+        Map.Entry<byte[], BufferedIndexValues> bufferedKey =
+            keyIterator.next();
+        keyBytes = bufferedKey.getKey();
+        key.setData(keyBytes);
+
+        id2children.updateKey(txn, key, bufferedKey.getValue().deletedIDs,
+            bufferedKey.getValue().addedIDs);
+
+        keyIterator.remove();
+      }
+    }
+
+    Index id2subtree = entryContainer.getID2Subtree();
+    bufferedValues = bufferedIndexes.remove(id2subtree);
+
+    if(bufferedValues != null)
+    {
+      Iterator<Map.Entry<byte[], BufferedIndexValues>> keyIterator =
+          bufferedValues.entrySet().iterator();
+      while(keyIterator.hasNext())
+      {
+        Map.Entry<byte[], BufferedIndexValues> bufferedKey =
+            keyIterator.next();
+        keyBytes = bufferedKey.getKey();
+        key.setData(keyBytes);
+
+        id2subtree.updateKey(txn, key, bufferedKey.getValue().deletedIDs,
+            bufferedKey.getValue().addedIDs);
+
+        keyIterator.remove();
+      }
+    }
+  }
+}

--
Gitblit v1.10.0