Skip to content

Commit ebd33a2

Browse files
authored
Merge pull request #25 from tidesdb/0.6.0
iss #23 #24 retire unused objecttargetfilesize cf config field and ad…
2 parents 5d32046 + 756f14a commit ebd33a2

9 files changed

Lines changed: 87 additions & 14 deletions

File tree

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,3 @@ Multiple licenses apply:
3131
## Contributing
3232

3333
Contributions are welcome! Please feel free to submit a Pull Request.
34-
35-
## Support
36-
37-
- [Discord](https://discord.gg/tWEmjR66cy)
38-
- [GitHub Issues](https://github.com/tidesdb/tidesdb-ts/issues)

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tidesdb",
3-
"version": "0.5.8",
3+
"version": "0.6.0",
44
"description": "TypeScript bindings for TidesDB - A high-performance embedded key-value storage engine",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/column-family.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ export class ColumnFamily {
174174
l1FileCountTrigger: cfgDecoded.l1_file_count_trigger as number,
175175
l0QueueStallThreshold: cfgDecoded.l0_queue_stall_threshold as number,
176176
useBtree: (cfgDecoded.use_btree as number) !== 0,
177-
objectTargetFileSize: cfgDecoded.object_target_file_size as number,
178177
objectLazyCompaction: (cfgDecoded.object_lazy_compaction as number) !== 0,
179178
objectPrefetchCompaction: (cfgDecoded.object_prefetch_compaction as number) !== 0,
180179
};
@@ -295,7 +294,7 @@ export class ColumnFamily {
295294
use_btree: config.useBtree ? 1 : 0,
296295
commit_hook_fn: null,
297296
commit_hook_ctx: null,
298-
object_target_file_size: config.objectTargetFileSize ?? 0,
297+
object_target_file_size: 0,
299298
object_lazy_compaction: config.objectLazyCompaction ? 1 : 0,
300299
object_prefetch_compaction: config.objectPrefetchCompaction === false ? 0 : 1,
301300
};

src/ffi.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ export const tidesdb_txn_get = lib.func(
264264
export const tidesdb_txn_delete = lib.func(
265265
"int tidesdb_txn_delete(tidesdb_txn_t *txn, tidesdb_column_family_t *cf, const uint8_t *key, size_t key_size)",
266266
);
267+
export const tidesdb_txn_single_delete = lib.func(
268+
"int tidesdb_txn_single_delete(tidesdb_txn_t *txn, tidesdb_column_family_t *cf, const uint8_t *key, size_t key_size)",
269+
);
267270
export const tidesdb_txn_commit = lib.func(
268271
"int tidesdb_txn_commit(tidesdb_txn_t *txn)",
269272
);

src/tidesdb.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,60 @@ describe("TidesDB", () => {
124124
readTxn.free();
125125
});
126126

127+
test("singleDelete makes prior put unreadable", () => {
128+
db.createColumnFamily("sd_cf");
129+
const cf = db.getColumnFamily("sd_cf");
130+
131+
const txn = db.beginTransaction();
132+
txn.put(cf, Buffer.from("sd_key"), Buffer.from("sd_value"), -1);
133+
txn.commit();
134+
txn.free();
135+
136+
const sdTxn = db.beginTransaction();
137+
sdTxn.singleDelete(cf, Buffer.from("sd_key"));
138+
sdTxn.commit();
139+
sdTxn.free();
140+
141+
const readTxn = db.beginTransaction();
142+
expect(() => readTxn.get(cf, Buffer.from("sd_key"))).toThrow();
143+
readTxn.free();
144+
});
145+
146+
test("singleDelete on non-existent key is allowed", () => {
147+
db.createColumnFamily("sd_missing_cf");
148+
const cf = db.getColumnFamily("sd_missing_cf");
149+
150+
const txn = db.beginTransaction();
151+
expect(() => txn.singleDelete(cf, Buffer.from("missing"))).not.toThrow();
152+
txn.commit();
153+
txn.free();
154+
});
155+
156+
test("singleDelete works alongside puts in the same transaction", () => {
157+
db.createColumnFamily("sd_mixed_cf");
158+
const cf = db.getColumnFamily("sd_mixed_cf");
159+
160+
// Seed two keys
161+
const seed = db.beginTransaction();
162+
seed.put(cf, Buffer.from("keep"), Buffer.from("keep_v"), -1);
163+
seed.put(cf, Buffer.from("drop"), Buffer.from("drop_v"), -1);
164+
seed.commit();
165+
seed.free();
166+
167+
// Mixed batch: insert a new key and single-delete an existing one
168+
const mix = db.beginTransaction();
169+
mix.put(cf, Buffer.from("fresh"), Buffer.from("fresh_v"), -1);
170+
mix.singleDelete(cf, Buffer.from("drop"));
171+
mix.commit();
172+
mix.free();
173+
174+
const readTxn = db.beginTransaction();
175+
expect(readTxn.get(cf, Buffer.from("keep")).toString()).toBe("keep_v");
176+
expect(readTxn.get(cf, Buffer.from("fresh")).toString()).toBe("fresh_v");
177+
expect(() => readTxn.get(cf, Buffer.from("drop"))).toThrow();
178+
readTxn.free();
179+
});
180+
127181
test("rollback", () => {
128182
db.createColumnFamily("test_cf");
129183
const cf = db.getColumnFamily("test_cf");

src/tidesdb.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ export function defaultColumnFamilyConfig(): ColumnFamilyConfig {
107107
l1FileCountTrigger: cConfig.l1_file_count_trigger as number,
108108
l0QueueStallThreshold: cConfig.l0_queue_stall_threshold as number,
109109
useBtree: cConfig.use_btree !== 0,
110-
objectTargetFileSize: cConfig.object_target_file_size as number,
111110
objectLazyCompaction: cConfig.object_lazy_compaction !== 0,
112111
objectPrefetchCompaction: cConfig.object_prefetch_compaction !== 0,
113112
};
@@ -281,7 +280,7 @@ export class TidesDB {
281280
use_btree: mergedConfig.useBtree ? 1 : 0,
282281
commit_hook_fn: null,
283282
commit_hook_ctx: null,
284-
object_target_file_size: mergedConfig.objectTargetFileSize ?? 0,
283+
object_target_file_size: 0,
285284
object_lazy_compaction: mergedConfig.objectLazyCompaction ? 1 : 0,
286285
object_prefetch_compaction: mergedConfig.objectPrefetchCompaction === false ? 0 : 1,
287286
};

src/transaction.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
tidesdb_txn_put,
2121
tidesdb_txn_get,
2222
tidesdb_txn_delete,
23+
tidesdb_txn_single_delete,
2324
tidesdb_txn_commit,
2425
tidesdb_txn_rollback,
2526
tidesdb_txn_reset,
@@ -110,6 +111,30 @@ export class Transaction {
110111
checkResult(result, 'failed to delete key');
111112
}
112113

114+
/**
115+
* Single-delete a key from the column family.
116+
*
117+
* Writes a tombstone with the same read semantics as delete(), but lets compaction
118+
* drop the put and the tombstone together as soon as both appear in the same merge
119+
* input. The caller promises the key has been put at most once between any two
120+
* single-deletes (and between the start of the key's history and its first
121+
* single-delete). The engine does not verify this; violating the contract can
122+
* leave older puts visible after the single-delete.
123+
*
124+
* Use only for keys that are inserted exactly once and then deleted exactly once
125+
* (e.g. classic insert-benchmark patterns, secondary-index entries on never-updated
126+
* columns, log-style tables with scheduled purges). When in doubt, prefer delete().
127+
*
128+
* @param cf Column family to delete from.
129+
* @param key Key as Buffer.
130+
*/
131+
singleDelete(cf: ColumnFamily, key: Buffer): void {
132+
if (!this._txn) throw new Error('Transaction has been freed');
133+
134+
const result = tidesdb_txn_single_delete(this._txn, cf.ptr, key, key.length);
135+
checkResult(result, 'failed to single-delete key');
136+
}
137+
113138
/**
114139
* Commit the transaction.
115140
*/

src/types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,6 @@ export interface ColumnFamilyConfig {
202202
l0QueueStallThreshold?: number;
203203
/** Use B+tree format for klog (default: false = block-based). */
204204
useBtree?: boolean;
205-
/** Target SSTable size in object store mode (default 256MB, 0=auto). */
206-
objectTargetFileSize?: number;
207205
/** Compact less aggressively in object store mode (default: false). */
208206
objectLazyCompaction?: boolean;
209207
/** Download all inputs before merge in object store mode (default: true). */

0 commit comments

Comments
 (0)