Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/helins/rktree.cljc
Trees where leaves are located both in time and space
https://github.com/helins/rktree.cljc
clojure data-structures ordering prioritization time
Last synced: about 1 month ago
JSON representation
Trees where leaves are located both in time and space
- Host: GitHub
- URL: https://github.com/helins/rktree.cljc
- Owner: helins
- License: mpl-2.0
- Created: 2020-05-02T09:49:19.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2021-03-25T17:57:36.000Z (almost 4 years ago)
- Last Synced: 2024-10-28T13:25:29.789Z (about 2 months ago)
- Topics: clojure, data-structures, ordering, prioritization, time
- Language: Clojure
- Size: 85 KB
- Stars: 15
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Ranked trees
[![Clojars
Project](https://img.shields.io/clojars/v/dvlopt/rktree.svg)](https://clojars.org/dvlopt/rktree)[![cljdoc badge](https://cljdoc.org/badge/dvlopt/rktree)](https://cljdoc.org/d/dvlopt/rktree)
![CircleCI](https://circleci.com/gh/helins/rktree.cljc.svg?style=shield)
Compatible with Clojurescript.
Feel free to clone this repo, the examples below located are in the
[dvlopt.rktree.example](../main/src/example/dvlopt/rktree/example.cljc)
namespace. See the "Development" section at the end of this document.## Usage
A `ranked tree` is a peculiar but interesting data structure. It is a form of
nested maps where leaves are located both in time and space. It comes in handy
for problems that needs some form of prioritization.More specifically, it is a complex of nested maps where former levels are sorted
and latter levels are unsorted.Following this definition, the following qualifies as a `ranked tree`:
```clojure
(def my-tree
(sorted-map 0 (sorted-map 1 {:a {:b 'leaf-1}})
5 {:a {:d {:e 'leaf-2}}}))
```Each leaf has two paths, one "horizontal" and one "vertical" (borrowing
vocabulary from the litterature). We shall rather talk (respectively) about
`ranks` providing a notion of time and a `path` providing a notion of space.Thus, `'leaf-1` is said to be located at `[:a :b]` and ranked at `[0 1]`.
Similarly, `'leaf-2` is said to be located at `[:c :d :e]` and ranked at `[5]`.
We specify both the `ranks` and the `path` when we want to `get` something out
of this tree:```clojure
(require '[dvlopt.rktree :as rktree])(= 'leaf-1
(rktree/get my-tree
[0 1]
[:a :b]))
```Ranks provid prioritization, a lower rank meaning a higher priority, 0 being the
highest priority. When we `pop` the tree, we receive whatever resides at the
ranks with the highest priority. More precisely, we receive `[popped-tree ranks
unsorted-node]`:```clojure
(= (rktree/pop my-tree)[(sorted-map 5 {:a {:d {:e 'leaf-2}}})
[0 1]
{:a {:b 'leaf-1}}])
```Interestingly, as you might have noticed, different leaves can have ranks of
different length. This library handles that automagically. Remember we already
have `'leaf-1` located at `[:a :b]` and ranked at `[0 1]`. What if we `assoc`
something past those ranks?```Clojure
(def my-tree-2
(rktree/assoc my-tree
[0 1 0 0 0 5]
[:possible?]
true));; Notice that 'leaf has been re-prioritized from [0 1] to [0 1 0 0 0 0].
;; Order is actually maintained as before, but we can account for the new
;; addition above.(= 'leaf-1
(rktree/get my-tree-2
[0 1 0 0 0 0]
[:a :b]));; But notice that we can still use the original ranks!
(= 'leaf-1
(rktree/get my-tree-2
[0 1]
[:a :b]))
```We have discovered a few recognizable functions such as `assoc` and `get`. The
[API](https://cljdoc.org/d/dvlopt/rktree) provide other ones (`dissoc`,
`update`, and friends), all acting on this idea of having `ranks` and a `path`.## Serialization
Some serializers make a distinction between sorted maps and unsorted ones. For
instance, [Nippy](https://github.com/ptaoussanis/nippy) does.But Transit does not.
The user can add the following dependency along side
[Transit-clj](https://github.com/cognitect/transit-clj) or
[Transit-cljs](https://github.com/cognitect/transit-cljs):[![Clojars
Project](https://img.shields.io/clojars/v/dvlopt/rktree.transit.svg)](https://clojars.org/dvlopt/rktree.transit)This package provides a read handler and a write handler for sorted maps:
```clojure
(require '[dvlopt.rktree.transit :as rktree.transit])rktree.transit/read-handler
rktree.transit/write-handler
```## Running tests
On the JVM, using [Kaocha](https://github.com/lambdaisland/kaocha):
```bash
$ ./bin/test/jvm/run
$ ./bin/test/jvm/watch
```
On NodeJS, using [Kaocha-CLJS](https://github.com/lambdaisland/kaocha-cljs):```bash
$ ./bin/test/node/run
$ ./bin/test/node/watch
```In the browser, using [Chui](https://github.com/lambdaisland/chui):
```
$ ./bin/test/browser/compile
# Then open ./resources/chui/index.html# For testing an advanced build
$ ./bin/test/browser/advanced
```## Development
Starting in Clojure JVM mode, mentioning an additional deps alias (here, a local
setup of NREPL):
```bash
$ ./bin/dev/clojure :nrepl
```Starting in CLJS mode using Shadow-CLJS:
```bash
$ ./bin/dev/cljs
# Then open ./resources/public/index.html
```## License
Copyright © 2020 Adam Helinski
Licensed under the term of the Mozilla Public License 2.0, see LICENSE.