Skip to content

Instantly share code, notes, and snippets.

@bvibber
Created May 14, 2022 18:55
Show Gist options
  • Save bvibber/8cc9755407d4121f1c6dd2eb8a0723e0 to your computer and use it in GitHub Desktop.
Save bvibber/8cc9755407d4121f1c6dd2eb8a0723e0 to your computer and use it in GitHub Desktop.

Integer-indexed arrays:

This is an in-order binary tree, where the tree nodes directly contain the items.

The bigger an array gets, the slower lookups will get in it but they'll be fairly consistent for a given size. Iterating the tree is faster than individually looking up indexes in turn.

The array-bits is the number of "hash" bits used to traverse the tree with 16-bit integer index keys. The array-length is the highest index inserted so far plus one; when it exceeds 2^array-bits, add a layer to the tree and move the old tree into the left hand. Start traversals with the most significant bit within the hash size for proper ordering.

Note that the object exposes a string-indexed property tree too, here elided into a single property descriptor for length, which mirrors the internal 16-bit length with a JS number.

["a", "b", "c"]
obj - Array prototype
    \ array - array-bits - 2 (2^2 = 4)
         |               \ array-length - 3
         |                              \ tree - tree - string "a"
         |                                    \       \ string "b"
          \                                    \ tree - string "c"
           \                                          \ nil
            \ prop-desc - string "length"
                        \ number 3

for n is power of 2: 5 * (n + 4) bytes (plus contents)

This does allow for "holes", but the array-length should in that case be big enough to cover the maximum index, and all missing levels of the tree must be inserted. Because keys are not stored, trees cannot be elided when only one entry is present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment