@@ -54,6 +54,52 @@ class RoaringBitmap {
5454 }
5555 this . consumed_len_bytes = pspecial - i ;
5656 return this ;
57+ } else if ( u8array [ i ] > 0xe0 ) {
58+ // Special representation of tiny sets that are runs
59+ const lspecial = u8array [ i ] & 0x0f ;
60+ this . keysAndCardinalities = new Uint8Array ( lspecial * 4 ) ;
61+ i += 1 ;
62+ const key = u8array [ i + 2 ] | ( u8array [ i + 3 ] << 8 ) ;
63+ const value = u8array [ i ] | ( u8array [ i + 1 ] << 8 ) ;
64+ const container = new RoaringBitmapRun ( 1 , new Uint8Array ( 4 ) ) ;
65+ container . array [ 0 ] = value & 0xFF ;
66+ container . array [ 1 ] = ( value >> 8 ) & 0xFF ;
67+ container . array [ 2 ] = lspecial - 1 ;
68+ this . containers . push ( container ) ;
69+ this . keysAndCardinalities [ 0 ] = key & 0xFF ;
70+ this . keysAndCardinalities [ 1 ] = ( key >> 8 ) & 0xFF ;
71+ this . keysAndCardinalities [ 2 ] = lspecial - 1 ;
72+ this . consumed_len_bytes = 5 ;
73+ return this ;
74+ } else if ( u8array [ i ] > 0xd0 ) {
75+ // Special representation of tiny sets that are close together
76+ const lspecial = u8array [ i ] & 0x0f ;
77+ this . keysAndCardinalities = new Uint8Array ( lspecial * 4 ) ;
78+ let pspecial = i + 1 ;
79+ let key = u8array [ pspecial + 2 ] | ( u8array [ pspecial + 3 ] << 8 ) ;
80+ let value = u8array [ pspecial ] | ( u8array [ pspecial + 1 ] << 8 ) ;
81+ let entry = ( key << 16 ) | value ;
82+ let container ;
83+ container = new RoaringBitmapArray ( 1 , new Uint8Array ( 4 ) ) ;
84+ container . array [ 0 ] = value & 0xFF ;
85+ container . array [ 1 ] = ( value >> 8 ) & 0xFF ;
86+ this . containers . push ( container ) ;
87+ this . keysAndCardinalities [ 0 ] = key ;
88+ this . keysAndCardinalities [ 1 ] = key >> 8 ;
89+ pspecial += 4 ;
90+ for ( let ispecial = 1 ; ispecial < lspecial ; ispecial += 1 ) {
91+ entry += u8array [ pspecial ] ;
92+ value = entry & 0xffff ;
93+ key = entry >> 16 ;
94+ container = this . addToArrayAt ( key ) ;
95+ const cardinalityOld = container . cardinality ;
96+ container . array [ cardinalityOld * 2 ] = value & 0xFF ;
97+ container . array [ ( cardinalityOld * 2 ) + 1 ] = ( value >> 8 ) & 0xFF ;
98+ container . cardinality = cardinalityOld + 1 ;
99+ pspecial += 1 ;
100+ }
101+ this . consumed_len_bytes = pspecial - i ;
102+ return this ;
57103 } else if ( u8array [ i ] < 0x3a ) {
58104 // Special representation of tiny sets with arbitrary 32-bit integers
59105 const lspecial = u8array [ i ] ;
@@ -2282,7 +2328,7 @@ function loadDatabase(hooks) {
22822328 */
22832329 class InlineNeighborsTree {
22842330 /**
2285- * @param {Uint8Array<ArrayBuffer> } encoded
2331+ * @param {Uint8Array } encoded
22862332 * @param {number } start
22872333 */
22882334 constructor (
@@ -2301,7 +2347,8 @@ function loadDatabase(hooks) {
23012347 const has_branches = ( encoded [ i ] & 0x04 ) !== 0 ;
23022348 /** @type {boolean } */
23032349 const is_suffixes_only = ( encoded [ i ] & 0x01 ) !== 0 ;
2304- let leaves_count = ( ( encoded [ i ] >> 4 ) & 0x0f ) + 1 ;
2350+ let leaves_count = ( ( encoded [ i ] >> 4 ) & 0x07 ) + 1 ;
2351+ let leaves_is_run = ( encoded [ i ] >> 7 ) !== 0 ;
23052352 i += 1 ;
23062353 let branch_count = 0 ;
23072354 if ( has_branches ) {
@@ -2311,8 +2358,10 @@ function loadDatabase(hooks) {
23112358 const dlen = encoded [ i ] & 0x3f ;
23122359 if ( ( encoded [ i ] & 0x80 ) !== 0 ) {
23132360 leaves_count = 0 ;
2361+ leaves_is_run = false ;
23142362 }
23152363 i += 1 ;
2364+ /** @type {Uint8Array } */
23162365 let data = EMPTY_UINT8 ;
23172366 if ( ! is_suffixes_only && dlen !== 0 ) {
23182367 data = encoded . subarray ( i , i + dlen ) ;
@@ -2324,8 +2373,10 @@ function loadDatabase(hooks) {
23242373 const branch_nodes = [ ] ;
23252374 for ( let j = 0 ; j < branch_count ; j += 1 ) {
23262375 const branch_dlen = encoded [ i ] & 0x0f ;
2327- const branch_leaves_count = ( ( encoded [ i ] >> 4 ) & 0x0f ) + 1 ;
2376+ const branch_leaves_count = ( ( encoded [ i ] >> 4 ) & 0x07 ) + 1 ;
2377+ const branch_leaves_is_run = ( encoded [ i ] >> 7 ) !== 0 ;
23282378 i += 1 ;
2379+ /** @type {Uint8Array } */
23292380 let branch_data = EMPTY_UINT8 ;
23302381 if ( ! is_suffixes_only && branch_dlen !== 0 ) {
23312382 branch_data = encoded . subarray ( i , i + branch_dlen ) ;
@@ -2338,13 +2389,28 @@ function loadDatabase(hooks) {
23382389 ( branch_leaves_count - 1 ) & 0xff ,
23392390 ( ( branch_leaves_count - 1 ) >> 8 ) & 0xff ,
23402391 ) ;
2341- branch_leaves . containers = [
2342- new RoaringBitmapArray (
2343- branch_leaves_count ,
2344- encoded . subarray ( i , i + ( branch_leaves_count * 2 ) ) ,
2345- ) ,
2346- ] ;
2347- i += branch_leaves_count * 2 ;
2392+ if ( branch_leaves_is_run ) {
2393+ branch_leaves . containers = [
2394+ new RoaringBitmapRun (
2395+ 1 ,
2396+ Uint8Array . of (
2397+ encoded [ i ] ,
2398+ encoded [ i + 1 ] ,
2399+ branch_leaves_count - 1 ,
2400+ 0 ,
2401+ ) ,
2402+ ) ,
2403+ ] ;
2404+ i += 2 ;
2405+ } else {
2406+ branch_leaves . containers = [
2407+ new RoaringBitmapArray (
2408+ branch_leaves_count ,
2409+ encoded . subarray ( i , i + ( branch_leaves_count * 2 ) ) ,
2410+ ) ,
2411+ ] ;
2412+ i += branch_leaves_count * 2 ;
2413+ }
23482414 branch_nodes . push ( Promise . resolve (
23492415 is_suffixes_only ?
23502416 new SuffixSearchTree (
@@ -2379,13 +2445,28 @@ function loadDatabase(hooks) {
23792445 ( leaves_count - 1 ) & 0xff ,
23802446 ( ( leaves_count - 1 ) >> 8 ) & 0xff ,
23812447 ) ;
2382- leaves . containers = [
2383- new RoaringBitmapArray (
2384- leaves_count ,
2385- encoded . subarray ( i , i + ( leaves_count * 2 ) ) ,
2386- ) ,
2387- ] ;
2388- i += leaves_count * 2 ;
2448+ if ( leaves_is_run ) {
2449+ leaves . containers = [
2450+ new RoaringBitmapRun (
2451+ 1 ,
2452+ Uint8Array . of (
2453+ encoded [ i ] ,
2454+ encoded [ i + 1 ] ,
2455+ leaves_count - 1 ,
2456+ 0 ,
2457+ ) ,
2458+ ) ,
2459+ ] ;
2460+ i += 2 ;
2461+ } else {
2462+ leaves . containers = [
2463+ new RoaringBitmapArray (
2464+ leaves_count ,
2465+ encoded . subarray ( i , i + ( leaves_count * 2 ) ) ,
2466+ ) ,
2467+ ] ;
2468+ i += leaves_count * 2 ;
2469+ }
23892470 }
23902471 return is_suffixes_only ?
23912472 new SuffixSearchTree (
@@ -2654,7 +2735,7 @@ function loadDatabase(hooks) {
26542735
26552736 /**
26562737 * @param {string } inputBase64
2657- * @returns {[Uint8Array<ArrayBuffer> , SearchTree] }
2738+ * @returns {[Uint8Array, SearchTree] }
26582739 */
26592740 function makeSearchTreeFromBase64 ( inputBase64 ) {
26602741 const input = makeUint8ArrayFromBase64 ( inputBase64 ) ;
@@ -2972,7 +3053,10 @@ function loadDatabase(hooks) {
29723053 // node with packed leaves and common 16bit prefix
29733054 const leaves_count = no_leaves_flag !== 0 ?
29743055 0 :
2975- ( ( compression_tag >> 4 ) & 0x0f ) + 1 ;
3056+ ( ( compression_tag >> 4 ) & 0x07 ) + 1 ;
3057+ const leaves_is_run = no_leaves_flag !== 0 ?
3058+ false :
3059+ ( ( compression_tag >> 4 ) & 0x08 ) !== 0 ;
29763060 const branch_count = is_long_compressed ?
29773061 ( ( compression_tag >> 8 ) & 0xff ) + 1 :
29783062 0 ;
@@ -2994,16 +3078,25 @@ function loadDatabase(hooks) {
29943078 for ( let j = 0 ; j < branch_count ; j += 1 ) {
29953079 const branch_dlen = input [ i ] & 0x0f ;
29963080 const branch_leaves_count = ( ( input [ i ] >> 4 ) & 0x0f ) + 1 ;
3081+ const branch_leaves_is_run = ( input [ i ] >> 7 ) !== 0 ;
29973082 i += 1 ;
29983083 if ( ! is_pure_suffixes_only_node ) {
29993084 i += branch_dlen ;
30003085 }
3001- i += branch_leaves_count * 2 ;
3086+ if ( branch_leaves_is_run ) {
3087+ i += 2 ;
3088+ } else {
3089+ i += branch_leaves_count * 2 ;
3090+ }
30023091 }
30033092 // branch keys
30043093 i += branch_count ;
30053094 // leaves
3006- i += leaves_count * 2 ;
3095+ if ( leaves_is_run ) {
3096+ i += 2 ;
3097+ } else {
3098+ i += leaves_count * 2 ;
3099+ }
30073100 if ( is_data_compressed ) {
30083101 const clen = (
30093102 1 + // first compression header byte
@@ -3305,7 +3398,7 @@ if (typeof window !== "undefined") {
33053398// eslint-disable-next-line max-len
33063399// polyfill https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
33073400/**
3308- * @type {function(string): Uint8Array<ArrayBuffer> } base64
3401+ * @type {function(string): Uint8Array } base64
33093402 */
33103403//@ts -expect-error
33113404const makeUint8ArrayFromBase64 = Uint8Array . fromBase64 ? Uint8Array . fromBase64 : ( string => {
@@ -3318,7 +3411,7 @@ const makeUint8ArrayFromBase64 = Uint8Array.fromBase64 ? Uint8Array.fromBase64 :
33183411 return bytes ;
33193412} ) ;
33203413/**
3321- * @type {function(string): Uint8Array<ArrayBuffer> } base64
3414+ * @type {function(string): Uint8Array } base64
33223415 */
33233416//@ts -expect-error
33243417const makeUint8ArrayFromHex = Uint8Array . fromHex ? Uint8Array . fromHex : ( string => {
0 commit comments