Skip to content

Commit cf3bfd6

Browse files
authored
Merge pull request #298 from HarperFast/delete-range
Delete range
2 parents 605d689 + 98530e6 commit cf3bfd6

File tree

7 files changed

+69
-152
lines changed

7 files changed

+69
-152
lines changed

src/binding/database.cpp

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,12 @@ napi_value Database::Constructor(napi_env env, napi_callback_info info) {
5555
}
5656

5757
/**
58-
* Removes all entries from the RocksDB database by dropping the column family
59-
* and recreating it.
58+
* Removes all entries in a RocksDB database column family using an uncapped range.
6059
*
6160
* @example
6261
* ```typescript
6362
* const db = new NativeDatabase();
64-
* await db.clear(); // default batch size of 10000
65-
*
66-
* await db.clear(1000); // batch size of 1000
63+
* await db.clear();
6764
* ```
6865
*/
6966
napi_value Database::Clear(napi_env env, napi_callback_info info) {
@@ -72,12 +69,6 @@ napi_value Database::Clear(napi_env env, napi_callback_info info) {
7269

7370
napi_value resolve = argv[0];
7471
napi_value reject = argv[1];
75-
uint32_t batchSize = 10000;
76-
napi_valuetype batchSizeType;
77-
NAPI_STATUS_THROWS(::napi_typeof(env, argv[2], &batchSizeType));
78-
if (batchSizeType == napi_number) {
79-
NAPI_STATUS_THROWS(::napi_get_value_uint32(env, argv[2], &batchSize));
80-
}
8172

8273
napi_value name;
8374
NAPI_STATUS_THROWS(::napi_create_string_utf8(
@@ -87,7 +78,7 @@ napi_value Database::Clear(napi_env env, napi_callback_info info) {
8778
&name
8879
))
8980

90-
auto state = new AsyncClearState(env, *dbHandle, batchSize);
81+
auto state = new AsyncClearState(env, *dbHandle);
9182
NAPI_STATUS_THROWS(::napi_create_reference(env, resolve, 1, &state->resolveRef))
9283
NAPI_STATUS_THROWS(::napi_create_reference(env, reject, 1, &state->rejectRef))
9384

@@ -101,7 +92,7 @@ napi_value Database::Clear(napi_env env, napi_callback_info info) {
10192
if (!state->handle || !state->handle->opened() || state->handle->isCancelled()) {
10293
state->status = rocksdb::Status::Aborted("Database closed during clear operation");
10394
} else {
104-
state->status = state->handle->clear(state->batchSize, state->deleted);
95+
state->status = state->handle->clear();
10596
}
10697
// signal that execute handler is complete
10798
state->signalExecuteCompleted();
@@ -116,9 +107,9 @@ napi_value Database::Clear(napi_env env, napi_callback_info info) {
116107
NAPI_STATUS_THROWS_VOID(::napi_get_global(env, &global))
117108

118109
if (state->status.ok()) {
119-
napi_value result;
120-
NAPI_STATUS_THROWS_VOID(::napi_create_int64(env, state->deleted, &result))
121-
state->callResolve(result);
110+
napi_value undefined;
111+
NAPI_STATUS_THROWS_VOID(::napi_get_undefined(env, &undefined))
112+
state->callResolve(undefined);
122113
} else {
123114
ROCKSDB_STATUS_CREATE_NAPI_ERROR_VOID(state->status, "Clear failed")
124115
state->callReject(error);
@@ -140,40 +131,24 @@ napi_value Database::Clear(napi_env env, napi_callback_info info) {
140131
}
141132

142133
/**
143-
* Removes all entries from the RocksDB database by dropping the column family
144-
* and recreating it.
134+
* Removes all entries in a RocksDB database column family using an uncapped range (synchronously).
145135
*
146136
* @example
147137
* ```typescript
148138
* const db = new NativeDatabase();
149-
* db.clearSync(); // default batch size of 10000
150-
*
151-
* db.clearSync(1000); // batch size of 1000
139+
* db.clearSync();
152140
* ```
153141
*/
154142
napi_value Database::ClearSync(napi_env env, napi_callback_info info) {
155143
NAPI_METHOD_ARGV(1)
156144
UNWRAP_DB_HANDLE_AND_OPEN()
157-
158-
// get the batch size
159-
uint32_t batchSize = 10000;
160-
napi_valuetype batchSizeType;
161-
NAPI_STATUS_THROWS(::napi_typeof(env, argv[0], &batchSizeType));
162-
if (batchSizeType == napi_number) {
163-
NAPI_STATUS_THROWS(::napi_get_value_uint32(env, argv[0], &batchSize));
164-
}
165-
166-
uint64_t deleted = 0;
167-
rocksdb::Status status = (*dbHandle)->clear(batchSize, deleted);
145+
rocksdb::Status status = (*dbHandle)->clear();
168146
if (!status.ok()) {
169147
ROCKSDB_STATUS_CREATE_NAPI_ERROR(status, "Clear failed to write batch")
170148
::napi_throw(env, error);
171149
return nullptr;
172150
}
173-
174-
napi_value result;
175-
NAPI_STATUS_THROWS(::napi_create_int64(env, deleted, &result))
176-
return result;
151+
NAPI_RETURN_UNDEFINED()
177152
}
178153

179154
/**
@@ -864,6 +839,7 @@ napi_value Database::PutSync(napi_env env, napi_callback_info info) {
864839
NAPI_RETURN_UNDEFINED()
865840
}
866841

842+
867843
/**
868844
* Removes a key from the RocksDB database.
869845
*/

src/binding/database.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,11 @@ struct Database final {
7171
struct AsyncClearState final : BaseAsyncState<std::shared_ptr<DBHandle>> {
7272
AsyncClearState(
7373
napi_env env,
74-
std::shared_ptr<DBHandle> handle,
75-
uint32_t batchSize
74+
std::shared_ptr<DBHandle> handle
7675
) :
77-
BaseAsyncState<std::shared_ptr<DBHandle>>(env, handle),
78-
batchSize(batchSize) {}
76+
BaseAsyncState<std::shared_ptr<DBHandle>>(env, handle)
77+
{}
7978

80-
uint64_t deleted;
81-
uint32_t batchSize;
8279
};
8380

8481
/**

src/binding/db_handle.cpp

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,60 +22,20 @@ DBHandle::~DBHandle() {
2222
/**
2323
* Clears all data in the database's column family.
2424
*/
25-
rocksdb::Status DBHandle::clear(uint32_t batchSize, uint64_t& deleted) {
25+
rocksdb::Status DBHandle::clear() {
2626
ASSERT_OPENED_AND_NOT_CANCELLED(this, "clear")
27-
28-
// create a write batch and iterator
29-
rocksdb::WriteBatch batch;
30-
std::unique_ptr<rocksdb::Iterator> it = std::unique_ptr<rocksdb::Iterator>(
31-
this->descriptor->db->NewIterator(
32-
rocksdb::ReadOptions(),
33-
this->column.get()
34-
)
35-
);
36-
37-
DEBUG_LOG("%p DBHandle::Clear Starting clear with batch size %u\n", this, batchSize)
38-
39-
// iterate over the database and add each key to the write batch
40-
rocksdb::Status status;
41-
deleted = 0;
42-
it->SeekToFirst();
43-
bool valid = it->Valid();
44-
while (valid) {
45-
ASSERT_OPENED_AND_NOT_CANCELLED(this, "clear")
46-
47-
batch.Delete(it->key());
48-
++deleted;
49-
it->Next();
50-
valid = it->Valid();
51-
52-
// if we've reached the end of the iterator or the batch is full, write the batch
53-
if (!valid || batch.Count() >= batchSize) {
54-
ASSERT_OPENED_AND_NOT_CANCELLED(this, "clear")
55-
DEBUG_LOG("%p DBHandle::Clear Writing batch with %zu keys\n", this, batch.Count())
56-
57-
rocksdb::WriteOptions writeOptions;
58-
writeOptions.disableWAL = this->disableWAL;
59-
60-
status = this->descriptor->db->Write(writeOptions, &batch);
61-
if (!status.ok()) {
62-
return status;
63-
}
64-
65-
batch.Clear();
66-
}
67-
}
68-
69-
// Check one final time before compaction
70-
ASSERT_OPENED_AND_NOT_CANCELLED(this, "clear")
71-
7227
// compact the database to reclaim space
73-
return this->descriptor->db->CompactRange(
28+
rocksdb::Status status = this->descriptor->db->CompactRange(
7429
rocksdb::CompactRangeOptions(),
7530
this->column.get(),
7631
nullptr,
7732
nullptr
7833
);
34+
if (!status.ok()) {
35+
return status;
36+
}
37+
// it appears we do not need to call WaitForCompact for this to work
38+
return rocksdb::DeleteFilesInRange(this->descriptor->db.get(), this->column.get(), nullptr, nullptr);
7939
}
8040

8141
/**

src/binding/db_handle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct DBHandle final : Closable, AsyncWorkHandle, public std::enable_shared_fro
6565
~DBHandle();
6666

6767
napi_ref addListener(napi_env env, std::string key, napi_value callback);
68-
rocksdb::Status clear(uint32_t batchSize, uint64_t& deleted);
68+
rocksdb::Status clear();
6969
void close();
7070
napi_value get(
7171
napi_env env,

src/database.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { DBI, type DBITransactional } from './dbi.js';
33
import { Store, type UserSharedBufferOptions, type ArrayBufferWithNotify, type StoreOptions } from './store.js';
44
import { config, type PurgeLogsOptions, type RocksDatabaseConfig, type TransactionOptions } from './load-binding.js';
55
import { Encoder as MsgpackEncoder } from 'msgpackr';
6-
import { withResolvers } from './util.js';
76
import * as orderedBinary from 'ordered-binary';
87
import type { Encoder, EncoderFunction, Key } from './encoding.js';
98

@@ -49,12 +48,10 @@ export class RocksDatabase extends DBI<DBITransactional> {
4948
* @example
5049
* ```typescript
5150
* const db = RocksDatabase.open('/path/to/database');
52-
* await db.clear(); // default batch size of 10000
53-
*
54-
* await db.clear(1000); // batch size of 1000
51+
* await db.clear();
5552
* ```
5653
*/
57-
clear(options?: { batchSize?: number }): Promise<number> {
54+
clear(): Promise<void> {
5855
if (!this.store.db.opened) {
5956
return Promise.reject(new Error('Database not open'));
6057
}
@@ -63,9 +60,9 @@ export class RocksDatabase extends DBI<DBITransactional> {
6360
this.store.encoder.structures = [];
6461
}
6562

66-
const { resolve, reject, promise } = withResolvers<number>();
67-
this.store.db.clear(resolve, reject, options?.batchSize);
68-
return promise;
63+
return new Promise((resolve, reject) => {
64+
this.store.db.clear(resolve, reject);
65+
});
6966
}
7067

7168
/**
@@ -74,12 +71,10 @@ export class RocksDatabase extends DBI<DBITransactional> {
7471
* @example
7572
* ```typescript
7673
* const db = RocksDatabase.open('/path/to/database');
77-
* db.clearSync(); // default batch size of 10000
78-
*
79-
* db.clearSync(1000); // batch size of 1000
74+
* db.clearSync();
8075
* ```
8176
*/
82-
clearSync(options?: { batchSize?: number }): number {
77+
clearSync(): void {
8378
if (!this.store.db.opened) {
8479
throw new Error('Database not open');
8580
}
@@ -88,7 +83,7 @@ export class RocksDatabase extends DBI<DBITransactional> {
8883
this.store.encoder.structures = [];
8984
}
9085

91-
return this.store.db.clearSync(options?.batchSize);
86+
return this.store.db.clearSync();
9287
}
9388

9489
/**

src/load-binding.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ export type PurgeLogsOptions = {
101101
export type NativeDatabase = {
102102
new(): NativeDatabase;
103103
addListener(event: string, callback: (...args: any[]) => void): void;
104-
clear(resolve: ResolveCallback<number>, reject: RejectCallback, batchSize?: number): void;
105-
clearSync(batchSize?: number): number;
104+
clear(resolve: ResolveCallback<void>, reject: RejectCallback): void;
105+
clearSync(): void;
106106
close(): void;
107107
flush(resolve: ResolveCallback<void>, reject: RejectCallback): void;
108108
flushSync(): void;

0 commit comments

Comments
 (0)