npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rbst-lite

v2016.10.10

Published

this package will provide a javascript implementation of randomized-binary-search-tree derived from http://kukuruku.co/hub/cpp/randomized-binary-search-trees with zero npm-dependencies

Downloads

15

Readme

rbst-lite

this package will provide a javascript implementation of randomized-binary-search-tree derived from http://kukuruku.co/hub/cpp/randomized-binary-search-trees with zero npm-dependencies

travis-ci.org build-status

NPM

package-listing

documentation

api-doc

api-doc

todo

  • none

change since 4fb90e68

  • npm publish 2016.10.10
  • add api-doc
  • add testCase_rbst_default
  • fix sizeUpdate
  • none

build-status travis-ci.org build-status

build commit status

| git-branch : | master | beta | alpha| |--:|:--|:--|:--| | test-report : | test-report | test-report | test-report| | coverage : | istanbul coverage | istanbul coverage | istanbul coverage| | build-artifacts : | build-artifacts | build-artifacts | build-artifacts|

master branch

  • stable branch
  • HEAD should be tagged, npm-published package

beta branch

  • semi-stable branch
  • HEAD should be latest, npm-published package

alpha branch

  • unstable branch
  • HEAD is arbitrary
  • commit history may be rewritten

quickstart example

/*
 * rbst-lite.js
 * https://github.com/kaizhu256/node-rbst-lite
 *
 * this package will provide a javascript implementation of randomized-binary-search-tree
 * derived from http://kukuruku.co/hub/cpp/randomized-binary-search-trees
 * with zero npm-dependencies
 *
 * quickstart example:
 *     copy and paste this entire script into the browser or nodejs console and press <enter>
 */



/* istanbul instrument in package rbst-lite */
/*jslint
    bitwise: true,
    browser: true,
    maxerr: 8,
    maxlen: 96,
    node: true,
    nomen: true,
    regexp: true,
    stupid: true
*/
(function () {
    'use strict';
    var local;
    local = {};
    // globally export local
    /* istanbul ignore next */
    if (typeof global === 'object' && global) {
        global.rbst_lite = local;
    }
    /* istanbul ignore next */
    if (typeof module === 'object' && module) {
        module.exports = local;
    }
    /* istanbul ignore next */
    if (typeof window === 'object' && window) {
        window.rbst_lite = local;
    }



    // run shared js-env code - lib.rbst.js
    (function (local) {
        var compare,
            create,
            find,
            findInKeyRange,
            insert,
            insertAsRoot,
            join,
            print,
            remove,
            rotateLeft,
            rotateRight,
            sizeUpdate;

        compare = function (aa, bb) {
        /*
         * this function will compare aa vs bb and return:
         * -1 if aa < bb
         *  0 if aa === bb
         *  1 if aa > bb
         * the priority for comparing different typeof's is:
         * number < boolean < string < object < undefined
         */
            var typeof1, typeof2;
            if (aa === bb) {
                return 0;
            }
            // handle undefined case
            if (aa === undefined) {
                return 1;
            }
            if (bb === undefined) {
                return -1;
            }
            typeof1 = typeof aa;
            typeof2 = typeof bb;
            if (typeof1 === typeof2) {
                return typeof1 === 'object'
                    ? 0
                    : aa < bb
                    ? -1
                    : 1;
            }
            if (typeof1 === 'number') {
                return -1;
            }
            if (typeof2 === 'number') {
                return 1;
            }
            if (typeof1 === 'boolean') {
                return -1;
            }
            if (typeof2 === 'boolean') {
                return 1;
            }
            if (typeof1 === 'string') {
                return -1;
            }
            if (typeof2 === 'string') {
                return 1;
            }
            return 0;
        };

        create = function (key, data) {
        /*
         * this function will create a tree with the given key and data
         */
            return {
                key: key,
                data: data,
                left: null,
                right: null,
                size: 1
            };
        };

        find = function (tree, key) {
        /*
         * this function will find the node in the tree with the given key
         */
            var node, tmp;
            node = tree;
            tmp = node && compare(node.key, key);
            while (tmp) {
                node = tmp === -1
                    ? node.right
                    : node.left;
                tmp = node && compare(node.key, key);
            }
            return node;
        };

        findInKeyRange = function (tree, aa, bb, fnc) {
        /*
         * this function will iteratively call fnc on all nodes in the tree,
         * with keys in the inclusive key-range [aa, bb]
         */
            var node, sentinel, stack, tmp, traversedList;
            if (!tree) {
                return;
            }
            // find first node with key >= aa
            node = tree;
            stack = [node];
            tmp = node && compare(node.key, aa);
            while (node) {
                stack.push(node);
                node = tmp === -1
                    ? node.right
                    : node.left;
                tmp = node && compare(node.key, aa);
            }
            traversedList = stack.slice();
            // find last node with key <= bb
            sentinel = null;
            node = tree;
            tmp = compare(node.key, bb);
            while (node) {
                sentinel = node;
                node = tmp === 1
                    ? node.left
                    : node.right;
                tmp = node && compare(node.key, bb);
            }
            sentinel = node || sentinel;
            // begin traversal with first node with key >= aa
            while (stack.length) {
                node = stack.pop();
                tmp = compare(node.key, bb);
                if (compare(node.key, aa) >= 0 && compare(node.key, bb) <= 0) {
                    fnc(node);
                }
                // end traversal with last node with key <= bb
                if (node === sentinel) {
                    return;
                }
                node = node.right;
                if (traversedList.indexOf(node) < 0) {
                    while (node) {
                        stack.push(node);
                        node = node.left;
                    }
                }
            }
        };

        insert = function (tree, key, data) {
        /*
         * this function will insert a new node in the tree with the given key and data,
         * with random re-balancing
         */
            if (!tree) {
                return create(key, data);
            }
            if (Math.floor(Math.random() * 0x10000000000000) % (tree.size + 1) === 0 &&
                    typeof key !== 'object') {
                return insertAsRoot(tree, key, data);
            }
            if (compare(key, tree.key) === -1) {
                tree.left = insert(tree.left, key, data);
            } else {
                tree.right = insert(tree.right, key, data);
            }
            sizeUpdate(tree);
            return tree;
        };

        insertAsRoot = function (tree, key, data) {
        /*
         * this function will insert a new node in the tree with the given key and data,
         * and rebalance it as the root node
         */
            if (!tree) {
                return create(key, data);
            }
            if (compare(key, tree.key) === -1) {
                tree.left = insertAsRoot(tree.left, key, data);
                return rotateRight(tree);
            }
            tree.right = insertAsRoot(tree.right, key, data);
            return rotateLeft(tree);
        };

        join = function (left, right) {
        /*
         * this function will join the left and right trees after deleting their parent tree
         */
            if (!left) {
                return right;
            }
            if (!right) {
                return left;
            }
            // left is heavy, so move it up
            if (left.size > right.size) {
                left.right = join(left.right, right);
                sizeUpdate(left);
                return left;
            }
            // right is heavy, so move it up
            right.left = join(left, right.left);
            sizeUpdate(right);
            return right;
        };

        print = function (tree) {
        /*
         * this function will print the tree
         */
            var height, ii, recurse;
            recurse = function (tree, depth) {
                if (!tree) {
                    return;
                }
                recurse(tree.left, depth + '* ');
                ii += 1;
                if (depth > height) {
                    height = depth;
                }
                console.log('(' + ii + ',' + (depth.length / 2) + ',' + tree.size + ') ' +
                    depth + JSON.stringify(tree.key));
                recurse(tree.right, depth + '* ');
            };
            height = '';
            ii = -1;
            console.log('\ntree\n(ii,depth,size) key');
            recurse(tree, '');
            console.log('height = ' + height.length / 2);
        };

        remove = function (tree, key) {
        /*
         * this function will remove the node in the tree with the given key
         */
            if (!tree) {
                return tree;
            }
            if (tree.key === key) {
                return join(tree.left, tree.right);
            }
            if (compare(key, tree.key) === -1) {
                tree.left = remove(tree.left, key);
            } else {
                tree.right = remove(tree.right, key);
            }
            sizeUpdate(tree);
            return tree;
        };

        rotateLeft = function (tree) {
        /*
         * this function will rotate-left tree.right up to its parent tree's position
         */
            var right;
            right = tree.right;
            tree.right = right.left;
            sizeUpdate(tree);
            right.left = tree;
            sizeUpdate(right);
            return right;
        };

        rotateRight = function (tree) {
        /*
         * this function will rotate-right tree.left up to its parent tree's position
         */
            var left;
            left = tree.left;
            tree.left = left.right;
            sizeUpdate(tree);
            left.right = tree;
            sizeUpdate(left);
            return left;
        };

        sizeUpdate = function (tree) {
        /*
         * this function will update tree.size
         */
            tree.size = 1 +
                ((tree.left && tree.left.size) || 0) +
                ((tree.right && tree.right.size) || 0);
        };

        // init local
        local.rbstCompare = compare;
        local.rbstCreate = create;
        local.rbstFind = find;
        local.rbstFindInKeyRange = findInKeyRange;
        local.rbstInsert = insert;
        local.rbstPrint = print;
        local.rbstRemove = remove;
    }(local));



    // run browser js-env code - test
    (function (local) {
        var assert, testCase_rbst_default;

        assert = function (passed, data) {
        /*
         * this function will, if passed is falsey, throw an error with the given data
         */
            if (!passed) {
                throw new Error(JSON.stringify(data));
            }
        };

        testCase_rbst_default = function (options, onError) {
            options = options || {};
            // create tree
            options.tree = local.rbstCreate(null, null);
            [
                -1, -0.5, 0, 0, 1, 2, 3,
                false, true,
                '-1', '0', '1', 'a', 'b',
                null, undefined, {}, []
            ]
                // shuffle list
                .sort(function () {
                    return Math.floor(Math.random() * 3) - 1;
                })
                .forEach(function (key, data) {
                    // insert
                    options.tree = local.rbstInsert(options.tree, key, data);
                });
            // find
            console.log('\nfind 0');
            options.data = local.rbstFind(options.tree, 0);
            console.log(options.data);
            assert(options.data.key === 0, options.data);
            console.log('\nfind undefined');
            options.data = local.rbstFind(options.tree, 'undefined');
            console.log(options.data);
            assert(options.data === null, options.data);
            // findInKeyRange
            console.log('\nfindInKeyRange [0, Infinity]');
            options.data = [];
            local.rbstFindInKeyRange(options.tree, 0, Infinity, function (node) {
                options.data.push(node.key);
            });
            console.log(options.data);
            assert(JSON.stringify(options.data) === '[0,0,1,2,3]', options.data);
            // print
            local.rbstPrint(options.tree);
            // output:
            // options.tree
            // (ii,depth) key
            // (0,3) * * * -1
            // (1,2) * * -0.5
            // (2,5) * * * * * 0
            // (3,4) * * * * 0
            // (4,3) * * * 1
            // (5,1) * 2
            // (6,3) * * * 3
            // (7,2) * * false
            // (8,0) true
            // (9,3) * * * "-1"
            // (10,5) * * * * * "0"
            // (11,4) * * * * "1"
            // (12,2) * * "a"
            // (13,1) * "b"
            // (14,2) * * null
            // (15,3) * * * []
            // (16,4) * * * * null
            // (17,6) * * * * * * {}
            // (18,5) * * * * * undefined
            // height = 6
            // remove
            options.tree = local.rbstRemove(options.tree, true);
            // print
            local.rbstPrint(options.tree);
            // coverage-hack - assert
            try {
                assert(false);
            } catch (ignore) {
            }
            // coverage-hack - compare
            options.symbolCreate = Symbol;
            options.data = local.rbstCompare({}, options.symbolCreate());
            assert(options.data === 0, options.data);
            // coverage-hack - remove
            options.tree = local.rbstRemove();
            local.rbstFindInKeyRange(null, null, null, console.log);
            for (options.ii = 0; options.ii < 0x100; options.ii += 1) {
                // coverage-hack - insert
                if (Math.random() >= 0.5) {
                    options.tree = local.rbstInsert(
                        options.tree,
                        options.ii,
                        'options.data' + options.ii
                    );
                }
                // coverage-hack - find
                local.rbstFind(options.tree, 'options.data' + options.ii);
                local.rbstFindInKeyRange(options.tree, -Infinity, undefined, assert);
            }
            options.data = [];
            local.rbstFindInKeyRange(options.tree, 0.5, 256.5, function (node) {
                options.data.push(node);
            });
            options.data.forEach(function (node) {
                // remove
                if (Math.random() >= 0.5) {
                    options.tree = local.rbstRemove(options.tree, node.key);
                }
            });
            // print
            // local.rbstPrint(options.tree);
            onError();
        };

        // run test
        testCase_rbst_default(null, function (error) {
            // validate no error occurred
            console.assert(!error, error);
        });
    }(local));
}());

package.json

{
    "package.json": true,
    "author": "[email protected]",
    "description": "{{packageJson.description}}",
    "devDependencies": {
        "electron-lite": "kaizhu256/node-electron-lite#alpha",
        "utility2": "kaizhu256/node-utility2#alpha"
    },
    "homepage": "https://github.com/kaizhu256/node-rbst-lite",
    "keywords": [
        "binary-search-tree", "bst",
        "heap",
        "randomized-binary-search-tree", "rbst",
        "self-balancing",
        "treap"
    ],
    "license": "MIT",
    "name": "rbst-lite",
    "repository": {
        "type": "git",
        "url": "https://github.com/kaizhu256/node-rbst-lite.git"
    },
    "scripts": {
        "build-ci": "utility2 shRun shReadmeBuild",
        "start": "utility2 start index.js",
        "test": "export PORT=$(utility2 shServerPortRandom) && utility2 test test.js"
    },
    "version": "2016.10.10"
}

internal build-script

  • build.sh
# build.sh

# this shell script will run the build for this package

shBuildCiTestPre() {(set -e
# this function will run the pre-test build
    # test published-package
    (export MODE_BUILD=npmTestPublished &&
        shRunScreenCapture shNpmTestPublished) || return $?
)}

shBuildCiTestPost() {(set -e
# this function will run the post-test build
    # if running legacy-node, then return
    [ "$(node --version)" \< "v5.0" ] && return || true
    export NODE_ENV=production
)}

shBuild() {(set -e
# this function will run the main build
    # init env
    . node_modules/.bin/utility2 && shInit
    # cleanup github-gh-pages dir
    # export BUILD_GITHUB_UPLOAD_PRE_SH="rm -fr build"
    # init github-gh-pages commit-limit
    export COMMIT_LIMIT=16
    # if branch is alpha, beta, or master, then run default build
    if [ "$CI_BRANCH" = alpha ] ||
        [ "$CI_BRANCH" = beta ] ||
        [ "$CI_BRANCH" = master ]
    then
        shBuildCiDefault
    fi
)}
shBuild