Skip to content

Commit 7ed4318

Browse files
authored
Refactoring, docs, tests, v0.6 (#22)
* moved all rust code to `rust` mod * moved cpp code to `cpp` mod * both are now optional * docs and an example for native * use main C++ repo * added myself to authors (hope it's ok) * add `--all-features` to all tests
1 parent 8bf978f commit 7ed4318

27 files changed

Lines changed: 273 additions & 191 deletions

.github/workflows/ci.yml

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,18 @@ jobs:
1717
with: { tool: just }
1818
- uses: actions/checkout@v4
1919
with: { submodules: recursive }
20-
#
21-
# Uncomment this and below once the crate has been published to crates.io
22-
#
23-
# - name: Ensure this crate has not yet been published (on release)
24-
# if: github.event_name == 'release' && matrix.type == 'latest'
25-
# run: just check-if-published
20+
- name: Ensure this crate has not yet been published (on release)
21+
if: github.event_name == 'release' && matrix.type == 'latest'
22+
run: just check-if-published
2623
- uses: Swatinem/rust-cache@v2
2724
if: github.event_name != 'release' && github.event_name != 'workflow_dispatch'
2825
- run: just -v ci-test
29-
# - name: Check semver
30-
# uses: obi1kenobi/cargo-semver-checks-action@v2
31-
# - name: Test packaging for publish
32-
# run: |
33-
# rustup install nightly --profile minimal
34-
# just test-publish
26+
- name: Check semver
27+
uses: obi1kenobi/cargo-semver-checks-action@v2
28+
- name: Test packaging for publish
29+
run: |
30+
rustup install nightly --profile minimal
31+
just test-publish
3532
3633
msrv:
3734
name: Test MSRV

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[submodule "cpp"]
22
path = cpp
3-
url = https://github.com/nyurik/FastPFor-cpp.git
3+
url = https://github.com/fast-pack/FastPFOR.git

Cargo.toml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[package]
22
name = "fastpfor"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
description = "FastPFOR library written in Rust."
5-
authors = ["Francisco Jimenez <jjcfrank@gmail.com>"]
5+
authors = ["Francisco Jimenez <jjcfrank@gmail.com>", "Yuri Astrakhan <YuriAstrakhan@gmail.com>"]
66
repository = "https://github.com/jjcfrancisco/fastpfor"
77
edition = "2021"
88
license = "MIT OR Apache-2.0"
@@ -11,25 +11,27 @@ categories = ["compression"]
1111
rust-version = "1.83.0"
1212

1313
[features]
14-
# We probably want to build without the C++ bindings by default.
14+
# Eventually we may want to build without the C++ bindings by default.
1515
# Keeping it on for now to simplify development.
1616
default = ["cpp"]
1717
cpp = ["dep:cmake", "dep:cxx", "dep:cxx-build"]
18+
rust = ["dep:thiserror"]
1819

1920
[dependencies]
20-
rand = "0.8.5"
21-
thiserror = "2.0.7"
2221
cxx = { version = "1.0.136", optional = true }
22+
thiserror = { version = "2.0.7" , optional = true}
23+
24+
[dev-dependencies]
25+
rand = "0.9.0"
2326

2427
[build-dependencies]
2528
cmake = { version = "0.1.52", optional = true }
2629
cxx-build = { version = "1.0.136", optional = true }
2730

2831
[lints.rust]
29-
unused_assignments = "allow"
3032
dead_code = "allow"
33+
unused_assignments = "allow"
34+
unused_qualifications = "warn"
3135

3236
[lints.clippy]
33-
unnecessary_cast = "allow"
34-
ptr_arg = "allow"
3537
needless_range_loop = "allow"

README.md

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,101 @@
1-
# FastPFor
1+
# FastPFor for Rust
22

33
[![GitHub](https://img.shields.io/badge/github-fastpfor-8da0cb?logo=github)](https://github.com/jjcfrancisco/fastpfor)
44
[![crates.io version](https://img.shields.io/crates/v/fastpfor.svg)](https://crates.io/crates/fastpfor)
55
[![docs.rs docs](https://docs.rs/fastpfor/badge.svg)](https://docs.rs/fastpfor)
6-
[![crates.io version](https://img.shields.io/crates/l/fastpfor.svg)](https://github.com/jjcfrancisco/fastpfor/blob/main/LICENSE-APACHE)
6+
[![license](https://img.shields.io/crates/l/fastpfor.svg)](https://github.com/jjcfrancisco/fastpfor/blob/main/LICENSE-APACHE)
77
[![CI build](https://github.com/jjcfrancisco/fastpfor/actions/workflows/ci.yml/badge.svg)](https://github.com/jjcfrancisco/fastpfor/actions)
88

9-
FastPFOR library written in Rust.
9+
This is a Rust wrapper for the [C++ FastPFor library](https://github.com/fast-pack/FastPFor), as well as a pure Rust re-implementation (work in progress). Supports 32-bit and 64-bit integers, and SIMD-optimized codecs for 128-bit and 256-bit vectors. Based on the [Decoding billions of integers per second through vectorization, 2012](https://arxiv.org/abs/1209.2137) paper.
1010

11-
## Requirements
11+
### Supported algorithms
12+
Unless otherwise specified, all codecs support `&[u32]` only.
13+
* BP32
14+
* Copy
15+
* FastBinaryPacking8
16+
* FastPFor128 (both `&[u32]` and `&[u64]`)
17+
* FastPFor256 (both `&[u32]` and `&[u64]`)
18+
* FastBinaryPacking16
19+
* FastBinaryPacking32
20+
* MaskedVByte
21+
* NewPFor
22+
* OptPFor
23+
* PFor2008
24+
* PFor
25+
* SimdBinaryPacking
26+
* SimdFastPFor128
27+
* SimdFastPFor256
28+
* SimdGroupSimple
29+
* SimdGroupSimpleRingBuf
30+
* SimdNewPFor
31+
* SimdOptPFor
32+
* SimdPFor
33+
* SimdSimplePFor
34+
* Simple16
35+
* Simple8b
36+
* Simple8bRle
37+
* Simple9
38+
* Simple9Rle
39+
* SimplePFor
40+
* StreamVByte
41+
* VByte
42+
* VarInt (both `&[u32]` and `&[u64]`)
43+
* VarIntGb
1244

13-
# MacOS
14-
To build FastPFor on macOS, you'll need to install SIMDe. Since Homebrew installs packages in /opt/homebrew (for Apple Silicon), you'll also need to explicitly set the include paths.
45+
## Usage
46+
47+
### Crate Features
48+
* `cpp` - C++ implementation (default)
49+
* `rust` - Rust implementation (work in progress, opt-in)
50+
51+
### Using C++ Wrapper
52+
53+
```rust
54+
use fastpfor::cpp::{Codec32 as _, SimdFastPFor128Codec};
55+
56+
fn main() {
57+
let mut codec = SimdFastPFor128Codec::new();
58+
59+
// Encode
60+
let mut input = vec![1, 2, 3, 4, 5];
61+
let mut output = vec![0; 10]; // must be large enough
62+
let enc_slice = codec.encode32(&input, &mut output).unwrap();
63+
64+
// Decode
65+
let mut decoded = vec![0; 10]; // must be large enough
66+
let dec_slice = codec.decode32(&enc_slice, &mut decoded).unwrap();
67+
68+
assert_eq!(input, dec_slice);
69+
}
70+
```
71+
72+
## Build Requirements
73+
74+
When using the Rust implementation, no additional dependencies are required.
75+
When using the C++ implementation, you need to have a C++ compiler that supports C++14 and SIMD intrinsics. See [FastPFor C++ requirements](https://github.com/fast-pack/FastPFor?tab=readme-ov-file#software-requirements).
76+
77+
### Linux
78+
The default GitHub action runner for Linux has all the needed dependencies. For local development, you may need to install the following packages.
79+
80+
```bash
81+
# This list may be incomplete
82+
sudo apt-get install build-essential libsimde-dev
83+
```
84+
85+
### macOS
86+
To build FastPFor on macOS, you'll need to install SIMDe. Since Homebrew installs packages in `/opt/homebrew` (for Apple Silicon), you'll also need to explicitly set the include paths.
1587

16-
First, install SIMDe via Homebrew:
1788
```bash
89+
# install SIMDe via Homebrew
1890
brew install simde
1991
```
20-
Then, ensure the compiler can find the required headers by setting:
92+
2193
```bash
94+
# Ensure the compiler can find the required headers before building
2295
export CXXFLAGS="-I/opt/homebrew/include"
2396
export CFLAGS="-I/opt/homebrew/include"
2497
```
2598

26-
## To do:
27-
- [ x ] Rust wrapper for the [C++ library](https://github.com/fast-pack/FastPFor): try [`cxxbridge`](https://github.com/dtolnay/cxx) or [`bindgen`](https://crates.io/crates/bindgen)
28-
2999
## License
30100

31101
Licensed under either of

build.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
use std::path::Path;
2-
3-
use cmake::Config;
4-
51
fn main() {
6-
if !Path::new("cpp/CMakeLists.txt").exists() {
7-
panic!("FastPFOR submodule not initialized. Run `git submodule update --init`.");
8-
}
2+
#[cfg(feature = "cpp")]
3+
{
4+
use std::path::Path;
95

10-
// Compile FastPFOR using CMake
11-
let lib_path = Config::new("cpp").build().join("lib");
12-
let lib_path = lib_path.to_str().unwrap();
13-
println!("cargo:rerun-if-changed=cpp");
6+
if !Path::new("cpp/CMakeLists.txt").exists() {
7+
panic!("FastPFOR submodule not initialized. Run `git submodule update --init`.");
8+
}
149

15-
// Compile the bridge
16-
cxx_build::bridge("src/bridge/mod.rs")
17-
.include("cpp/headers")
18-
.include("src/bridge")
19-
.std("c++14")
20-
.compile("fastpfor_bridge");
21-
println!("cargo:rerun-if-changed=src/ffi.rs");
22-
println!("cargo:rerun-if-changed=src/bridge/fastpfor_bridge.cc");
23-
println!("cargo:rerun-if-changed=src/bridge/fastpfor_bridge.h");
10+
// Compile FastPFOR using CMake
11+
println!("cargo:rerun-if-changed=cpp");
12+
let lib_path = cmake::Config::new("cpp").build().join("lib");
13+
let lib_path = lib_path.to_str().unwrap();
2414

25-
// Link the FastPFOR library - must be done after the bridge is compiled
26-
println!("cargo:rustc-link-search=native={lib_path}");
27-
println!("cargo:rustc-link-lib=static=FastPFOR");
15+
// Compile the bridge
16+
println!("cargo:rerun-if-changed=src/cpp/fastpfor_bridge.h");
17+
println!("cargo:rerun-if-changed=src/cpp/mod.rs");
18+
cxx_build::bridge("src/cpp/mod.rs")
19+
.include("cpp/headers")
20+
.include("src/cpp")
21+
.std("c++14")
22+
.compile("fastpfor_bridge");
23+
24+
// Link the FastPFOR library - must be done after the bridge is compiled
25+
println!("cargo:rustc-link-search=native={lib_path}");
26+
println!("cargo:rustc-link-lib=static=FastPFOR");
27+
}
2828
}

justfile

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ update:
1515

1616
# Run cargo clippy
1717
clippy:
18-
cargo clippy --all-targets --workspace -- -D warnings
18+
cargo clippy --all-targets --workspace --all-features -- -D warnings
1919

2020
# Test code formatting
2121
test-fmt:
@@ -27,27 +27,27 @@ fmt:
2727

2828
# Build and open code documentation
2929
docs:
30-
cargo doc --no-deps --open
30+
cargo doc --no-deps --all-features --open
3131

3232
# Quick compile
3333
check:
34-
cargo check --all-targets --workspace
34+
cargo check --all-targets --workspace --all-features
3535

3636
# Default build
3737
build *ARGS:
38-
cargo build --all-targets --workspace {{ARGS}}
38+
cargo build --all-targets --workspace --all-features {{ARGS}}
3939

4040
# Run all tests
4141
test *ARGS: build
42-
cargo test --all-targets --workspace {{ARGS}}
42+
cargo test --all-targets --workspace --all-features {{ARGS}}
4343

4444
# Find the minimum supported Rust version. Install it with `cargo install cargo-msrv`
4545
msrv:
46-
cargo msrv find --component rustfmt -- {{just_executable()}} ci-test-msrv
46+
cargo msrv find --component rustfmt --all-features -- {{just_executable()}} ci-test-msrv
4747

4848
# Find unused dependencies. Install it with `cargo install cargo-udeps`
4949
udeps:
50-
cargo +nightly udeps --all-targets --workspace
50+
cargo +nightly udeps --all-targets --workspace --all-features
5151

5252
# Check semver compatibility with prior published version. Install it with `cargo install cargo-semver-checks`
5353
semver *ARGS:
@@ -72,22 +72,19 @@ test-publish:
7272

7373
# Run tests, and accept their results. Requires insta to be installed.
7474
bless:
75-
TRYBUILD=overwrite cargo insta test --accept
75+
TRYBUILD=overwrite cargo insta test --accept --all-features
7676

7777
# Test documentation
7878
test-doc:
79-
cargo test --doc
80-
cargo doc --no-deps
79+
cargo test --doc --all-features
80+
cargo doc --no-deps --all-features
8181

8282
rust-info:
8383
rustc --version
8484
cargo --version
8585

86-
# Run tests only relevant to the latest version
87-
ci-test-extras: test-doc
88-
8986
# Run all tests as expected by CI
90-
ci-test: rust-info test-fmt clippy test build
87+
ci-test: rust-info test-fmt clippy test test-doc
9188

9289
# Run minimal subset of tests to ensure compatibility with MSRV
9390
ci-test-msrv: rust-info test

0 commit comments

Comments
 (0)