Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:

1.

**Expected behavior**
A clear and concise description of what you expected to happen.

**Logs**
If applicable, add logs to help explain your problem.

**Additional context**
Add any other context about the problem here.
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Discussions
url: https://github.com/CogitatorTech/ordered/discussions
about: Please ask and answer general questions here
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
4 changes: 1 addition & 3 deletions .github/workflows/benches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: Run Benchmarks
on:
workflow_dispatch:
push:
branches:
- main
tags:
- 'v*'
pull_request:
Expand All @@ -25,7 +23,7 @@ jobs:
- name: Install Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: '0.15.1'
version: '0.15.2'

- name: Install Dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Install Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: '0.15.1'
version: '0.15.2'

- name: Install System Dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Install Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: '0.15.1'
version: '0.15.2'

- name: Install Dependencies
run: |
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: Run Tests
on:
workflow_dispatch:
push:
branches:
- main
tags:
- 'v*'
pull_request:
Expand All @@ -25,7 +23,7 @@ jobs:
- name: Install Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: '0.15.1'
version: '0.15.2'

- name: Install Dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ################################################################################
# # Configuration and Variables
# ################################################################################
ZIG ?= $(shell which zig || echo ~/.local/share/zig/0.15.1/zig)
ZIG ?= $(shell which zig || echo ~/.local/share/zig/0.15.2/zig)
BUILD_TYPE ?= Debug
BUILD_OPTS = -Doptimize=$(BUILD_TYPE)
JOBS ?= $(shell nproc || echo 2)
Expand Down
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,38 @@
<h2>Ordered</h2>

[![Tests](https://img.shields.io/github/actions/workflow/status/CogitatorTech/ordered/tests.yml?label=tests&style=flat&labelColor=282c34&logo=github)](https://github.com/CogitatorTech/ordered/actions/workflows/tests.yml)
[![Benchmarks](https://img.shields.io/github/actions/workflow/status/CogitatorTech/ordered/benches.yml?label=benches&style=flat&labelColor=282c34&logo=github)](https://github.com/CogitatorTech/ordered/actions/workflows/benches.yml)
[![Benchmarks](https://img.shields.io/github/actions/workflow/status/CogitatorTech/ordered/benches.yml?label=benchmarks&style=flat&labelColor=282c34&logo=github)](https://github.com/CogitatorTech/ordered/actions/workflows/benches.yml)
[![CodeFactor](https://img.shields.io/codefactor/grade/github/CogitatorTech/ordered?label=quality&style=flat&labelColor=282c34&logo=codefactor)](https://www.codefactor.io/repository/github/CogitatorTech/ordered)
[![Zig Version](https://img.shields.io/badge/Zig-0.15.2-orange?logo=zig&labelColor=282c34)](https://ziglang.org/download/)
<br>
[![Docs](https://img.shields.io/badge/docs-view-blue?style=flat&labelColor=282c34&logo=read-the-docs)](https://CogitatorTech.github.io/ordered/)
[![Examples](https://img.shields.io/badge/examples-view-green?style=flat&labelColor=282c34&logo=zig)](https://github.com/CogitatorTech/ordered/tree/main/examples)
[![Zig Version](https://img.shields.io/badge/Zig-0.15.1-orange?logo=zig&labelColor=282c34)](https://ziglang.org/download/)
[![Release](https://img.shields.io/github/release/CogitatorTech/ordered.svg?label=release&style=flat&labelColor=282c34&logo=github)](https://github.com/CogitatorTech/ordered/releases/latest)
[![License](https://img.shields.io/badge/license-MIT-007ec6?label=license&style=flat&labelColor=282c34&logo=open-source-initiative)](https://github.com/CogitatorTech/ordered/blob/main/LICENSE)

A collection of data structures that keep data in order in pure Zig
Pure Zig implementations of high-performance, memory-safe ordered data structures

</div>

---

Ordered is a Zig library that provides fast and efficient implementations of various popular data structures including
Ordered is a Zig library that provides efficient implementations of various popular data structures including
B-tree, skip list, trie, and red-black tree for Zig programming language.

### Supported Data Structures
### Features

Currently supported data structures include:
To be added.

- [B-tree](src/ordered/btree_map.zig): A self-balancing search tree where nodes can have many children.
- [Sorted Set](src/ordered/sorted_set.zig): A data structure that stores a collection of unique elements in a consistently sorted order.
- [Skip List](src/ordered/skip_list.zig): A probabilistic data structure that uses multiple linked lists to create "express lanes" for fast, tree-like search.
- [Trie](src/ordered/trie.zig): A tree where paths from the root represent prefixes which makes it extremely fast for tasks like text autocomplete.
- [Red-black Tree](src/ordered/red_black_tree.zig): A self-balancing binary search tree that uses node colors to guarantee efficient operations.
- [Cartesian Tree](src/ordered/cartesian_tree.zig): A binary tree that uniquely combines a binary search tree property for its keys with a heap** property for its values.
### Data Structures

| # | Data Structure | Build Complexity | Memory Complexity | Search Complexity |
|---|----------------|------------------|-------------------|----------------------|
| 1 | B-tree | $O(\log n)$ | $O(n)$ | $O(\log n)$ |
| 2 | Cartesian tree | $O(\log n)$\* | $O(n)$ | $O(\log n)$\* |
| 3 | Red-black tree | $O(\log n)$ | $O(n)$ | $O(\log n)$ |
| 4 | Skip list | $O(\log n)$\* | $O(n)$ | $O(\log n)$\* |
| 5 | Sorted set | $O(n)$ | $O(n)$ | $O(\log n)$ |
| 6 | Trie | $O(m)$ | $O(n \cdot m)$ | $O(m)$ |
| Data Structure | Build Complexity | Memory Complexity | Search Complexity |
|------------------------------------------------------------------------|------------------|-------------------|-------------------|
| [B-tree](https://en.wikipedia.org/wiki/B-tree) | $O(\log n)$ | $O(n)$ | $O(\log n)$ |
| [Cartesian tree](https://en.wikipedia.org/wiki/Cartesian_tree) | $O(\log n)$\* | $O(n)$ | $O(\log n)$\* |
| [Red-black tree](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree) | $O(\log n)$ | $O(n)$ | $O(\log n)$ |
| [Skip list](https://en.wikipedia.org/wiki/Skip_list) | $O(\log n)$\* | $O(n)$ | $O(\log n)$\* |
| Sorted set | $O(n)$ | $O(n)$ | $O(\log n)$ |
| [Trie](https://en.wikipedia.org/wiki/Trie) | $O(m)$ | $O(n \cdot m)$ | $O(m)$ |

- $n$: number of stored elements
- $m$: maximum length of a key
Expand Down Expand Up @@ -72,6 +68,10 @@ and view in a web browser.

Check out the [examples](examples) directory for example usages of Ordered.

### Benchmarks

To be added.

---

### Contributing
Expand Down
6 changes: 3 additions & 3 deletions benches/b2_sorted_set.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn benchmarkAdd(allocator: std.mem.Allocator, size: usize) !void {

var i: i32 = 0;
while (i < size) : (i += 1) {
try set.add(i);
_ = try set.put(i);
}

const elapsed = timer.read() - start;
Expand All @@ -51,7 +51,7 @@ fn benchmarkContains(allocator: std.mem.Allocator, size: usize) !void {

var i: i32 = 0;
while (i < size) : (i += 1) {
try set.add(i);
_ = try set.put(i);
}

var timer = try Timer.start();
Expand Down Expand Up @@ -80,7 +80,7 @@ fn benchmarkRemove(allocator: std.mem.Allocator, size: usize) !void {

var i: i32 = 0;
while (i < size) : (i += 1) {
try set.add(i);
_ = try set.put(i);
}

var timer = try Timer.start();
Expand Down
10 changes: 5 additions & 5 deletions benches/b3_red_black_tree.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn benchmarkInsert(allocator: std.mem.Allocator, size: usize) !void {

var i: i32 = 0;
while (i < size) : (i += 1) {
try tree.insert(i);
try tree.put(i);
}

const elapsed = timer.read() - start;
Expand All @@ -55,7 +55,7 @@ fn benchmarkFind(allocator: std.mem.Allocator, size: usize) !void {

var i: i32 = 0;
while (i < size) : (i += 1) {
try tree.insert(i);
try tree.put(i);
}

var timer = try Timer.start();
Expand All @@ -64,7 +64,7 @@ fn benchmarkFind(allocator: std.mem.Allocator, size: usize) !void {
i = 0;
var found: usize = 0;
while (i < size) : (i += 1) {
if (tree.find(i) != null) found += 1;
if (tree.get(i) != null) found += 1;
}

const elapsed = timer.read() - start;
Expand All @@ -84,7 +84,7 @@ fn benchmarkRemove(allocator: std.mem.Allocator, size: usize) !void {

var i: i32 = 0;
while (i < size) : (i += 1) {
try tree.insert(i);
try tree.put(i);
}

var timer = try Timer.start();
Expand All @@ -111,7 +111,7 @@ fn benchmarkIterator(allocator: std.mem.Allocator, size: usize) !void {

var i: i32 = 0;
while (i < size) : (i += 1) {
try tree.insert(i);
try tree.put(i);
}

var timer = try Timer.start();
Expand Down
2 changes: 1 addition & 1 deletion benches/b4_skip_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn benchmarkDelete(allocator: std.mem.Allocator, size: usize) !void {

i = 0;
while (i < size) : (i += 1) {
_ = list.delete(i);
_ = list.remove(i);
}

const elapsed = timer.read() - start;
Expand Down
14 changes: 7 additions & 7 deletions benches/b5_trie.zig
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,14 @@ fn benchmarkPrefixSearch(allocator: std.mem.Allocator, size: usize) !void {

i = 0;
while (i < num_searches) : (i += 1) {
var keys = try trie.keysWithPrefix(allocator, "key_");
defer {
for (keys.items) |key| {
allocator.free(key);
}
keys.deinit(allocator);
var iter = try trie.keysWithPrefix(allocator, "key_");
defer iter.deinit();

var count: usize = 0;
while (try iter.next()) |_| {
count += 1;
}
total_found += keys.items.len;
total_found += count;
}

const elapsed = timer.read() - start;
Expand Down
4 changes: 2 additions & 2 deletions benches/b6_cartesian_tree.zig
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ fn benchmarkIterator(allocator: std.mem.Allocator, size: usize) !void {
var timer = try Timer.start();
const start = timer.lap();

var iter = tree.iterator(allocator);
var iter = try tree.iterator(allocator);
defer iter.deinit();

var count: usize = 0;
while (iter.next()) |_| {
while (try iter.next()) |_| {
count += 1;
}

Expand Down
4 changes: 2 additions & 2 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.{
.name = .ordered,
.version = "0.1.0-alpha.2",
.version = "0.1.0-alpha.3",
.fingerprint = 0xc3121f99b0352e1b, // Changing this has security and trust implications.
.minimum_zig_version = "0.15.1",
.minimum_zig_version = "0.15.2",
.paths = .{
"build.zig",
"build.zig.zon",
Expand Down
16 changes: 15 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Ordered Examples
### Usage Examples

| # | File | Description |
|---|------------------------------------------------|-----------------------------------------------------|
Expand All @@ -8,3 +8,17 @@
| 4 | [e4_skip_list.zig](e4_skip_list.zig) | An example using the `SkipList` data structure |
| 5 | [e5_trie.zig](e5_trie.zig) | An example using the `Trie` data structure |
| 6 | [e6_cartesian_tree.zig](e6_cartesian_tree.zig) | An example using the `CartesianTree` data structure |

### Running Examples

To run an example, run the following command from the root of the repository:

```zig
zig build run-{FILE_NAME_WITHOUT_EXTENSION}
```

For example:

```zig
zig build run-e1_btree_map
```
8 changes: 5 additions & 3 deletions examples/e1_btree_map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub fn main() !void {
const allocator = std.heap.page_allocator;

std.debug.print("## BTreeMap Example ##\n", .{});
const B = 4; // Branching Factor
const B = 4; // Branching Factor for B-tree
var map = ordered.BTreeMap([]const u8, u32, strCompare, B).init(allocator);
defer map.deinit();

Expand All @@ -22,6 +22,8 @@ pub fn main() !void {
std.debug.print("Found key '{s}': value is {d}\n", .{ key_to_find, value_ptr.* });
}

_ = map.remove("banana");
std.debug.print("Contains 'banana' after delete? {any}\n\n", .{map.get("banana") != null});
const removed = map.remove("banana");
std.debug.print("Removed 'banana' with value: {?d}\n", .{if (removed) |v| v else null});
std.debug.print("Contains 'banana' after remove? {any}\n", .{map.contains("banana")});
std.debug.print("Map count: {d}\n\n", .{map.count()});
}
12 changes: 8 additions & 4 deletions examples/e2_sorted_set.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ pub fn main() !void {
var sorted_set = ordered.SortedSet(i32, i32Compare).init(allocator);
defer sorted_set.deinit();

try sorted_set.add(100);
try sorted_set.add(25);
try sorted_set.add(50);
_ = try sorted_set.put(100);
_ = try sorted_set.put(25);
_ = try sorted_set.put(50);
const duplicate = try sorted_set.put(50); // Try adding a duplicate

std.debug.print("SortedSet contents: {any}\n\n", .{sorted_set.items.items});
std.debug.print("SortedSet count: {d}\n", .{sorted_set.count()});
std.debug.print("Added duplicate 50? {any}\n", .{duplicate});
std.debug.print("SortedSet contents: {any}\n", .{sorted_set.items.items});
std.debug.print("Contains 100? {any}\n\n", .{sorted_set.contains(100)});
}
Loading
Loading