我试图通过在其上使用固定大小的滑动窗口来解析一个很长的文件。对于每个这样的窗口,我希望将其作为具有自定义结构作为值的键插入HashMap
,或者修改窗口的现有值。我的主要问题是内存使用,因为它应该扩展到非常大的数量(高达数十亿个不同的窗口),我想重用现有的密钥。
我想将窗口(或更具体的字节)附加到向量并将索引用作HashMap
中的键,但使用索引下的窗口进行哈希计算和密钥比较。因为窗口是重叠的,我只会附加新窗口的部分(如果我有一个输入AAAB和大小3我将有2个窗口:AAA和AAB,但只会存储4个字节--AAAB;窗口会有索引分别为0和1),这是没有用窗口本身键入HM的原因。
这里是简化的伪代码,其中我省略了最小输入问题:
let file = // content of the file on which i can call windows()
let vec = Rc::new(RefCell::new(Vec::new())); // RefCell allows me to store Rc in the hashmap while mutating the underlying vector
let hm: HashMap<KeyStruct, ValueStruct> = HashMap::new();
for i in file.windows(FIXED_SIZE) {
let idx = vec.len();
vec.borrow_mut().push(i);
if hm.contains_key(KeyStruct::new(idx)) {
// get the key associated with i
// modify the value associated with i
// do something with the key
vec.borrow_mut().pop(); // window is already in the vector
}
else {
hm.insert(KeyStruct::new(idx), ValueStruct::new(...));
}
}
我提出了两种不同的方法:修改现有的HashMap
实现以使其按预期工作,或使用自定义结构作为HashMap
的键。由于我只使用一个向量来存储窗口,因此我可以在Rc
中为其存储HashMap
,然后将其用于查找。
我还可以创建一个包含Rc
和索引的结构,并将其用作HashMap
的键。后一个解决方案适用于vanilla HashMap
,但会将大量冗余Rc
存储到同一个向量中。我还想过将一个静态指针存储到Rc
,然后在Rc
块中得到unsafe
,但我必须保证堆栈上Rc
的位置永远不会变化,我不确定我是否可以保证。
我尝试实现第一种方法(自定义HashMap
),但事实证明Bucket
使用了很多门控功能,我无法使用稳定的编译器。
更糟糕的是,我希望在成功查找时获得HashMap
中已有的密钥(因为不同的索引可以存储同一个窗口,{{1} } / hash
将是相同的)并在值结构中使用它。我无法使用cmp
提供的API找到相应的方法 - 我最接近的是使用HashMap
,其中包含entry()
,但它没有&# 39;有任何方法可以检索密钥,并且无法通过不安全的内存查找来获取密钥,因为OccupiedEntry
上的文档说明在默认表示中不保证结构中的顺序。我可以将键(或仅索引)存储在值struct中,但是每个条目添加另一个repr()
个字节,只是以可达到的方式存储索引/键,无论哪种方式都保存该条目
我的问题是:
size_of::<usize>()
的几个方法并编译整个项目?HashMap
成功查找后,有没有办法获取密钥? (我甚至found out libs团队决定反对HashMap
实施方法,这样我就可以获得密钥...)修改
为了澄清问题,让我们考虑一个简单的例子 - 输入ABABCBACBC,窗口大小为2. 我们应该将索引作为Entry
的关键,它应该得到窗口 - 作为从该索引开始的窗口的大小字节数:使用向量[A,A,C],索引1和窗口大小2 HashMap
应该尝试查找AC的散列/密钥。
我们得到这样的窗口:
HashMap
第一对是AB,我们将它附加到空向量中并给它一个0的索引。
AB -> BA -> AB -> BC -> CB -> BA -> AC -> CB -> BC
下一对是BA:
vec = [A, B]
hm = [(0, val)]
vec = [A,B,A] hm = [(0,val0),(1,val1)]
接下来是AB窗口:
修改价值,用钥匙等做点什么......
vec = [A,B,A] hm = [(0,val0_modified),(1,val1)]
在循环输入后,我应该最终得到:
HashMap
和对的索引可以表示为:[(AB,0),(BA,1),(BC,3),(CB,4),(AC,6)]
我不想要修改密钥。除了在查找/插入期间推/弹窗口外,我也不想修改矢量。
旁注:尽管在将所有内容都放入向量后,我仍然在此特定示例中有冗余信息,但在使用原始数据时却不会出现这种情况。