TreeFlat - the simplest way to build & traverse a pre-order Tree in Rust

Overview

TreeFlat is the simplest way to build & traverse a pre-order Tree for Rust.

Alpha-relase!

If you build a Tree in pre-order, and display in pre-order, this is the tree for you.

No extra fluff, just a simple & performant one-trick pony.

Note: The tree depends on the build order, so is not possible to re-order the tree (changing parents or levels) in a different order. So, for example, you can't add a branch later to one in the middle (only can add after the end...).

How it works

Instead of creating a Tree of Node pointers, nested enums, or nested Arena-based ids, it just stores the representation of a Tree:

. Users
├── jhon_doe
├   ├── file1.rs
├   ├── file2.rs
├── jane_doe
└────── cat.jpg

... flattened in pre-order on 3 vectors, that store the data, the level & the parent:

DATA: Users jhon_doe file1.rs file2.rs jane_doe cat.jpg
LEVEl: 0 1 2 2 1 2
PARENT: 0 0 1 1 0 4

This allows for the performance of Rust Vec, on the most common operations (critically: Push items + Iterate), and very efficient iterations of node::Node::parents/node::Node::children/node::Node::siblings, because it just traverses the flat vectors.

The iterators exploit these observations:

  • The children are at the right/up of the parent
  • The parents are at the left/down of the children
  • The siblings are all that share the same level

So this means that in the case of navigating the children of jhon_doe:

. Users					  ⇡ parents
├── jhon_doe			   Index: 1, Level: 1
					           ⇩ children start at 
							jhon_doe + 1,
							level 	 > jhon_doe
├   ├── file1.rs				: Level 2 is child!
├   ├── file2.rs				: Level 2 is child!
├── jane_doe			        : Level 1 is below, stop!
└────── cat.jpg

With this, instead of searching a potentially large array, it jumps directly after the node and iterates as long the nodes are above it!.

Examples

use tree_flat::prelude::*;

let mut tree = Tree::with_capacity("Users", 6);

let mut root = tree.root_mut();

let mut child = root.push("jhon_doe");
child.push("file1.rs");
child.push("file2.rs");

let mut child = root.push("jane_doe");
child.push("cat.jpg");

//The data is backed by vectors and arena-like ids on them:
assert_eq!(
   tree.as_data(),
   ["Users", "jhon_doe", "file1.rs", "file2.rs", "jane_doe", "cat.jpg",]
);
assert_eq!(tree.as_level(), [0, 1, 2, 2, 1, 2,]);
assert_eq!(tree.as_parents(), [0, 0, 1, 1, 0, 4,]);
//Pretty print the tree
println!("{}", tree);

// Iterations is as inserted:
for f in &tree {
  dbg!(f);
}

More info at my blog .


Inspired by the talk:

“High-performance Tree Wrangling, the APL Way” -- Aaron Hsu - APL Wiki

🤝 Contributing

Contributions, issues, and feature requests are welcome!

Show your support

Give a ⭐️ if you like this project! or wanna help make my projects a reality consider donating or sponsoring my work with a subscription in https://www.buymeacoffee.com/mamcx.

📝 License

This project is dual licenced as MIT & APACHE.

You might also like...
Array helpers for Rust's Vector and String types

array_tool Array helpers for Rust. Some of the most common methods you would use on Arrays made available on Vectors. Polymorphic implementations for

Generic array types in Rust

generic-array This crate implements generic array types for Rust. Requires minumum Rust version of 1.36.0, or 1.41.0 for From[T; N] implementations

A priority queue for Rust with efficient change function.

PriorityQueue This crate implements a Priority Queue with a function to change the priority of an object. Priority and items are stored in an IndexMap

Roaring bitmap implementation for Rust

RoaringBitmap This is not yet production ready. The API should be mostly complete now. This is a Rust port of the Roaring bitmap data structure, initi

Rust Persistent Data Structures

Rust Persistent Data Structures Rust Persistent Data Structures provides fully persistent data structures with structural sharing. Setup To use rpds a

Rust crate to extend io::Read & io::Write types with progress callbacks

progress-streams Rust crate to provide progress callbacks for types which implement io::Read or io::Write. Examples Reader extern crate progress_strea

Parameterized routing for generic resources in Rust

Usher Usher provides an easy way to construct parameterized routing trees in Rust. The nodes of these trees is naturally generic, allowing Usher to le

RiteLinked - LinkedHashMap & LinkedHashSet in Rust

RiteLinked -- HashMap-like containers that hold their key-value pairs in a user controllable order RiteLinked provides more up to date versions of Lin

A proof of concept implementation of cyclic data structures in stable, safe, Rust.

A proof of concept implementation of cyclic data structures in stable, safe, Rust. This demonstrates the combined power of the static-rc crate and the

Comments
  • Benchmark against a standard approach

    Benchmark against a standard approach

    I'm exploring options around custom types for collections - so arenas are out of my wheelhouse.

    I find it difficult to get a sense of the performance of this vs what you might do using Rust std collections.

    Without that information it is tough to justify investing time into implementing something that may yield insufficient benefit?

    opened by taqtiqa-mark 4
  • Generalize to accept given collection types?

    Generalize to accept given collection types?

    Thanks you for making this available. Would it make sense be possible to generalize this to allow some other collection? Say some newtype specialization of Vec or Hash*

    opened by taqtiqa-mark 4
  • low benchmark scores

    low benchmark scores

    from looking at your benchmark scores, they seem really low (by a factor of 10-100x) for reading/writing contiguous memory, even if your doing some other stuff too...did you remember to benchmark with optimizations enabled? you never mentioned the commands you used in the blog entry so I couldn't tell.

    opened by programmerjake 2
Owner
Mario Montoya
Mario Montoya
Broot - A new way to see and navigate directory trees

Broot A better way to navigate directories Installation Instructions Get an overview of a directory, even a big one br -s Notice the unlisted? That's

Canop 8k Jan 8, 2023
Ternary search tree collection in rust

tst Ternary search tree collection in rust with similar API to std::collections as it possible. Ternary search tree is a type of trie (sometimes calle

Alexey Pervushin 20 Dec 7, 2022
K-dimensional tree in Rust for fast geospatial indexing and lookup

kdtree K-dimensional tree in Rust for fast geospatial indexing and nearest neighbors lookup Crate Documentation Usage Benchmark License Usage Add kdtr

Rui Hu 152 Jan 2, 2023
A tree structure in Rust optimized for looking up domain names, with wildcard support

domain-lookup-tree Overview DomainLookupTree is a data structure which provides efficient domain name lookup matching with support for wildcard entrie

null 18 Nov 28, 2022
Recursive & Iterative Binary Search Tree Implementations within Rust

bst-rs Recursive & Iterative Binary Search Tree Implementations within Rust Table of Contents Personal Goals About Quick Start License Contributing In

Hamothy 6 Oct 1, 2022
Bw-Tree for Rust

Bw-Tree for Rust This is a work-in-progress implementation of Bw-Trees for Rust. Nothing works, this is mostly for my own education right now. Design

Pekka Enberg 11 May 25, 2023
Redis Tree(Ploytree) Structure Module

RedisTree is a Redis module that implements Polytree as a native data type. It allows creating,locating,pushing and detaching tree from Redi

Bonsai 63 Dec 25, 2022
B-Tree map for pub/sub services

submap B-tree map for pub/sub services. Create a new subscription map let mut smap: SubMap<Client> = SubMap::new(); where "Client" is a pub/sub client

Altertech 6 Sep 21, 2022
A prefix tree (trie) is a data structure that allows you to store an associative array whose keys are strings

RadixTrie A prefix tree (trie) is a data structure that allows you to store an associative array whose keys are strings. It is a root tree, each edge

null 2 Jan 28, 2022
Rust-algorithm-club - Learn algorithms and data structures with Rust

Rust Algorithm Club ?? ?? This repo is under construction. Most materials are written in Chinese. Check it out here if you are able to read Chinese. W

Weihang Lo 360 Dec 28, 2022