Home

Awesome

Archived

NOTICE - I don't see the value in maintaining this any more as it has become a burden and I don't see any value when there is armon/libart which is more robust and proven. Also zig's std.StringHashMap() out-performs this implementation by around 2x in the benchmarks below.

If anyone sees value in this project, can convince me of it and wishes to maintain it, please open an issue and I'll be glad to un-archive and add you as a maintainer.

Features

This library provides a zig implementation of the Adaptive Radix Tree or ART. The ART operates similar to a traditional radix tree but avoids the wasted space of internal nodes by changing the node size. It makes use of 4 node sizes (8, 16, 48, 256), and can guarantee that the overhead is no more than 52 bytes per key, though in practice it is much lower. As a radix tree, it provides the following:

NOTES:

taken from armon/libart

the memory footprint described here is unverified

Usage

See src/test_art.zig

Important Notes

This library requires null terminated string slices ([:0]const u8).

Developed and tested against zig's latest master version. The zig version when this readme was updated was 0.11.0-dev.3834+d98147414.

Use with the zig package manager

// build.zig.zon
.{
    .name = "my lib",
    .version = "0.0.1",

    .dependencies = .{
        .art = .{
            .url = "https://github.com/travisstaloch/art.zig/archive/e8866a9f5b29a5b40db215e2242a8e265ccf300c.tar.gz",
            .hash = "1220d4b11d054408f1026fcdb026ef44939120e9a11a1ca2963a1c66e5adf3639ab6",
        },
    }
}
// build.zig
const art_dep = b.dependency("art", .{});
const art_mod = art_dep.module("art");
exe.addModule("art", art_mod);
// example zig app
const art = @import("art");

pub fn main() !void {
    const A = art.Art(usize);
    var a = A.init(&std.heap.page_allocator);
    _ = try a.insert("foo", 0);
}

Test

$ zig build test -Doptimize=ReleaseSafe

Run repl

$ zig run src/art.zig -lc

REPL

The repl is very simple and responds to these commands:

A representation of the tree will be printed after each operation.

Benchmarks

zig build bench

This simple benchark consists of inserting, searching for and deleting each line from testdata/words.txt (235886 lines). Benchmarks are compiled with --release-fast.

vs StringHashMap

(from zig's standard library) can be found here src/test_art.zig.

The results of the benchark on my machine:

.../zig/art.zig $ zig build bench
StringHashMap
insert 15ms, search 4ms, delete 2ms, combined 22ms
Art
insert 21ms, search 10ms, delete 13ms, combined 45ms

vs armon/libart

WARNING - this benchmark is old and flawed. Most of its time is spent reading lines from files which hides the performance of radix trees. Thanks to @iacore for helping me realize this.

Can be found src/clibart.zig

art.zig insert 505ms, search 482ms, delete 494ms, combined 1481ms
art.c   insert 494ms, search 481ms, delete 484ms, combined 1459ms
Operation% difference
insert2.22% slower
search0.20% slower
delete2.06% slower
combined1.50% slower

References