【问题标题】:Using Sled, how do I serialize and deserialize?使用 Sled,我如何序列化和反序列化?
【发布时间】:2019-10-12 20:25:56
【问题描述】:

我正在使用 crate sled 并尝试使用 bincode 进行简单的序列化和反序列化练习,只是为了掌握使用情况。

虽然我可以让插入工作,但尝试获得一系列结果似乎更加困难。在这里,我尝试输入两条记录:一个值为“Alice”的 42 键和一个值为“Bob”的 69 键,然后检索并打印它们。我很难协调向量的反序列化出来的:

use crate::db::Database;
use sled::Db;
use bincode;


pub struct SledDatabase {
    db: Db,
}

impl Database for SledDatabase {
    fn create(&self) {
        // Not handling errors; just an example.
        let key: i64 = 42;
        println!("ser {:?}", bincode::serialize(&key).unwrap());
        self.db.insert(bincode::serialize(&key).unwrap(), bincode::serialize("Alice").unwrap());
        let key2: i64 = 69;
        self.db.insert(bincode::serialize(&key2).unwrap(), bincode::serialize("Bob").unwrap());
    }

    fn query(&self, value : i64) {
        let range = value.to_ne_bytes();
        let mut iter = self.db.range(range..);
        while let Some(item) = iter.next() {
            let (k, v) = item.unwrap();
            println!("res {:?}", k);
            let key: i64 = bincode::deserialize(&k).unwrap();
            let value: String = bincode::deserialize(&v).unwrap();
            println!("age = {}", key);
            println!("name = {}", value);
        }
    }
}

impl SledDatabase {
    pub fn connect() -> SledDatabase {
        // use sled::{ConfigBuilder, Error};
        // let config = ConfigBuilder::new().temporary(true).build();
        SledDatabase { db: Db::open("sled.db").unwrap() }
    }
}

尝试使用我拼凑的控制台条目侦听器与之交互,我得到以下输出:

ser [42, 0, 0, 0, 0, 0, 0, 0]
>> 1
res [42]
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" })', src/libcore/result.rs:1084:5

这发生在尝试反序列化(Stringi64 值。有趣的是,输出似乎表明 sled 或 bincode 正在截断键值。

examples of sled usage 似乎并没有解决检索值的问题,但是通过查看一些文档和部分源代码,我感觉 serde 序列化是一种让东西进出 sled 的有效方式。

【问题讨论】:

    标签: rust bincode


    【解决方案1】:

    我无法使用上面给出的代码重现此问题,我不确定 sled 实现是否可能更改了与 range 函数相关的某些内容的大小,现在是否符合代码的预期,或者这只是一个错误。

    不过,由于我的一些粗心,我遇到了这个错误消息。

    fn main() -> Result<(), Error> {
        let db = sled::open("foo.sled_db").unwrap();
        let codec = bincode::config();
    
        db.insert("uhoh", codec.serialize(&0)?)?;
        let ser = &db.get("uhoh")?.unwrap();
        let de1: i32 = codec.deserialize(ser)?;
        println!("ok... {}", de1);
        let de2: usize = codec.deserialize(ser)?;
        println!("not ok {}", de2);
    }
    
    • 为了简化问题,我省略了 From&lt;sled::Error&gt;From&lt;bincode::Error&gt; 的实现。

    好的... 0

    错误:Bincode(Io(Custom { kind: UnexpectedEof,错误:“无法填充整个缓冲区”})

    这里要注意的是(如你所说)被序列化的值更小, 比我们尝试反序列化的类型。

    println!(
           "{} {}",
           core::mem::size_of::<usize>(),
           core::mem::size_of_val(&0)
    );
    
    println!(
            "{} {}",
            core::mem::size_of::<usize>(),
            core::mem::size_of::<i32>()
    );
    

    8 4

    8 4

    为了解决这个问题,我使用值&amp;0usize 而不是&amp;0 对其进行了序列化。 对 sled 键和值使用 serde 序列化确实看起来不错,但您确实需要小心推断出的值大小。

    【讨论】:

      猜你喜欢
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      • 2012-10-27
      • 2011-03-26
      相关资源
      最近更新 更多