From 5d726eaa0659d2dc17f903db4010695a04017fe2 Mon Sep 17 00:00:00 2001 From: rafapaezbas Date: Fri, 14 Apr 2023 12:42:09 +0200 Subject: [PATCH 1/2] added onlyIfChanged opt --- README.md | 3 ++- index.js | 4 +++- package.json | 1 + test/basic.js | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 871b7583..567ea4f6 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,8 @@ Options include: ``` { keyEncoding: 'utf-8' | 'binary' | 'ascii', // or some abstract encoding - valueEncoding: + valueEncoding: , + onlyIfChanged: true // put or delete a value only if it means a change in the db } ``` diff --git a/index.js b/index.js index d3893742..f6795276 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,4 @@ +const sameData = require('same-data') const codecs = require('codecs') const { Readable } = require('streamx') const mutexify = require('mutexify/promise') @@ -284,6 +285,7 @@ class Hyperbee { this.sep = opts.sep || SEP this.readonly = !!opts.readonly this.prefix = opts.prefix || null + this.onlyIfChanged = !!opts.onlyIfChanged this._unprefixedKeyEncoding = this.keyEncoding this._sub = !!this.prefix @@ -616,7 +618,7 @@ class Batch { async put (key, value, opts) { const release = this.batchLock ? await this.batchLock() : null - const cas = (opts && opts.cas) || null + const cas = (opts && opts.cas) || (this.tree.onlyIfChanged ? sameData : null) const encoding = this._getEncoding(opts) if (!this.locked) await this.lock() diff --git a/package.json b/package.json index 713ac7ac..c5658a02 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "mutexify": "^1.4.0", "protocol-buffers-encodings": "^1.2.0", "safety-catch": "^1.0.2", + "same-data": "^1.0.0", "streamx": "^2.12.4" }, "devDependencies": { diff --git a/test/basic.js b/test/basic.js index e59b5afb..ed245349 100644 --- a/test/basic.js +++ b/test/basic.js @@ -1,7 +1,6 @@ const test = require('brittle') const b4a = require('b4a') const { create, collect, createCore } = require('./helpers') - const Hyperbee = require('..') test('out of bounds iterator', async function (t) { @@ -486,3 +485,39 @@ test('supports encodings in snapshot', async function (t) { t.alike(await snap1.get('hi'), { seq: 1, key: b4a.from('hi'), value: 'there' }) t.alike(await snap2.get('hi'), { seq: 1, key: 'hi', value: b4a.from('there') }) }) + +test('onlyIfChanged put', async function (t) { + { + const db = create({ onlyIfChanged: true }) + await db.ready() + await db.put('key', 'value') + t.is(db.feed.length, 2) + await db.put('key', 'value') + t.is(db.feed.length, 2) + } + { + const db = create({ onlyIfChanged: true, valueEncoding: 'binary' }) + await db.ready() + await db.put('key', Buffer.from('buffer')) + t.is(db.feed.length, 2) + await db.put('key', Buffer.from('buffer')) + t.is(db.feed.length, 2) + } + { + const db = create({ onlyIfChanged: true, valueEncoding: 'json' }) + await db.ready() + await db.put('key', { a: 1 }) + t.is(db.feed.length, 2) + await db.put('key', { a: 1 }) + t.is(db.feed.length, 2) + } +}) + +test('onlyIfChanged put after del', async function (t) { + const db = create({ onlyIfChanged: true }) + await db.ready() + await db.put('key', 'value') + await db.del('key') + await db.put('key', 'value') + t.is(db.feed.length, 4) +}) From 7acd58f5c0065b7c47cb130f2816f4f0fb5275b2 Mon Sep 17 00:00:00 2001 From: rafapaezbas Date: Tue, 16 May 2023 11:20:36 +0200 Subject: [PATCH 2/2] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26f530e9..a74818a2 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Make a new Hyperbee instance. `core` should be a [Hypercore](https://github.com/ { keyEncoding: 'binary', // "binary" (default), "utf-8", "ascii", "json", or an abstract-encoding valueEncoding: 'binary' // Same options as keyEncoding like "json", etc - onlyIfChanged: true // put or delete a value only if it means a change in the db + onlyIfChanged: true // put a value only if it means a change in the db } ```