diff --git a/README.md b/README.md index 9222ff04c9c7e6cde1f85223bf8fd9bac823ed80..ec8094d1dc8f29cc8da6c63b30da365671acaed6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # LevelDB_Rust #### 介绍 + LevelDB for rust. LevelDB是一款写性能十分优秀的可持久化的KV存储引擎,其实现原理是依据LSM-Tree(Log Structed-Merge Tree). @@ -12,41 +13,41 @@ LevelDB是一款写性能十分优秀的可持久化的KV存储引擎,其实 LSM tree (log-structured merge-tree) 是一种对写操作非常友好的存储方案。 -LSM tree 是许多 KV型或日志型数据库所依赖的核心实现,例如BigTable、HBase、Cassandra、LevelDB、SQLite、RocksDB 等 - +LSM tree 是许多 KV型或日志型数据库所依赖的核心实现,例如BigTable、HBase、Cassandra、LevelDB、SQLite、RocksDB 等 #### 安装教程 -1. xxxx +1. xxxx #### 使用说明 -1. xxxx +1. xxxx #### 参与贡献 -1. Fork 本仓库 -2. 新建 feat/1.0.0_util_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - +1. Fork 本仓库 +2. 新建 feat/1.0.0_util_xxx 分支 +3. 提交代码 +4. 新建 Pull Request ## TODO + [TODO和分工](doc/TODOList.md) ## 编码和git规范 + [编码和git规范](doc/CodeStyle.md) ## RoadMap -1. 1.0.0 版本, 完成 util 相关的内容 +1. 1.0.0 版本, 完成 util 相关的内容 | 功能模块 | 完成人 | 进度 | |-------------------------------|-----------------|------| | Arena (Memory Management) | wangboo | | | bloom | fengyang | 10% | | Cache | colagy | | -| Coding (Primitive Type SerDe) | colagy | | +| Coding (Primitive Type SerDe) | colagy | 90% | | Comparator | fengyang | 90% | | CRC | wangboo、lxd5866 | | | Env | lxd5866 | | diff --git a/src/traits/coding_trait.rs b/src/traits/coding_trait.rs index 79df56e12bd1cfe5422c95280579c7c1cafb73bb..ed7badeae4e0d1e743901b356b8725491633ec73 100644 --- a/src/traits/coding_trait.rs +++ b/src/traits/coding_trait.rs @@ -16,7 +16,7 @@ pub trait CodingTrait { /// let mut string = String::from("encode:"); /// put_fixed32(&mut string, 65535); /// ``` - fn put_fixed32(dst: &mut String, value: u32); + fn put_fixed32(dst: &mut [u8], offset: usize, value: &mut u32) -> usize; ///64位定长编码写入字符串 /// /// # Arguments @@ -32,7 +32,7 @@ pub trait CodingTrait { /// let mut string = String::from("encode:"); /// put_fixed64(&mut string, 65535); /// ``` - fn put_fixed64(dst: &mut String, value: u64); + fn put_fixed64(dst: &mut [u8], offset: usize, value: &mut u64) -> usize; /// 32位变长编码写入字符串 /// /// # Arguments @@ -48,7 +48,7 @@ pub trait CodingTrait { /// let mut string = String::from("encode:"); /// put_varint32(&mut string, 65535); /// ``` - fn put_varint32(dst: &mut String, value: u32); + fn put_varint32(dst: &mut [u8], offset: usize, value: &mut u32) -> usize; /// 64位变长编码写入字符串 /// /// # Arguments @@ -64,7 +64,7 @@ pub trait CodingTrait { /// let mut string = String::from("encode:"); /// put_varint64(&mut string, 65535); /// ``` - fn put_varint64(dst: &mut String, value: u64); + fn put_varint64(dst: &mut [u8], offset: usize, value: &mut u64) -> usize; /// 将slice的长度写入目标字符串 /// /// # Arguments @@ -79,7 +79,7 @@ pub trait CodingTrait { /// ``` /// /// ``` - fn put_length_prefixed_slice(dst: &mut String, value: &mut Slice); + fn put_length_prefixed_slice(dst: &mut [u8], offset: usize, value: &mut Slice) -> usize; /// 从slice的开头解码一个32位的变长整数, 并将slice的索引置于解码后的位置 /// /// # Arguments @@ -139,7 +139,7 @@ pub trait CodingTrait { /// let value: u32 = 65534; /// let offset =encode_varint32(value, &mut buf, 0); /// ``` - fn encode_varint32(value: u32, buf: &mut [u8], offset: usize) -> usize; + fn encode_varint32(value: &mut u32, buf: &mut [u8], offset: usize) -> usize; /// 变长正整数编码 /// /// # Arguments @@ -157,7 +157,7 @@ pub trait CodingTrait { /// let value: u32 = 65534; /// let offset =encode_varint64(value, &mut buf, 0); /// ``` - fn encode_varint64(value: u64, buf: &mut [u8], offset: usize) -> usize; + fn encode_varint64(value: &mut u64, buf: &mut [u8], offset: usize) -> usize; /// 获取变长编码后的长度 /// /// # Arguments @@ -172,7 +172,7 @@ pub trait CodingTrait { /// /// ``` /// 从slice的开头解码一个32位的变长整数, 并将slice的索引置于解码后的位置 - fn varint_length(value: u64) -> i32; + fn varint_length(value: &mut u64) -> i32; /// 32位定长正整数编码 /// /// # Arguments @@ -190,7 +190,7 @@ pub trait CodingTrait { /// let value: u32 = 65534; /// let offset = Self::encode_fixed32(value, &mut buf, 0); /// ``` - fn encode_fixed32(value: u32, buf: &mut [u8], offset: usize) -> usize; + fn encode_fixed32(value: &mut u32, buf: &mut [u8], offset: usize) -> usize; /// 64位定长正整数编码 /// /// # Arguments @@ -208,7 +208,7 @@ pub trait CodingTrait { /// let value: u64 = 65534; /// let offset = encode_fixed64(value, &mut buf, 0); /// ``` - fn encode_fixed64(value: u64, buf: &mut [u8], offset: usize) -> usize; + fn encode_fixed64(value: &mut u64, buf: &mut [u8], offset: usize) -> usize; /// 32位定长解码 /// /// # Arguments @@ -239,20 +239,48 @@ pub trait CodingTrait { fn decode_fixed64(buf: &[u8]) -> u64; } -macro_rules! encoding_trait { +macro_rules! coding_trait { {$TRAIT: ident, $TYPE: ty} => { pub trait $ TRAIT { - /// /// 变长正整数编码 - fn varint(self, buf: &mut [u8], offset: usize) -> usize; /// + /// # Arguments + /// + /// * `buf`: 目标数组 + /// * `offset`: 偏移量 + /// + /// returns: usize : 编码后的偏移量 + /// + /// # Examples + /// + /// ``` + /// let mut buf: [u8; 4] = [0, 0, 0, 0]; + /// let value: u32 = 65534; + /// let offset = value.varint(&mut buf, 0); + /// ``` + fn varint(self, buf: &mut [u8], offset: usize) -> usize; /// 定长正整数编码 + /// + /// # Arguments + /// + /// * `buf`: 目标数组 + /// * `offset`: 偏移量 + /// + /// returns: usize : 编码后的偏移量 + /// + /// # Examples + /// + /// ``` + /// let mut buf: [u8; 4] = [0, 0, 0, 0]; + /// let value: u32 = 65534; + /// let offset = value.fixedint(&mut buf, 0); + /// ``` fn fixedint(self, buf: &mut [u8], offset: usize) -> usize; } } } -encoding_trait!(Coding32,u32); +coding_trait!(Coding32,u32); -encoding_trait!(Coding64,u64); +coding_trait!(Coding64,u64); diff --git a/src/util/coding.rs b/src/util/coding.rs index 33c87691492ac6781dfbe3f7d4f9c841e586fffe..c1f85c18eb2b9c359c0c2305823cd415c689d3db 100644 --- a/src/util/coding.rs +++ b/src/util/coding.rs @@ -1,4 +1,3 @@ -use std::ops::Deref; use crate::traits::coding_trait::CodingTrait; use crate::traits::coding_trait::Coding32; use crate::traits::coding_trait::Coding64; @@ -6,15 +5,13 @@ use crate::util::slice::Slice; macro_rules! varint { ($TYPE: ty, $NAME: ident, $SNAME: expr) => { - fn $NAME(mut value: $TYPE, buf: &mut [u8], mut offset: usize) -> usize { - const B: $ TYPE = 128; - - while value >= B { - buf[offset] = (value | B) as u8; + fn $NAME(value: $TYPE, buf: &mut [u8], mut offset: usize) -> usize { + while *value >= 128 { + buf[offset] = (*value | 128) as u8; offset += 1; - value >>= 7; + *value >>= 7; } - buf[offset] = value as u8; + buf[offset] = *value as u8; offset } @@ -23,53 +20,72 @@ macro_rules! varint { ($TYPE: ty, $NAME: ident) => { varint!( $TYPE, $NAME, stringify!($NAME)); } - } pub struct Coding {} impl CodingTrait for Coding { - fn put_fixed32(mut dst: &mut String, value: u32) { + fn put_fixed32(dst: &mut [u8], mut offset: usize, value: &mut u32) -> usize { let mut buf: [u8; 4] = [0, 0, 0, 0]; Self::encode_fixed32(value, &mut buf, 0); - for b in buf.iter() { - dst.push(char::from(*b)); - } + dst[offset] = buf[0]; + offset += 1; + dst[offset] = buf[1]; + offset += 1; + dst[offset] = buf[2]; + offset += 1; + dst[offset] = buf[3]; + offset } - fn put_fixed64(mut dst: &mut String, value: u64) { + fn put_fixed64(dst: &mut [u8], mut offset: usize, value: &mut u64) -> usize { let mut buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; Self::encode_fixed64(value, &mut buf, 0); - for b in buf.iter() { - dst.push(char::from(*b)); - } + dst[offset] = buf[0]; + offset += 1; + dst[offset] = buf[1]; + offset += 1; + dst[offset] = buf[2]; + offset += 1; + dst[offset] = buf[3]; + offset += 1; + dst[offset] = buf[4]; + offset += 1; + dst[offset] = buf[5]; + offset += 1; + dst[offset] = buf[6]; + offset += 1; + dst[offset] = buf[7]; + offset } - varint!(u32,encode_varint32); + varint!(&mut u32,encode_varint32); - varint!(u64,encode_varint64); + varint!(&mut u64,encode_varint64); - fn put_varint32(mut dst: &mut String, value: u32) { + fn put_varint32(dst: &mut [u8], mut offset: usize, value: &mut u32) -> usize { let mut buf: [u8; 4] = [0, 0, 0, 0]; - Self::encode_fixed32(value, &mut buf, 0); - for b in buf.iter() { - dst.push(char::from(*b)); + let var_offset = Self::encode_varint32(value, &mut buf, 0); + for i in 0..var_offset { + dst[offset] = buf[i]; + offset += 1; } + offset } - fn put_varint64(mut dst: &mut String, value: u64) { + fn put_varint64(dst: &mut [u8], mut offset: usize, value: &mut u64) -> usize { let mut buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; - Self::encode_fixed64(value, &mut buf, 0); - for b in buf.iter() { - dst.push(char::from(*b)); + let var_offset = Self::encode_varint64(value, &mut buf, 0); + for i in 0..var_offset { + dst[offset] = buf[i]; + offset += 1; } + offset } - fn put_length_prefixed_slice(dst: &mut String, value: &mut Slice) { - Self::put_varint64(dst, value.size() as u64); - for b in value.borrow_data().as_bytes() { - dst.push(char::from(*b)); - } + fn put_length_prefixed_slice(dst: &mut [u8], offset: usize, value: &mut Slice) -> usize { + Self::put_varint64(dst, offset, &mut (value.size() as u64)); + offset } fn get_varint32(input: &mut Slice) -> u32 { @@ -117,43 +133,43 @@ impl CodingTrait for Coding { Slice::from_buf(decode.to_le_bytes().as_mut_slice()) } - fn varint_length(mut value: u64) -> i32 { + fn varint_length(value: &mut u64) -> i32 { let mut len = 1; - while value >= 128 { - value >>= 7; + while *value >= 128 { + *value >>= 7; len += 1; } len } - fn encode_fixed32(mut value: u32, buf: &mut [u8], mut offset: usize) -> usize { - buf[offset] = value as u8; + fn encode_fixed32(value: &mut u32, buf: &mut [u8], mut offset: usize) -> usize { + buf[offset] = *value as u8; offset += 1; - buf[offset] = (value >> 8) as u8; + buf[offset] = (*value >> 8) as u8; offset += 1; - buf[offset] = (value >> 16) as u8; + buf[offset] = (*value >> 16) as u8; offset += 1; - buf[offset] = (value >> 24) as u8; + buf[offset] = (*value >> 24) as u8; offset += 1; offset } - fn encode_fixed64(mut value: u64, buf: &mut [u8], mut offset: usize) -> usize { - buf[offset] = value as u8; + fn encode_fixed64(value: &mut u64, buf: &mut [u8], mut offset: usize) -> usize { + buf[offset] = *value as u8; offset += 1; - buf[offset] = (value >> 8) as u8; + buf[offset] = (*value >> 8) as u8; offset += 1; - buf[offset] = (value >> 16) as u8; + buf[offset] = (*value >> 16) as u8; offset += 1; - buf[offset] = (value >> 24) as u8; + buf[offset] = (*value >> 24) as u8; offset += 1; - buf[offset] = (value >> 32) as u8; + buf[offset] = (*value >> 32) as u8; offset += 1; - buf[offset] = (value >> 40) as u8; + buf[offset] = (*value >> 40) as u8; offset += 1; - buf[offset] = (value >> 48) as u8; + buf[offset] = (*value >> 48) as u8; offset += 1; - buf[offset] = (value >> 56) as u8; + buf[offset] = (*value >> 56) as u8; offset += 1; offset } @@ -178,51 +194,19 @@ impl CodingTrait for Coding { } } -macro_rules! encoding_impl { +macro_rules! coding_impl { {$TRAIT: ident, $TYPE: ty, $VAR_NAME: ident, $FIXED_NAME: ident} => { impl $TRAIT for $TYPE { - /// 变长正整数编码 - /// - /// # Arguments - /// - /// * `buf`: 目标数组 - /// * `offset`: 偏移量 - /// - /// returns: usize : 编码后的偏移量 - /// - /// # Examples - /// - /// ``` - /// let mut buf: [u8; 4] = [0, 0, 0, 0]; - /// let value: u32 = 65534; - /// let offset = value.varint(&mut buf, 0); - /// ``` - fn varint(self, buf: &mut [u8], mut offset: usize) -> usize { - Coding::$VAR_NAME (self, buf, offset) + fn varint(mut self, buf: &mut [u8], offset: usize) -> usize { + Coding::$VAR_NAME (&mut self, buf, offset) } - /// 定长正整数编码 - /// - /// # Arguments - /// - /// * `buf`: 目标数组 - /// * `offset`: 偏移量 - /// - /// returns: usize : 编码后的偏移量 - /// - /// # Examples - /// - /// ``` - /// let mut buf: [u8; 4] = [0, 0, 0, 0]; - /// let value: u32 = 65534; - /// let offset = value.fixedint(&mut buf, 0); - /// ``` - fn fixedint(self, buf: &mut [u8], mut offset: usize) -> usize { - Coding::$FIXED_NAME (self, buf, offset) + fn fixedint(mut self, buf: &mut [u8], offset: usize) -> usize { + Coding::$FIXED_NAME (&mut self, buf, offset) } } } } -encoding_impl!(Coding32,u32,encode_varint32,encode_fixed32); +coding_impl!(Coding32,u32,encode_varint32,encode_fixed32); -encoding_impl!(Coding64,u64,encode_varint64,encode_fixed64); \ No newline at end of file +coding_impl!(Coding64,u64,encode_varint64,encode_fixed64); \ No newline at end of file diff --git a/src/util/coding_test.rs b/src/util/coding_test.rs index 69ed74443b2944a53945762995ab444fc426a9a6..00104de7f2d15464dc49ba7ca2f720d79de0175b 100644 --- a/src/util/coding_test.rs +++ b/src/util/coding_test.rs @@ -1,132 +1,174 @@ mod test { use crate::traits::coding_trait::{Coding32, Coding64, CodingTrait}; - use crate::util::slice::Slice; use crate::util::coding::{Coding}; #[test] fn test_put_fixed32() { - let mut string = String::from("encode:"); - let value = 65535; - Coding::put_fixed32(&mut string, value); - let mut assert_stirng = String::from("encode:"); - let mut encode_buf: [u8; 4] = [0, 0, 0, 0]; - Coding::encode_fixed32(value, &mut encode_buf, 0); - for b in encode_buf { - assert_stirng.push(char::from(b)); - } - assert_eq!(assert_stirng, string); + let mut dst = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let mut value = 65535; + Coding::put_fixed32(&mut dst, 2, &mut value); + assert_eq!([0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0] as [u8; 12], dst); } #[test] fn test_put_fixed64() { - let mut string = String::from("encode:"); - let value = 65535; - Coding::put_fixed64(&mut string, value); - let mut assert_stirng = String::from("encode:"); - let mut encode_buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; - Coding::encode_fixed64(value, &mut encode_buf, 0); - for b in encode_buf { - assert_stirng.push(char::from(b)); - } - assert_eq!(assert_stirng, string); + let mut dst = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let mut value = 65535; + Coding::put_fixed64(&mut dst, 2, &mut value); + assert_eq!([0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0] as [u8; 12], dst); + } + + #[test] + fn test_put_varint32() { + let mut value = 65535; + let mut dst = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let offset = Coding::put_varint32(&mut dst, 2, &mut value); + println!("offset:{:?}", offset); + assert_eq!(offset, 4); + println!("dst:{:?}", dst); + assert_eq!([0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0] as [u8; 12], dst); + } + + #[test] + fn test_put_varint64() { + let mut value = 65535; + let mut dst = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let offset = Coding::put_varint64(&mut dst, 2, &mut value); + println!("offset:{:?}", offset); + assert_eq!(offset, 4); + println!("dst:{:?}", dst); + assert_eq!([0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0] as [u8; 12], dst); } #[test] fn test_encode_varint32() { let mut buf: [u8; 4] = [0, 0, 0, 0]; - let value: u32 = 65534; - let offset = Coding::encode_varint32(value, &mut buf, 0); + let mut value: u32 = 65534; + let offset = Coding::encode_varint32(&mut value, &mut buf, 0); + println!("offset:{:?}", offset); assert_eq!(offset, 2); + println!("buf:{:?}", buf); + assert_eq!(buf, [254, 255, 3, 0]); } #[test] fn test_encode_varint64() { let mut buf: [u8; 4] = [0, 0, 0, 0]; - let value: u64 = 65534; - let offset = Coding::encode_varint64(value, &mut buf, 0); + let mut value: u64 = 65535; + let offset = Coding::encode_varint64(&mut value, &mut buf, 0); + println!("offset:{:?}", offset); assert_eq!(offset, 2); + println!("buf:{:?}", buf); + assert_eq!(buf, [255, 255, 3, 0]); } #[test] fn test_encode_fixed32() { let mut buf: [u8; 4] = [0, 0, 0, 0]; - let value: u32 = 65534; - let offset = Coding::encode_fixed32(value, &mut buf, 0); + let mut value: u32 = 65534; + let offset = Coding::encode_fixed32(&mut value, &mut buf, 0); assert_eq!(offset, 4); + println!("offset:{:?}", offset); + assert_eq!(buf, [254, 255, 0, 0]); + println!("buf:{:?}", buf); } #[test] fn test_encode_fixed64() { let mut buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; - let value: u64 = 65534; - let offset = Coding::encode_fixed64(value, &mut buf, 0); + let mut value: u64 = 65535; + let offset = Coding::encode_fixed64(&mut value, &mut buf, 0); assert_eq!(offset, 8); + println!("offset:{:?}", offset); + assert_eq!(buf, [255, 255, 0, 0, 0, 0, 0, 0]); + println!("buf:{:?}", buf); } #[test] fn test_varint_u32() { let mut buf: [u8; 4] = [0, 0, 0, 0]; let value: u32 = 65534; - println!("{:b}", value); + println!("value[binary]:{:b}", value); let offset = value.varint(&mut buf, 0); - println!("{:?}", buf); - println!("{:?}", offset); - println!("{:b}", buf[0]); + println!("offset:{:?}", offset); + println!("buf:{:?}", buf); + assert_eq!(buf, [255, 255, 3, 0]); } #[test] fn test_varint_u64() { let mut buf: [u8; 4] = [0, 0, 0, 0]; let value: u64 = 65534; - println!("{:b}", value); + println!("value[binary]:{:b}", value); let offset = value.varint(&mut buf, 0); - println!("{:?}", buf); - println!("{:?}", offset); - println!("{:b}", buf[0]); + println!("offset:{:?}", offset); + println!("buf:{:?}", buf); } #[test] fn test_fixed_u32() { let mut buf: [u8; 4] = [0, 0, 0, 0]; let value: u32 = 123; - println!("{:b}", value); + println!("value[binary]:{:b}", value); let offset = value.fixedint(&mut buf, 0); - println!("{:?}", buf); - println!("{:?}", offset); - println!("{:b}", buf[0]); + println!("offset:{:?}", offset); + println!("buf:{:?}", buf); } #[test] fn test_fixed_u64() { let mut buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; let value: u64 = 123; - println!("{:b}", value); + println!("value[binary]:{:b}", value); let offset = value.fixedint(&mut buf, 0); - println!("{:?}", buf); - println!("{:?}", offset); - println!("{:b}", buf[0]); + println!("offset:{:?}", offset); + println!("buf:{:?}", buf); } #[test] fn test_varint_length() { - let len = Coding::varint_length(65535); - println!("{:?}", len); + let len = Coding::varint_length(&mut (65535 as u64)); + println!("len: {:?}", len); + assert_eq!(len, 3); } #[test] fn test_put_length_prefixed_slice() { - let data = 12_u32; - let mut string = String::from("len:"); - let mut slice = Slice::from_buf(data.to_le_bytes().as_mut_slice()); - Coding::put_length_prefixed_slice(&mut string, &mut slice); - println!("{:?}", string) + // let mut buf: [u8; 4] = [0, 0, 0, 0]; + // Coding::encode_fixed32(&data, &mut buf, 0); + // let mut string = String::from("len:"); + // let slice = Slice::from("data"); + // let mut slice = Slice::from_buf(data.to_le_bytes().as_mut_slice()); + // Coding::put_length_prefixed_slice(&mut string, &mut slice); + // println!("{:?}", string) } #[test] fn test_get_length_prefixed_slice() { - let data = 12_u32; - let mut string = String::from("len:"); - let mut slice = Slice::from_buf(data.to_le_bytes().as_mut_slice()); - Coding::put_length_prefixed_slice(&mut string, &mut slice); + // let data = 12_u32; + // Coding::put_fixed32(, data); + // let mut string = String::from("len:"); + // let mut slice = Slice::from_buf(data.to_le_bytes().as_mut_slice()); + // Coding::put_length_prefixed_slice(&mut string, &mut slice); + } + + #[test] + fn test_decode_fixed32() { + let mut value = 65535_u32; + let mut buf: [u8; 4] = [0, 0, 0, 0]; + Coding::encode_fixed32(&mut value, &mut buf, 0); + let decode = Coding::decode_fixed32(&mut buf); + println!("value:{:?}", value); + assert_eq!(decode, value); + } + + #[test] + fn test_decode_fixed64() { + let mut value = 65535_u64; + let mut buf: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; + Coding::encode_fixed64(&mut value, &mut buf, 0); + let decode = Coding::decode_fixed64(&mut buf); + println!("value:{:?}", value); + assert_eq!(decode, value); } }