Skip to content

Instantly share code, notes, and snippets.

@arl
Last active January 27, 2023 09:32
Show Gist options
  • Save arl/58fb163ef702fa3895e10e4616b82a77 to your computer and use it in GitHub Desktop.
Save arl/58fb163ef702fa3895e10e4616b82a77 to your computer and use it in GitHub Desktop.

cargo run output:

cargo run
   Compiling rust-tmp v0.1.0 (/home/aurelien/dev/rust-tmp)
    Finished dev [unoptimized + debuginfo] target(s) in 0.99s
     Running `target/debug/app`
existing_value: [105, 100, 49, 0, 0, 0, 0, 3, 248, 255, 255, 255, 1, 0, 0, 0] address: 0x55a2ac554a95
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `0`: unaligned buffer, expected alignment 4 but found alignment 1
help: rkyv requires byte buffers to be aligned to access the data inside.
      Using an ALignedVec or manually aligning your data with #[align(...)]
      may resolve this issue.', /home/aurelien/.cargo/registry/src/github.com-1ecc6299db9ec823/rkyv-0.7.35/src/util/mod.rs:40:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
[package]
edition = "2018"
name = "rust-tmp"
version = "0.1.0"
[dependencies]
anyhow = "1.0.52"
derive_more = "0.99.17"
rkyv = "0.7.35"
rocksdb = "0.18.0"
[[bin]]
name = "app"
path = "src/main.rs"
use std::path::Path;
use anyhow::Result;
use rkyv::ser::Serializer;
use rkyv::{AlignedVec, Archive, Deserialize, Serialize};
fn serialize_ids(ids: Vec<Identifier>) -> Result<AlignedVec> {
let mut serializer = rkyv::ser::serializers::AllocSerializer::<1024>::default();
serializer.serialize_value(&ids)?;
Ok(serializer.into_serializer().into_inner())
}
fn deserialize_ids(buf: &[u8]) -> Result<Vec<Identifier>> {
let archived = unsafe { rkyv::archived_root::<Vec<Identifier>>(buf) };
Ok(archived.deserialize(&mut rkyv::Infallible)?)
}
fn identifier_merge_zerocopy(
_new_key: &[u8],
existing_val: Option<&[u8]>,
operands: &rocksdb::MergeOperands,
) -> Option<Vec<u8>> {
println!(
"existing_value: {:?} address: {:p}",
existing_val.unwrap(),
existing_val.unwrap()
);
let mut result = Vec::new();
if let Some(buf) = existing_val {
let ids = deserialize_ids(&buf).expect("from binary");
result.extend(ids.into_iter());
};
for buf in operands {
let ids = deserialize_ids(&buf).expect("from binary");
result.extend(ids.into_iter());
}
let bytes = serialize_ids(result).expect("to binary");
Some(bytes.into_vec())
}
#[derive(Debug, Clone, Eq, PartialEq, Archive, Deserialize, Serialize)]
pub struct Identifier {
pub value: String,
}
fn main() {
let mut opts = rocksdb::Options::default();
opts.create_missing_column_families(true);
opts.create_if_missing(true);
opts.set_merge_operator_associative("identifier operator", identifier_merge_zerocopy);
let db = rocksdb::DB::open(&opts, Path::new("./rocks.db")).expect("open/create rocksdb");
let key = &"key".to_string();
let id1 = Identifier {
value: "id1".to_string(),
};
let ids = vec![id1.clone()];
let buf = serialize_ids(ids.clone()).expect("serialize");
let res = deserialize_ids(&buf).expect("deserialize");
assert_eq!(ids, res, "not equal?!");
let ids = vec![id1.clone()];
let buf = serialize_ids(ids).expect("serialize");
db.put(key, buf).expect("put");
let res = db.get(key).expect("get").expect("not null");
let ids_back = deserialize_ids(&res).expect("deserialize");
assert_eq!(ids_back, vec![id1.clone()]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment