bitflicker64 commented on code in PR #3299:
URL: https://github.com/apache/hugegraph/pull/3299#discussion_r4257615305


##########
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/rocksdb/RocksDBSessionsTest.java:
##########
@@ -308,6 +310,88 @@ protected Map<String, RocksDBSessions> tableDBMapping() {
         }
     }
 
+    @Test
+    public void testToplingOlapClearKeepsHandleAndOtherTables() throws 
Exception {
+        this.assertOlapClear(true, false);
+    }
+
+    @Test
+    public void testToplingOlapClearRoutesIndependentDatabase() throws 
Exception {
+        this.assertOlapClear(true, true);
+    }
+
+    @Test
+    public void testStandardOlapClearRecreatesTable() throws Exception {
+        this.assertOlapClear(false, false);
+    }
+
+    private void assertOlapClear(boolean topling, boolean separate) throws 
Exception {
+        Id id = IdGenerator.of(123L);
+        String path = DB_PATH + "/olap-clear-" + topling + "-" + separate;
+        RocksDBSessions olap = new RocksDBStdSessions(FakeObjects.newConfig(), 
"db", "olap", path, path);
+        RocksDBStore.RocksDBGraphStore store = new 
RocksDBStore.RocksDBGraphStore(
+                new RocksDBStoreProvider(), "db", "store") {
+            @Override
+            protected RocksDBSessions db(HugeType type) {
+                return type == HugeType.OLAP ? olap : super.db(type);
+            }
+        };
+        Whitebox.setInternalState(store, "sessions", separate ? this.rocks : 
olap);
+        Whitebox.setInternalState(store, "toplingProvider", topling);
+        try {
+            olap.session();
+            store.createOlapTable(id);
+            String table = "store+ap_123";
+            olap.createTable(TABLE, "other-olap");
+            RocksDBSessions.Session session = olap.session();
+            session.put(table, getBytes("m"), getBytes("old"));
+            session.put(table, getBytes("n"), getBytes("old"));
+            session.put("other-olap", getBytes("other"), getBytes("retained"));
+            session.commit();
+            session.put(TABLE, getBytes("main"), getBytes("retained main"));
+            session.commit();
+            AtomicReference<?> owner = Whitebox.getInternalState(olap, 
"rocksdb");
+            Object opened = owner.get();
+            Map<String, ?> handles = Whitebox.getInternalState(opened, 
"cfHandles");
+            Object handle = handles.get(table);
+            Assert.assertNotNull(handle);
+            for (int i = 0; i < 2; i++) {
+                // Pending keys lie outside the stored range, or in an empty 
table.
+                if (topling) {
+                    session.put(table, getBytes("a"), getBytes("pending 
first"));
+                    session.put(table, getBytes("z"), getBytes("pending 
last"));
+                }
+                store.clearOlapTable(id);
+                if (topling) {
+                    Assert.assertSame(handle, handles.get(table));
+                } else {
+                    Assert.assertNotSame(handle, handles.get(table));

Review Comment:
   Minor: on the standard branch this assertion only proves recreation for the 
first clear. `handle` is read once before the loop (line 356) and never 
refreshed, so on the second iteration it is still the pre-first-clear handle 
and `assertNotSame` passes even if the second `clearOlapTable` did not drop and 
recreate the table. Please re-read the handle at the end of each iteration (for 
example `handle = handles.get(table)` after the assertions on the standard 
branch) so the repeated clear is actually checked.



##########
hugegraph-server/hugegraph-rocksdb/src/main/java/org/apache/hugegraph/backend/store/rocksdb/RocksDBStore.java:
##########
@@ -1135,14 +1135,32 @@ public void createOlapTable(Id id) {
 
         @Override
         public void clearOlapTable(Id id) {
-            String name = this.olapTableName(id);
-            RocksDBTable table = this.table(name);
-            RocksDBSessions db = this.db(HugeType.OLAP);
-            if (!db.existsTable(table.table())) {
-                throw new HugeException("Not exist table '%s''", name);
+            Lock writeLock = this.storeLock().writeLock();
+            writeLock.lock();
+            try {
+                String name = this.olapTableName(id);
+                RocksDBTable table = this.table(name);
+                RocksDBSessions db = this.db(HugeType.OLAP);
+                if (!db.existsTable(table.table())) {
+                    throw new HugeException("Not exist table '%s''", name);
+                }
+                if (super.toplingProvider) {
+                    // Keep the CF owner alive. Use only the clearing thread's
+                    // lease so pending writes cannot be committed by 
clearTables.
+                    RocksDBSessions.Session session = 
(RocksDBSessions.Session) db.useSession();
+                    try {
+                        session.reset();

Review Comment:
   Minor: the reset is limited to the clearing thread's session, and the PR 
description states that other threads' leases are left untouched, but 
`assertOlapClear` only writes pending data from the same thread that calls 
`clearOlapTable`. Nothing pins what happens to a batch another thread has 
already filled for this table: `RocksDBSessions.clearTables` only range-deletes 
committed keys, so that batch commits after the write lock is released and its 
rows survive the clear, unlike `truncate()`, which calls `forceResetSessions` 
on every database. Please add a test that puts to the OLAP table from a second 
thread, runs the clear, commits on the second thread and asserts the intended 
outcome, and state that outcome in `docs/storage-lifecycle.md`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to