{"id":15010266,"url":"https://github.com/clojure/core.rrb-vector","last_synced_at":"2025-04-07T23:11:03.548Z","repository":{"id":7715698,"uuid":"9081126","full_name":"clojure/core.rrb-vector","owner":"clojure","description":"RRB-Trees in Clojure","archived":false,"fork":false,"pushed_at":"2024-07-15T17:57:03.000Z","size":1641,"stargazers_count":197,"open_issues_count":0,"forks_count":22,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-03-31T22:20:03.423Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clojure.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-03-28T16:22:26.000Z","updated_at":"2025-03-09T14:17:54.000Z","dependencies_parsed_at":"2022-09-02T19:40:24.050Z","dependency_job_id":"326745f2-ec0a-4f95-9d36-09dd986e16b2","html_url":"https://github.com/clojure/core.rrb-vector","commit_stats":{"total_commits":272,"total_committers":11,"mean_commits":"24.727272727272727","dds":0.5294117647058824,"last_synced_commit":"88c2f814b47c0bbc4092dad82be2ec783ed2961f"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fcore.rrb-vector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fcore.rrb-vector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fcore.rrb-vector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fcore.rrb-vector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clojure","download_url":"https://codeload.github.com/clojure/core.rrb-vector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247744335,"owners_count":20988783,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T19:33:15.901Z","updated_at":"2025-04-07T23:11:03.525Z","avatar_url":"https://github.com/clojure.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# core.rrb-vector\n\nWhy would anyone want to use this library?  The two primary answers\nare:\n\n+ You want faster concatenation of vectors, which core.rrb-vector's\n  `catvec` function provides for both Clojure and ClojureScript.\n+ You use vectors of Java primitive types like long, double, etc.,\n  returned by Clojure's `vector-of` function, e.g. to reduce memory\n  usage to about 1/3 of the memory required by vectors of arbitrary\n  objects, and\n  + You want the speed enabled by using the transient versions of such\n    vectors.  Clojure does not implement transients for primitive\n    vectors created via `vector-of` -- core.rrb-vector does.\n\nVectors are one of the most commonly used data structures within\nClojure.  Likely you already know that creating a vector equal to `v`\nplus a new element `e` appended to the end using the expression `(conj\nv e)` has a run time that is \"effectively constant\", i.e. it takes\nO(log N) time in the size N of `v`, where the base of the logarithm is\n32, so it is a constant at most 4 for all vector sizes up to a\nmillion, and at most 7 for all vector sizes that Clojure supports.\n\nThe fastest way to concatenate two vectors `v1` and `v2` into a single\nnew vector is using an expression like `(into v1 v2)`.  This is\nimplemented by repeatedly appending a single element from the second\nvector to the first, so it takes linear time in the size of `v2`\n(multiplied by the effectively constant time mentioned above).\n\nAside: There might be another expression that has a better _constant\nfactor_ for its run time than `(into v1 v2)` does, and is thus faster.\nHowever, any other such expression will still take at least linear\ntime in the size of the second vector.\n\nThe core.rrb-vector library uses a tree structure similar to the one\nthat Clojure uses internally for vectors, but generalizes it in such a\nway that producing a new tree that represents the concatenation of two\ninput vectors using the `catvec` function can be done in O(log N)\ntime, where N is the size of the result.\n\nYou can give `catvec` vectors created in all of the ways you already\nnormally do, and while it will return a new type of object, this new\ntype behaves in all of the ways you expect a Clojure vector to behave.\nThis new type of vector is indistinguishable from a normal Clojure\nvector unless you examine the value of `(type v)` or `(class v)`.  In\nparticular, `(vector? v)` is true for this new type, you can call all\nof the usual sequence-based functions on it to examine or process its\nelements, you can call `conj` on it, `nth`, etc.\n\nThus if you have a program where frequently concatenating large\nvectors to produce new vectors is useful, core.rrb-vector may help you\nwrite a much faster program in a more natural way.\n\nThis library is an implementation of the confluently persistent vector\ndata structure introduced in the paper \"RRB-Trees: Efficient Immutable\nVectors\", EPFL-REPORT-169879, September, 2011, by Phil Bagwell and\nTiark Rompf.\n\nRRB-Trees build upon Clojure's internal `PersistentVector` class used\nto implement its built in vectors, adding logarithmic time\nconcatenation and slicing (i.e. create sub-vectors from input\nvectors).  ClojureScript is supported with the same API, except for\nthe absence of the `vector-of` function.\n\nThe main functions provided are `clojure.core.rrb-vector/catvec`,\nperforming vector concatenation, and `clojure.core.rrb-vector/subvec`,\nwhich produces a new vector containing the appropriate subrange of the\ninput vector (in contrast to `clojure.core/subvec`, which returns a\nview on the input vector).\n\nLike Clojure vectors, core.rrb-vector vectors can store arbitrary\nvalues, or using `vector-of` you can create vectors restricted to one\nprimitive type, e.g. long, double, etc.  The core.rrb-vector\nimplementation provides seamless interoperability with the built in\nClojure vectors of class `clojure.lang.PersistentVector`,\n`clojure.core.Vec` (vectors of primitive values) and\n`clojure.lang.APersistentVector$SubVector` instances:\n`clojure.core.rrb-vector/catvec` and `clojure.core.rrb-vector/subvec`\nconvert their inputs to `clojure.core.rrb_vector.rrbt.Vector`\ninstances whenever necessary (this is a very fast constant time\noperation for PersistentVector and primitive vectors; for SubVector it\nis O(log N), where N is the size of the underlying vector).\n\n`clojure.core.rrb-vector` also provides its own versions of `vector`,\n`vector-of`, and `vec` that always produce\n`clojure.core.rrb_vector.rrbt.Vector` instances.  Note that\n`vector-of` accepts `:object` as one of the possible type arguments,\nin addition to keywords naming primitive types.\n\n\n## Usage\n\ncore.rrb-vector exports one public namespace:\n\n    (require '[clojure.core.rrb-vector :as fv])\n\nNote that the ClojureScript version uses the same namespace name (it\n*does not* use the alternative `cljs.*` prefix!). This is because the\nAPI is precisely the same (except `clojure.core.rrb-vector/vector-of`\nonly makes sense on the JVM and is therefore not available in\nClojureScript).\n\nThe docstring attached to the namespace provides an overview of the\navailable functionality (as found at the top of this README):\n\n    (doc clojure.core.rrb-vector)\n\nThe new functionality is accessible through two functions:\n`clojure.core.rrb-vector/subvec`, which provides logarithmic-time\nnon-view slicing (in contrast to `clojure.core/subvec`, which is a\nconstant-time operation producing view vectors that prevent the\nunderlying vector from becoming eligible for garbage collection), and\n`clojure.core.rrb-vector/catvec`, which provides logarithmic-time\nconcatenation. Crucially, these can be applied to regular\nClojure(Script) vectors.\n\n    (doc fv/subvec)\n    (doc fv/catvec)\n\n    ;; apply catvec and subvec to regular Clojure(Script) vectors\n    (fv/catvec (vec (range 1234)) (vec (range 8765)))\n    (fv/subvec (vec (range 1024)) 123 456)\n\nAdditionally, several functions for constructing RRB vectors are\nprovided. There is rarely any reason to use them, since, as mentioned\nabove, the interesting functions exported by core.rrb-vector work with\nregular vectors. Note that `clojure.core.rrb-vector/vec`, in contrast\nto `clojure.core/vec`, reuses the internal tree of its input if it\nalready is a vector (of any type) and does not alias short arrays.\nWhen passed a non-vector argument, it returns an RRB vector.\n\n    (doc fv/vector)\n    (doc fv/vector-of)\n    (doc fv/vec)\n\nThe debug namespace bundled with core.rrb-vector provides several\nutilities used by the test suite, as well as a function for\nvisualizing the internal structure of vectors that works with regular\nClojure(Script) vectors and RRB vectors.\n\n    ;; for peeking under the hood\n    (require '[clojure.core.rrb-vector.debug :as dv])\n    (dv/dbg-vec (fv/catvec (vec (range 1234)) (vec (range 8765))))\n\n\n## Releases and dependency information\n\ncore.rrb-vector requires Clojure \u003e= 1.5.0. View vectors created by\n`clojure.core/subvec` are correctly handled for Clojure \u003e= 1.6.0. The\nClojureScript version is regularly tested against the most recent\nClojureScript release.\n\ncore.rrb-vector releases are available from Maven Central. Development\nsnapshots are available from the Sonatype OSS repository.\n\n* [Released versions](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.clojure%22%20AND%20a%3A%22core.rrb-vector%22)\n* [Development snapshots](https://oss.sonatype.org/index.html#nexus-search;gav~org.clojure~core.rrb-vector~~~)\n* [Change log](CHANGES.md) of changes made in this library.\n* Some [benchmark results](doc/benchmarks/benchmarks.md) comparing the run time of core.rrb-vector's JVM implementation against other vector/list implementations on the JVM.\n\nFollow the first link above to discover the current release number.\n\n[CLI/`deps.edn`](https://clojure.org/reference/deps_and_cli) dependency information:\n```clojure\norg.clojure/core.rrb-vector {:mvn/version \"${version}\"}\n```\n\n[Leiningen](http://leiningen.org/) dependency information:\n\n    [org.clojure/core.rrb-vector \"${version}\"]\n\n[Maven](http://maven.apache.org/) dependency information:\n\n    \u003cdependency\u003e\n      \u003cgroupId\u003eorg.clojure\u003c/groupId\u003e\n      \u003cartifactId\u003ecore.rrb-vector\u003c/artifactId\u003e\n      \u003cversion\u003e${version}\u003c/version\u003e\n    \u003c/dependency\u003e\n\n[Gradle](http://www.gradle.org/) dependency information:\n\n    compile \"org.clojure:core.rrb-vector:${version}\"\n\n\n## TODO\n\n 1. more tests;\n\n 2. performance: general perf tuning, more efficient `catvec`\n    implementation (to replace current seq-ops-based impl).\n\n\n## Developer information\n\ncore.rrb-vector is being developed as a Clojure Contrib project, see\nthe\n[What is Clojure Contrib](https://clojure.org/dev/contrib_libs)\npage for details. Patches will only be accepted from developers who\nhave signed the Clojure Contributor Agreement.\n\n* [GitHub project](https://github.com/clojure/core.rrb-vector)\n* [Bug Tracker](https://clojure.atlassian.net/browse/CRRBV)\n* [Continuous Integration](https://github.com/clojure/core.rrb-vector/actions/workflows/test.yml)\n\n\n### Useful Maven commands\n\nTo run Clojure and ClojureScript tests:\n```bash\n$ mvn -DCLOJURE_VERSION=1.10.1 -Dclojure.version=1.10.1 clean test\n```\n\nClojure versions as old as 1.5.1 can be tested with such a command,\nbut the ClojureScript tests only work when using Clojure 1.8.0 or\nlater.\n\nTo run tests and, if successful, create a JAR file in the targets\ndirectory:\n```bash\n$ mvn -DCLOJURE_VERSION=1.10.1 -Dclojure.version=1.10.1 clean package\n```\n\nPrerequisites: Only Java and Maven need to be installed.  Maven will\ndownload whatever versions of Clojure are needed for the command you\nuse.  Both Clojure and ClojureScript tests are run with the commands\ngiven here.  They use the Nashorn JavaScript run time environment\nincluded with Java -- no other JavaScript run time is needed.\n\n\n### Useful clj CLI commands\n\nTo run relatively short Clojure tests, but no ClojureScript tests:\n```bash\n$ ./script/jdo test\n```\n\nTo run relatively short ClojureScript tests, but no Clojure tests:\n```bash\n$ ./script/sdo test\n```\n\nWarning: Currently the command above for running ClojureScript tests\ndoes _not_ show warnings from the ClojureScript compiler.  I have seen\nsome ClojureScript compiler warnings appear when running the Maven\ncommand above, and the Leiningen command given below for running\nClojureScript tests, that unfortunately do not appear using\n`./script/sdo test`.  Suggestions welcome on how to make that command\nalso show similar warnings.\n\nReplace `test` in the commands above with one of the following for\nother useful things:\n\n* `sock` (or no argument at all) - start a REPL, and listen for a\n  socket REPL connection on TCP port 50505\n* `long` - run a longer set of tests\n* `coll` - run generative tests from\n  [`collection-check`](https://github.com/ztellman/collection-check)\n  library\n* `east` - run Eastwood lint tool (clj version only, not cljs)\n\n\n### Useful Leiningen commands\n\nTo run Clojure tests, but no ClojureScript tests:\n```bash\n$ lein with-profile +1.10 test\n```\nYou can test with Clojure versions 1.5 through 1.10 by specifying that\nversion number after the `+`.\n\nPrerequisites: Only Java and Leiningen.  Leiningen will download\nwhatever versions of Clojure and other libraries are needed.\n\nTo run ClojureScript tests with Node.js and SpiderMonkey JavaScript\nruntimes, but no Clojure tests:\n```bash\n$ lein with-profile +cljs cljsbuild test\n```\nAdd `node` or `spidermonkey` as a separate argument after `test` to\nrestrict the JavaScript runtime used to only the one you specify.  You\nmay need to adjust the command names in the `:test-commands` section\nof the `project.clj` file if the command for running those JavaScript\nruntimes have a different name on your system than what is used there.\n\nPrerequisites: Java, Leiningen, and either or both of Node.js and\nSpiderMonkey JavaScript run time environments.\n\nTo run normal Clojure tests, plus the\n[`collection-check`](https://github.com/ztellman/collection-check)\ntests, but no ClojureScript tests:\n```bash\n$ lein with-profile +coll,+1.7 test\n```\nThe `collection-check` tests require Clojure 1.7.0 or later, I believe\nbecause collection-check and/or its dependencies require that.\n\nThere is no existing command configured to run `collection-check`\ntests with ClojureScript.\n\nTo start a REPL from Leiningen with Clojure versions 1.6.0 and older,\nyou must use Leiningen 2.8.0 (likely some other versions work, too).\n\n\n### Installing other software you will need\n\nFor all of the development commands you must have Java installed.\nThis includes the ClojureScript compile and test commands, since the\nClojureScript compiler is at least partially written in the Java\nversion of Clojure.\n\n\n#### Java\n\nInstall one or more of the pre-built binaries from\n[AdoptOpenJDK](https://adoptopenjdk.net), or several other providers\nof Java binaries.\n\nAdditional methods:\n* Ubuntu 18.04 Linux: `sudo apt-get install default-jre`\n\n\n#### Maven\n\nFor any `mvn` command you must install\n[Maven](https://maven.apache.org).\n\n* Ubuntu 18.04 Linux: `sudo apt-get install maven`\n* macOS\n  * plus Homebrew: `brew install maven`\n  * plus MacPorts: `sudo port install maven3`, then either use the\n    command `mvn3`, or to use `mvn` also run the command `sudo port\n    select --set maven maven3`.\n\n\n#### Leiningen\n\nAn install script and instructions are available on the\n[Leiningen](https://leiningen.org) site.\n\n\n#### Node.js JavaScript run time environment\n\nInstallation instructions for many different versions of Node.js are\navailable on the [Node.js web site](https://nodejs.org).  You can also\ninstall it using the commands below.\n\n* Ubuntu 18.04 Linux: `sudo apt-get install nodejs`\n* macOS\n  * plus Homebrew: `brew install node`\n  * plus MacPorts: `sudo port install nodejs10`.  You can see other\n    versions available via the command `port list | grep nodejs`.\n\n\n#### SpiderMonkey JavaScript run time environment\n\nInstallation instructions for many different versions of SpiderMonkey\nare available on the [SpiderMonkey web\nsite](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey).\nYou may also install it using the commands below.\n\n* Ubuntu 18.04 Linux: `sudo apt-get install libmozjs-52-dev`\n* macOS\n  * plus Homebrew: As of 2019-Sep-24, `brew install spidermonkey`\n    installs version 1.8.5 of SpiderMonkey, which according to the\n    Wikipedia page on SpiderMonkey was first released in 2011, with at\n    least one release per year after that.  The ClojureScript tests\n    fail to run using this version of SpiderMonkey.  It seems worth\n    avoiding this version of SpiderMonkey for the purposes of testing\n    `core.rrb-vector`.\n  * plus MacPorts: `sudo port install mozjs52`\n\n\n## Clojure(Script) code reuse\n\ncore.rrb-vector's vectors support the same basic functionality regular\nClojure's vectors do (with the omissions listed above). Where\npossible, this is achieved by reusing code from Clojure's gvec and\nClojureScript's PersistentVector implementations. The Clojure(Script)\nsource files containing the relevant code carry the following\ncopyright notice:\n\n    Copyright (c) Rich Hickey. All rights reserved.\n    The use and distribution terms for this software are covered by the\n    Eclipse Public License 1.0 (https://opensource.org/license/epl-1-0/)\n    which can be found in the file epl-v10.html at the root of this distribution.\n    By using this software in any fashion, you are agreeing to be bound by\n      the terms of this license.\n    You must not remove this notice, or any other, from this software.\n\n\n## Licence\n\nCopyright © Michał Marczyk, Andy Fingerhut, Rich Hickey and contributors\n\nDistributed under the\n[Eclipse Public License 1.0](https://opensource.org/license/epl-1-0/),\nthe same as Clojure. The licence text can be found in the\n`epl-v10.html` file at the root of this distribution.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure%2Fcore.rrb-vector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclojure%2Fcore.rrb-vector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure%2Fcore.rrb-vector/lists"}