Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.apache.hadoop.hdds.utils.db.DBStore;
import org.apache.hadoop.hdds.utils.db.DBStoreBuilder;
import org.apache.hadoop.hdds.utils.db.Table;
import org.apache.hadoop.hdds.utils.db.Table.KeyValue;
import org.apache.hadoop.hdds.utils.db.TableIterator;
import org.apache.hadoop.ozone.recon.ReconUtils;
import org.slf4j.Logger;
Expand Down Expand Up @@ -111,16 +110,22 @@ public DBStore getDbStore() {
return dbStore;
}

static void truncateTable(Table table) throws IOException {
static <K> void truncateTable(Table<K, ?> table) throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move it to Table, make it non-static and rename it to clear().

if (table == null) {
return;
}
try (TableIterator<Object, Table.KeyValue<Object, Object>> tableIterator = table.iterator()) {
while (tableIterator.hasNext()) {
KeyValue<Object, Object> entry = tableIterator.next();
table.delete(entry.getKey());
final K firstKey;
final K lastKey;
try (TableIterator<K, K> keyIterator = table.keyIterator()) {
if (!keyIterator.hasNext()) {
return;
}
firstKey = keyIterator.next();
keyIterator.seekToLast();
lastKey = keyIterator.next();
}
table.deleteRange(firstKey, lastKey);
table.delete(lastKey);
Comment on lines +127 to +128

@szetszwo szetszwo Jul 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a new deleteRange method to including the lastKey. Google suggestion:

Image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried it a little bit:

diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/DatanodeTable.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/DatanodeTable.java
index ed7a05027e..23e807cb88 100644
--- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/DatanodeTable.java
+++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/DatanodeTable.java
@@ -68,6 +68,11 @@ public void deleteRange(KEY beginKey, KEY endKey) throws RocksDatabaseException,
     table.deleteRange(beginKey, endKey);
   }
 
+  @Override
+  public void deleteRange(KEY beginKey, KEY endKey, boolean includeEndKey) throws RocksDatabaseException, CodecException {
+    table.deleteRange(beginKey, endKey, includeEndKey);
+  }
+
   @Override
   public void deleteWithBatch(BatchOperation batch, KEY key) throws CodecException {
     table.deleteWithBatch(batch, key);
diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/SchemaOneDeletedBlocksTable.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/SchemaOneDeletedBlocksTable.java
index 913d6e30d1..2ee943ee9c 100644
--- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/SchemaOneDeletedBlocksTable.java
+++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/metadata/SchemaOneDeletedBlocksTable.java
@@ -78,6 +78,11 @@ public void deleteRange(String beginKey, String endKey) throws RocksDatabaseExce
     super.deleteRange(prefix(beginKey), prefix(endKey));
   }
 
+  @Override
+  public void deleteRange(String beginKey, String endKey, boolean includeEndKey) throws RocksDatabaseException, CodecException {
+    super.deleteRange(beginKey, endKey, includeEndKey);
+  }
+
   @Override
   public boolean isExist(String key) throws RocksDatabaseException, CodecException {
     return super.isExist(prefix(key));
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBTable.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBTable.java
index e1fc7297d4..a83f7f03bc 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBTable.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/RDBTable.java
@@ -199,6 +199,25 @@ public void deleteRange(byte[] beginKey, byte[] endKey) throws RocksDatabaseExce
     db.deleteRange(family, beginKey, endKey);
   }
 
+  @Override
+  public void deleteRange(byte[] beginKey, byte[] endKey, boolean includeEndKey) throws RocksDatabaseException, CodecException {
+    if (includeEndKey) {
+      boolean found = false;
+      for (int i = 0; i < endKey.length && !found; i++) {
+        if (endKey[i] < Byte.MAX_VALUE) {
+          endKey[i]++;
+        }
+      }
+      if (!found) {
+        final byte[] tmp = new byte[endKey.length + 1];
+        System.arraycopy(endKey, 0, tmp, 0, endKey.length);
+        tmp[endKey.length - 1] = 0;
+        endKey = tmp;
+      }
+    }
+    deleteRange(beginKey, endKey);
+  }
+
   void deleteWithBatch(BatchOperation batch, CodecBuffer key) {
     if (batch instanceof RDBBatchOperation) {
       ((RDBBatchOperation) batch).delete(family, key);
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/Table.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/Table.java
index 400547a0e3..92f309e214 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/Table.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/Table.java
@@ -134,13 +134,33 @@ default VALUE getReadCopy(KEY key) throws RocksDatabaseException, CodecException
   void deleteWithBatch(BatchOperation batch, KEY key) throws CodecException;
 
   /**
-   * Deletes a range of keys from the metadata store.
+   * Deletes a range of keys from this table.
    *
-   * @param beginKey start metadata key
-   * @param endKey end metadata key
+   * @param beginKey start key (inclusive)
+   * @param endKey end key (inclusive or exclusive, depending on includeEndKey)
+   * @param includeEndKey including end key?
    */
+  void deleteRange(KEY beginKey, KEY endKey, boolean includeEndKey) throws RocksDatabaseException, CodecException;
+
+  /** The same as deleteRange(beginKey, endKey, false). */
   void deleteRange(KEY beginKey, KEY endKey) throws RocksDatabaseException, CodecException;
 
+  /** Deletes all entries from this table. */
+  default void clear() throws RocksDatabaseException, CodecException {
+    final KEY beginKey;
+    final KEY endKey;
+    try (TableIterator<KEY, KEY> keyIterator = keyIterator()) {
+      if (!keyIterator.hasNext()) {
+        return;
+      }
+      beginKey = keyIterator.next();
+      keyIterator.seekToLast();
+      endKey = keyIterator.next();
+    }
+
+    deleteRange(beginKey, endKey, true);
+  }
+
   /** The same as iterator(null, KEY_AND_VALUE). */
   default KeyValueIterator<KEY, VALUE> iterator() throws RocksDatabaseException, CodecException {
     return iterator(null, IteratorType.KEY_AND_VALUE);
diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/TypedTable.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/TypedTable.java
index 59e924529c..e24ceb8d4d 100644
--- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/TypedTable.java
+++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/db/TypedTable.java
@@ -397,6 +397,11 @@ public void deleteRange(KEY beginKey, KEY endKey) throws RocksDatabaseException,
     rawTable.deleteRange(encodeKey(beginKey), encodeKey(endKey));
   }
 
+  @Override
+  public void deleteRange(KEY beginKey, KEY endKey, boolean includeEndKey) throws RocksDatabaseException, CodecException {
+    rawTable.deleteRange(encodeKey(beginKey), encodeKey(endKey), includeEndKey);
+  }
+
   @Override
   public KeyValueIterator<KEY, VALUE> iterator(KEY prefix, IteratorType type)
       throws RocksDatabaseException, CodecException {
diff --git a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java
index 1dbb502971..a76c6c0f25 100644
--- a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java
+++ b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/utils/db/InMemoryTestTable.java
@@ -95,6 +95,11 @@ public void deleteRange(KEY beginKey, KEY endKey) {
     map.subMap(beginKey, endKey).clear();
   }
 
+  @Override
+  public void deleteRange(KEY beginKey, KEY endKey, boolean includeEndKey) throws RocksDatabaseException, CodecException {
+    map.subMap(beginKey, true, endKey, includeEndKey).clear();
+  }
+
   @Override
   public KeyValueIterator<KEY, VALUE> iterator(KEY prefix, IteratorType type) {
     throw new UnsupportedOperationException();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the sketch! will move it into Table as clear() with the deleteRange overload.

}

private static DBStore initializeDBStore(OzoneConfiguration configuration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package org.apache.hadoop.ozone.recon.spi.impl;

import static org.apache.hadoop.ozone.recon.ReconServerConfigKeys.OZONE_RECON_DB_DIR;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import com.google.inject.AbstractModule;
Expand All @@ -28,6 +30,8 @@
import java.io.IOException;
import java.nio.file.Path;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.utils.db.Table;
import org.apache.hadoop.hdds.utils.db.TableIterator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
Expand Down Expand Up @@ -64,4 +68,36 @@ public void testGet() throws Exception {
assertNotNull(reconDBProvider.getDbStore());
}

@Test
public void testTruncateTable() throws Exception {
ReconDBProvider.truncateTable(null);

ReconDBProvider reconDBProvider = injector.getInstance(
ReconDBProvider.class);
Table<Long, Long> table = ReconDBDefinition.CONTAINER_KEY_COUNT.getTable(
reconDBProvider.getDbStore());

ReconDBProvider.truncateTable(table);
assertTableIsEmpty(table);

table.put(1L, 10L);
ReconDBProvider.truncateTable(table);
assertTableIsEmpty(table);

for (long i = 0; i < 100; i++) {
table.put(i, i);
}
ReconDBProvider.truncateTable(table);
assertTableIsEmpty(table);

table.put(7L, 70L);
assertEquals(70L, table.get(7L));
}

private static void assertTableIsEmpty(Table<?, ?> table) throws Exception {
try (TableIterator<?, ?> keyIterator = table.keyIterator()) {
assertThat(keyIterator).isExhausted();
}
}

}