@@ -11,6 +11,8 @@ const debug = require('debug')('jitdb')
11
11
const {
12
12
saveTypedArrayFile,
13
13
loadTypedArrayFile,
14
+ savePrefixMapFile,
15
+ loadPrefixMapFile,
14
16
saveBitsetFile,
15
17
loadBitsetFile,
16
18
safeFilename,
@@ -113,6 +115,17 @@ module.exports = function (log, indexesPath) {
113
115
filepath : path . join ( indexesPath , file ) ,
114
116
}
115
117
cb ( )
118
+ } else if ( file . endsWith ( '.32prefixmap' ) ) {
119
+ // Don't load it yet, just tag it `lazy`
120
+ indexes [ indexName ] = {
121
+ offset : - 1 ,
122
+ count : 0 ,
123
+ map : { } ,
124
+ lazy : true ,
125
+ prefix : 32 ,
126
+ filepath : path . join ( indexesPath , file ) ,
127
+ }
128
+ cb ( )
116
129
} else if ( file . endsWith ( '.index' ) ) {
117
130
// Don't load it yet, just tag it `lazy`
118
131
indexes [ indexName ] = {
@@ -181,6 +194,21 @@ module.exports = function (log, indexesPath) {
181
194
)
182
195
}
183
196
197
+ function savePrefixMapIndex ( name , prefixIndex , count , cb ) {
198
+ if ( prefixIndex . offset < 0 ) return
199
+ debug ( 'saving prefix map index: %s' , name )
200
+ const num = prefixIndex . prefix
201
+ const filename = path . join ( indexesPath , name + `.${ num } prefixmap` )
202
+ savePrefixMapFile (
203
+ filename ,
204
+ prefixIndex . version || 1 ,
205
+ prefixIndex . offset ,
206
+ count ,
207
+ prefixIndex . map ,
208
+ cb
209
+ )
210
+ }
211
+
184
212
function growTarrIndex ( index , Type ) {
185
213
debug ( 'growing index' )
186
214
const newArray = new Type ( index . tarr . length * 2 )
@@ -284,12 +312,32 @@ module.exports = function (log, indexesPath) {
284
312
}
285
313
}
286
314
315
+ function addToPrefixMap ( map , seq , value ) {
316
+ if ( value === 0 ) return
317
+
318
+ const arr = map [ value ] || ( map [ value ] = [ ] )
319
+ arr . push ( seq )
320
+ }
321
+
322
+ function updatePrefixMapIndex ( opData , index , buffer , seq , offset ) {
323
+ if ( seq > index . count - 1 ) {
324
+ const fieldStart = opData . seek ( buffer )
325
+ if ( ~ fieldStart ) {
326
+ const buf = bipf . slice ( buffer , fieldStart )
327
+ addToPrefixMap ( index . map , seq , buf . length ? safeReadUint32 ( buf ) : 0 )
328
+ }
329
+
330
+ index . offset = offset
331
+ index . count = seq + 1
332
+ }
333
+ }
334
+
287
335
function updatePrefixIndex ( opData , index , buffer , seq , offset ) {
288
336
if ( seq > index . count - 1 ) {
289
337
if ( seq > index . tarr . length - 1 ) growTarrIndex ( index , Uint32Array )
290
338
291
339
const fieldStart = opData . seek ( buffer )
292
- if ( fieldStart ) {
340
+ if ( ~ fieldStart ) {
293
341
const buf = bipf . slice ( buffer , fieldStart )
294
342
index . tarr [ seq ] = buf . length ? safeReadUint32 ( buf ) : 0
295
343
} else {
@@ -368,7 +416,9 @@ module.exports = function (log, indexesPath) {
368
416
updatedSequenceIndex = true
369
417
370
418
if ( indexNeedsUpdate ) {
371
- if ( op . data . prefix )
419
+ if ( op . data . prefix && op . data . useMap )
420
+ updatePrefixMapIndex ( op . data , index , buffer , seq , offset )
421
+ else if ( op . data . prefix )
372
422
updatePrefixIndex ( op . data , index , buffer , seq , offset )
373
423
else updateIndexValue ( op , index , buffer , seq )
374
424
}
@@ -389,7 +439,10 @@ module.exports = function (log, indexesPath) {
389
439
390
440
index . offset = indexes [ 'seq' ] . offset
391
441
if ( indexNeedsUpdate ) {
392
- if ( index . prefix ) savePrefixIndex ( op . data . indexName , index , count )
442
+ if ( index . prefix && index . map )
443
+ savePrefixMapIndex ( op . data . indexName , index , count )
444
+ else if ( index . prefix )
445
+ savePrefixIndex ( op . data . indexName , index , count )
393
446
else saveIndex ( op . data . indexName , index )
394
447
}
395
448
@@ -401,7 +454,14 @@ module.exports = function (log, indexesPath) {
401
454
function createIndexes ( opsMissingIndexes , cb ) {
402
455
const newIndexes = { }
403
456
opsMissingIndexes . forEach ( ( op ) => {
404
- if ( op . data . prefix )
457
+ if ( op . data . prefix && op . data . useMap ) {
458
+ newIndexes [ op . data . indexName ] = {
459
+ offset : 0 ,
460
+ count : 0 ,
461
+ map : { } ,
462
+ prefix : typeof op . data . prefix === 'number' ? op . data . prefix : 32 ,
463
+ }
464
+ } else if ( op . data . prefix )
405
465
newIndexes [ op . data . indexName ] = {
406
466
offset : 0 ,
407
467
count : 0 ,
@@ -443,6 +503,14 @@ module.exports = function (log, indexesPath) {
443
503
updatedSequenceIndex = true
444
504
445
505
opsMissingIndexes . forEach ( ( op ) => {
506
+ if ( op . data . prefix && op . data . useMap )
507
+ updatePrefixMapIndex (
508
+ op . data ,
509
+ newIndexes [ op . data . indexName ] ,
510
+ buffer ,
511
+ seq ,
512
+ offset
513
+ )
446
514
if ( op . data . prefix )
447
515
updatePrefixIndex (
448
516
op . data ,
@@ -473,7 +541,9 @@ module.exports = function (log, indexesPath) {
473
541
for ( var indexName in newIndexes ) {
474
542
const index = ( indexes [ indexName ] = newIndexes [ indexName ] )
475
543
index . offset = indexes [ 'seq' ] . offset
476
- if ( index . prefix ) savePrefixIndex ( indexName , index , count )
544
+ if ( index . prefix && index . map )
545
+ savePrefixMapIndex ( indexName , index , count )
546
+ else if ( index . prefix ) savePrefixIndex ( indexName , index , count )
477
547
else saveIndex ( indexName , index )
478
548
}
479
549
@@ -485,7 +555,18 @@ module.exports = function (log, indexesPath) {
485
555
function loadLazyIndex ( indexName , cb ) {
486
556
debug ( 'lazy loading %s' , indexName )
487
557
let index = indexes [ indexName ]
488
- if ( index . prefix ) {
558
+ if ( index . prefix && index . map ) {
559
+ loadPrefixMapFile ( index . filepath , ( err , data ) => {
560
+ if ( err ) return cb ( err )
561
+ const { version, offset, count, map } = data
562
+ index . version = version
563
+ index . offset = offset
564
+ index . count = count
565
+ index . map = map
566
+ index . lazy = false
567
+ cb ( )
568
+ } )
569
+ } else if ( index . prefix ) {
489
570
loadTypedArrayFile ( index . filepath , Uint32Array , ( err , data ) => {
490
571
if ( err ) return cb ( err )
491
572
const { version, offset, count, tarr } = data
@@ -576,16 +657,27 @@ module.exports = function (log, indexesPath) {
576
657
function matchAgainstPrefix ( op , prefixIndex , cb ) {
577
658
const target = op . data . value
578
659
const targetPrefix = target ? safeReadUint32 ( target ) : 0
579
- const count = prefixIndex . count
580
- const tarr = prefixIndex . tarr
581
660
const bitset = new TypedFastBitSet ( )
582
661
const done = multicb ( { pluck : 1 } )
583
- for ( let seq = 0 ; seq < count ; ++ seq ) {
584
- if ( tarr [ seq ] === targetPrefix ) {
585
- bitset . add ( seq )
586
- getRecord ( seq , done ( ) )
662
+
663
+ if ( prefixIndex . map ) {
664
+ if ( prefixIndex . map [ targetPrefix ] ) {
665
+ prefixIndex . map [ targetPrefix ] . forEach ( ( seq ) => {
666
+ bitset . add ( seq )
667
+ getRecord ( seq , done ( ) )
668
+ } )
669
+ }
670
+ } else {
671
+ const count = prefixIndex . count
672
+ const tarr = prefixIndex . tarr
673
+ for ( let seq = 0 ; seq < count ; ++ seq ) {
674
+ if ( tarr [ seq ] === targetPrefix ) {
675
+ bitset . add ( seq )
676
+ getRecord ( seq , done ( ) )
677
+ }
587
678
}
588
679
}
680
+
589
681
done ( ( err , recs ) => {
590
682
// FIXME: handle error better, this cb() should support 2 args
591
683
if ( err ) return console . error ( err )
0 commit comments