https://github.com/artichoke/strudel
🥐 🥮 Rust port and drop-in replacement for the `st_hash` C hash table library
https://github.com/artichoke/strudel
artichoke c ffi hashmap ruby rust rust-crate
Last synced: 4 months ago
JSON representation
🥐 🥮 Rust port and drop-in replacement for the `st_hash` C hash table library
- Host: GitHub
- URL: https://github.com/artichoke/strudel
- Owner: artichoke
- License: mit
- Created: 2020-07-07T22:51:03.000Z (almost 6 years ago)
- Default Branch: trunk
- Last Pushed: 2025-11-03T01:40:20.000Z (8 months ago)
- Last Synced: 2025-11-03T03:23:32.494Z (8 months ago)
- Topics: artichoke, c, ffi, hashmap, ruby, rust, rust-crate
- Language: Rust
- Homepage: https://artichoke.github.io/strudel/strudel/
- Size: 4.79 MB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# strudel
[](https://github.com/artichoke/strudel/actions)
[](https://twitter.com/artichokeruby)
[](https://crates.io/crates/strudel)
[](https://docs.rs/strudel)
[](https://artichoke.github.io/strudel/strudel/)
Insertion-ordered hash table suitable for embedding via FFI.
Status: Work in progress.
Strudel was conceived as a drop-in replacement for `st_hash`, a hash map
implemented in C originally written by Peter Moore @ UCB and used in [Ruby]'s
[implementation][`st.c`] of the [`Hash`][hash] core class.
[ruby]: https://github.com/ruby/ruby
[hash]: https://ruby-doc.org/core-2.6.3/Hash.html
This crate is an exercise in implementing an insertion-ordered hash map in Rust
that cannot use the built-in `Hasher` infrastructure. The implementation uses
[Ruby's `Hash` backend][sthash-notes] and [Python's dict][pydict-notes] as prior
art.
[sthash-notes]: https://github.com/ruby/ruby/blob/v2_6_3/st.c#L1-L101
[pydict-notes]:
https://github.com/python/cpython/blob/v3.8.4/Objects/dictobject.c#L1-L110
This crate exports two types:
- `StHashMap` is a hash map built on top of the high performance [`HashMap`] and
[`Vec`] in Rust `std`. It is designed to implement the `st_hash` C API and be
FFI-friendly. This map supports in-place updates of hash keys. No mutable
iterators are provided.
- `StHashSet` is a set that wraps an `StHashMap` like `HashSet` does in `std`.
[`hashmap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html
[`vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
[`hashse`]: https://doc.rust-lang.org/std/collections/struct.HashSet.html
The `api` and `capi` modules in `strudel` build on top of `StHashMap` to
implement a compatible C API to `st_hash`. This API includes support for
iterating over a mutable map and in-place updates of `(key, value)` pairs. These
features distinguish it from the [`HashMap`] in Rust `std`.
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
strudel = "1.0"
```
## Building Ruby with Strudel
Strudel exports most of the symbols implemented by `st.c` in MRI 2.6.3. The
[included patch] and some [`configure` arguments] can build the bootstrapping
phase of MRI 2.6.3 with Strudel as the hash backend.
[included patch]: strudelify-mri.patch
[`configure` arguments]: build.sh
To build `miniruby` with Strudel, run:
```sh
./build.sh
```
`build.sh` requires autoconf 2.69. On macOS with Homebrew, this can be done
with:
```sh
brew install autoconf@2.69
PATH="/usr/local/opt/autoconf@2.69/bin:$PATH" ./build.sh
```
The resulting Ruby is in `./build/ruby-strudel-build-root/miniruby`. `miniruby`
can run simple scripts involving `Hash`, for example:
```console
$ ./build/ruby-strudel-build-root/miniruby -e 'h = {}' -e '1000.times { |i| h[i] = i }' -e 'puts h.length'
1000
```
`miniruby` successfully executes the benchmarks in [`benches`](benches).
NOTE: Strudel cannot build a full Ruby due to bugs in the implementation of the
`st_hash` API.
## License
`strudel` is licensed under the [MIT License](LICENSE) (c) Ryan Lopopolo.
This repository includes a vendored copy of [`st.h`] and [`st.c`] from Ruby
2.6.3, which is licensed under the [Ruby license] or [BSD 2-clause license]. See
[`vendor/README.md`] for more details. These sources are not distributed on
[crates.io].
[`st.h`]: vendor/ruby-2.6.3/st.h
[`st.c`]: vendor/ruby-2.6.3/st.c
[ruby license]: vendor/ruby-2.6.3/COPYING
[bsd 2-clause license]: vendor/ruby-2.6.3/BSDL
[`vendor/readme.md`]: vendor/README.md
[crates.io]: https://crates.io/
The `st_hash` implementation in Ruby includes the following notice:
```
/* This is a public domain general purpose hash table package
originally written by Peter Moore @ UCB.
The hash table data strutures were redesigned and the package was
rewritten by Vladimir Makarov . */
```