Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bogwi/sortedmap
Map for fast storing key-value pairs sorted by key
https://github.com/bogwi/sortedmap
map skiplist sorted-data sorted-map zig zig-library zig-package ziglang
Last synced: about 2 months ago
JSON representation
Map for fast storing key-value pairs sorted by key
- Host: GitHub
- URL: https://github.com/bogwi/sortedmap
- Owner: bogwi
- License: mit
- Created: 2023-11-29T04:12:49.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2024-03-13T16:46:18.000Z (11 months ago)
- Last Synced: 2024-11-06T02:41:12.472Z (3 months ago)
- Topics: map, skiplist, sorted-data, sorted-map, zig, zig-library, zig-package, ziglang
- Language: Zig
- Homepage:
- Size: 125 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SortedMap in ZIG
## Description
Sorted Map is a fast key-value table, an advance version of [skiplist ADT](https://en.wikipedia.org/wiki/Skip_list) as proposed by W.Pugh in 1989 for ordered mapping of keys to values.
## Features
* Takes any numeric key except the maximum possible value for the given type.
* Takes any literal key of type `[]const u8` and of any length, but lexicographically smaller than `"ÿ"` ASCII 255.
* Values are arbitrary values.
* Works in `.set` or `.list` mode. The latter allows duplicate keys.
* Has forward and backward iteration.
* Has `min`, `max`, `median` key query.
* Supports queries by key or index, similar to Python's list class, including reverse indexing.
* Basic operations like `get`, `remove` work on a range as well.
* Updating the values by giving the `start_idx` - `stop_idx` range is O(1) each update. Yes, the whole map can be updated in O(n).
* Updating the values by giving the `start_key` - `stop_key` range is O(1) each update.## Performance
The benchmark is a set of standard stress routines to measure the throughput for the given task. The machine is an Apple M1 with 32GB RAM, optimization flag `ReleaseFast`.There are five tests in total, all of which are run on the random data with intermediate shuffling during the test stages:
**READ HEAVY**\
[read 98, insert 1, remove 1, update 0 ]\
Models caching of data in places such as web servers and disk page caches.**EXCHANGE**\
[read 10, insert 40, remove 40, update 10]\
Replicates a scenario where the map is used to exchange data.**EXCHANGE HEAVY**\
[read 1, insert 98, remove 98, update 1]\
This test is an inverse of *RH* test. Hard for any map.**RAPID GROW**\
[read 5, insert 80, remove 5, update 10]\
A scenario where the map is used to collect large amounts of data in a short burst.**CLONE**\
Clone the Map. That is, rebuild the map anew yet from the sorted data.### `u64`, arbitrary feed
```
SortedMap u64 BENCHMARK|
10_000_000 ops:each test||name |Tp Mops:sec| Rt :sec|
=====================================
|RH | 51.47| 0.194274|
arena size: 13804, cache len: 131|EX | 23.25| 0.430069|
arena size: 13804, cache len: 121|EXH | 20.20| 0.494928|
arena size: 13804, cache len: 135|RG | 0.53| 18.996072|
arena size: 595966060, cache len: 5|CLONE | 5.86| 1.279128|
```### `[8]const u8`, arbitrary literal, arbitrary feed
```
SortedMap STR BENCHMARK|
10_000_000 ops:each test||name |Tp Mops:sec| Rt :sec|
=====================================
|RH | 25.49| 0.392336|
arena size: 13564, cache len: 133|EX | 17.02| 0.587408|
arena size: 13564, cache len: 123|EXH | 14.49| 0.690115|
arena size: 13564, cache len: 137|RG | 0.37| 26.855707|
arena size: 894236804, cache len: 5|CLONE | 3.12| 2.400613|
```## How to run the benchmark
```
zig build bench
```
By default it runs 100_000 rounds each test on the `u64` type.Give it a larger number to stress the map more.
```
zig build bench -- 1_000_000
```
Prepend with `-str` to test on the arbitrary `[8]u8` word.
```
zig build bench -- 1_000_000 -str
```## How to use it
Copy `sorted_map.zig` and `cache.zig` into your project, or make a fork and work from there. Or you can import it as a dependency.Declare in your file:
```zig
const SortedMap = @import("sorted_map.zig").SortedMap;
```Initiate for numeric keys:
```zig
const map = SortedMap(u64, your_value_type, .list).init(your_allocator);
defer map.deinit();```
Initiate for string literal keys:
```zig
const map = SortedMap([]const u8, your_value_type, .set).init(your_allocator);
defer map.deinit();
```## zig version
```
0.12.0-dev.1830+779b8e259
```