Skip to content

Commit e7fb193

Browse files
authored
Merge pull request #97 from ssb-ngi-pointer/prefix-offset
Add prefixOffset option
2 parents 13e5389 + f41e4b5 commit e7fb193

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,11 @@ inverted index that allows for faster queries at the cost of extra
390390
space. Maps don't store empty values meaning they are also a good fit
391391
for sparce indexes such as vote links.
392392

393+
It is possible specifiy where in the target the prefix buffer should
394+
be constructed from using `prefixOffset`. This is useful for targets
395+
that starts with a common prefix such as % in order to increase the
396+
information amount.
397+
393398
## Low-level API
394399

395400
First some terminology: offset refers to the byte position in the log

index.js

+14-6
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,13 @@ module.exports = function (log, indexesPath) {
302302
}
303303
}
304304

305-
function safeReadUint32(buf) {
305+
function safeReadUint32(buf, prefixOffset = 0) {
306306
if (buf.length < 4) {
307307
const bigger = Buffer.alloc(4)
308308
buf.copy(bigger)
309-
return bigger.readUInt32LE(0)
309+
return bigger.readUInt32LE(prefixOffset)
310310
} else {
311-
return buf.readUInt32LE(0)
311+
return buf.readUInt32LE(prefixOffset)
312312
}
313313
}
314314

@@ -324,7 +324,11 @@ module.exports = function (log, indexesPath) {
324324
const fieldStart = opData.seek(buffer)
325325
if (~fieldStart) {
326326
const buf = bipf.slice(buffer, fieldStart)
327-
addToPrefixMap(index.map, seq, buf.length ? safeReadUint32(buf) : 0)
327+
addToPrefixMap(
328+
index.map,
329+
seq,
330+
buf.length ? safeReadUint32(buf, opData.prefixOffset) : 0
331+
)
328332
}
329333

330334
index.offset = offset
@@ -339,7 +343,9 @@ module.exports = function (log, indexesPath) {
339343
const fieldStart = opData.seek(buffer)
340344
if (~fieldStart) {
341345
const buf = bipf.slice(buffer, fieldStart)
342-
index.tarr[seq] = buf.length ? safeReadUint32(buf) : 0
346+
index.tarr[seq] = buf.length
347+
? safeReadUint32(buf, opData.prefixOffset)
348+
: 0
343349
} else {
344350
index.tarr[seq] = 0
345351
}
@@ -683,7 +689,9 @@ module.exports = function (log, indexesPath) {
683689

684690
function matchAgainstPrefix(op, prefixIndex, cb) {
685691
const target = op.data.value
686-
const targetPrefix = target ? safeReadUint32(target) : 0
692+
const targetPrefix = target
693+
? safeReadUint32(target, op.data.prefixOffset)
694+
: 0
687695
const bitset = new TypedFastBitSet()
688696
const done = multicb({ pluck: 1 })
689697

test/helpers.js

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const bipf = require('bipf')
22

3+
const bKey = Buffer.from('key')
34
const bValue = Buffer.from('value')
45
const bVote = Buffer.from('vote')
56
const bLink = Buffer.from('link')
@@ -14,6 +15,11 @@ const bPrivate = Buffer.from('private')
1415
const bChannel = Buffer.from('channel')
1516

1617
module.exports = {
18+
seekKey: function (buffer) {
19+
var p = 0 // note you pass in p!
20+
return bipf.seekKey(buffer, p, bKey)
21+
},
22+
1723
seekAuthor: function (buffer) {
1824
var p = 0 // note you pass in p!
1925
p = bipf.seekKey(buffer, p, bValue)

test/prefix.js

+36
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,39 @@ prepareAndRunTest('Prefix map equal', dir, (t, db, raf) => {
375375
})
376376
})
377377
})
378+
379+
prepareAndRunTest('Prefix offset', dir, (t, db, raf) => {
380+
const msg1 = { type: 'post', text: 'Testing!' }
381+
const msg2 = { type: 'contact', text: 'Testing!' }
382+
const msg3 = { type: 'post', text: 'Testing 2!' }
383+
384+
let state = validate.initial()
385+
state = validate.appendNew(state, null, keys, msg1, Date.now())
386+
state = validate.appendNew(state, null, keys, msg2, Date.now() + 1)
387+
state = validate.appendNew(state, null, keys, msg3, Date.now() + 2)
388+
389+
addMsg(state.queue[0].value, raf, (err, msg) => {
390+
addMsg(state.queue[1].value, raf, (err, msg) => {
391+
addMsg(state.queue[2].value, raf, (err, msg) => {
392+
const typeQuery = {
393+
type: 'EQUAL',
394+
data: {
395+
seek: helpers.seekKey,
396+
value: Buffer.from(msg.key),
397+
indexType: 'key',
398+
indexName: 'value_key_' + msg.key,
399+
useMap: true,
400+
prefix: 32,
401+
prefixOffset: 1,
402+
},
403+
}
404+
405+
db.all(typeQuery, 0, false, false, (err, results) => {
406+
t.equal(results.length, 1)
407+
t.equal(results[0].value.content.text, 'Testing 2!')
408+
t.end()
409+
})
410+
})
411+
})
412+
})
413+
})

0 commit comments

Comments
 (0)