作者回复: 赞!
作者回复: 👍
作者回复: 这是个和 CPU 指令集紧密相关的操作。x86/64 CPU 目前还是服务器的主流(虽然未来不一定)
作者回复: 不是 usize 大小的指针。你可以自己想想 String 和 Vec<T> 的结构都是什么样子的。所以这里 key 是 24 个字节,value 也是 24 个字节,它们再通过结构里的指针指向额外的堆地址里的内容。
作者回复: 你可以在不同的系统上打印 main 函数的地址和 main 下一个 u32,一个 vec 的堆地址,就可以大概看到不同地址的区别了。比如: ```rust fn main() { let a = 1; let arr = vec![1,2,3]; println!("main: {:p}, a: {:p}, s: {:p}", main as *const (), &a, &arr[0]); } ``` 在 playground 下的打印(https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8003d4ccfbf6d63280b124811a219f4a): main: 0x55bcfa1f5100, a: 0x7ffcd8b6adec, s: 0x55bcfb6ca9d0 如果你想知道更详细的各个段的地址,可以使用 readelf 或者在 gdb 里面查看。
作者回复: 对!
作者回复: 你可以参考:https://gankra.github.io/blah/rust-btree-case/ 来学习。虽然是比较旧的文章,但 Btreemap 的思想和大方向是一致的。 3. B=6,edges 是个数组,里面有 12 个元素,元素类型是可能未初始化(MaybeUninit)的BoxedNode<K, V>。这个代码开头处有伪代码表述想要达成的目的: // This is an attempt at an implementation following the ideal // // ``` // struct BTreeMap<K, V> { // height: usize, // root: Option<Box<Node<K, V, height>>> // } // // struct Node<K, V, height: usize> { // keys: [K; 2 * B - 1], // vals: [V; 2 * B - 1], // edges: [if height > 0 { Box<Node<K, V, height - 1>> } else { () }; 2 * B], // parent: Option<(NonNull<Node<K, V, height + 1>>, u16)>, // len: u16, // }
作者回复: 注意看图,这句话之后的图,你看看图中前后对比。 > 在移动的过程中,会涉及哈希的重分配。从下图可以看到,‘a’ / ‘c’ 的相对位置和它们的 ctrl byte 没有变化,但重新做 hash 后,‘b’ 的 ctrl byte 和位置都发生了变化。 现在 ctrl bits 的位置是:5 6 7 8 1 2 3 4。所以 0a 对应第一项。
作者回复: 1. 正确! 2. 需要内存 (200+15+1) * 2M = 432M,实际占用 (200+15) * 114M = 246M,利用率 57%。注意 HashMap bucket 数量是指数增长的。
作者回复: 对!