TL;DR; 10400000 * 100 - это как раз почти гигабайт.
В текущем виде это компилироваться не должно, тк as_slice возвращает ссылку, а чтобы структура могла содержать в себе ссылку - нужно добавить лайфтайм в объявление структуры => этот же лайфтайм нужно будет указать в сигнатуре функции.
Сейчас ни того ни другого я не вижу и код не должен компилироваться по причине того что ты пытаешься вернуть ссылку на данные, которые живут только в рамках fn get.
Если же BinValue на самом деле владеет вектором, то это не утечка, а вполне ожидаемое поведение.
Смотри, где должен он дропаться в будущем.
1. Тут можно достаточно легко избавиться от unsafe:
let res = self.get_index_and_file(key);
if res.is_none() {
return None;
}
let (file, info) = unsafe { res.unwrap_unchecked() };
Превращается в
let Some((file,info)) = self.get_index_and_file(key) else {
return None;
};
2.
Вообще достаточно странный код.
На этой строке мы создали вектор - это ок. Он требует места в куче. Хотя странно, что info.0 у нас u64, а не usize
let mut buf = vec![0; info.0 as usize];
file.read().unwrap().read_at(info.1, &mut buf).expect("failed to read");
Тут мы файл прочитали. Возможно был смысл сделать BufRead, но не думаю, что он тут бы тут много чего сделал бы.
В остальном тут нет аллокаций.
3. А вот это уже выглядит реально подозрительно:
return Some(BinValue::new(buf.as_slice()));
Это вообще компилируется? Покажи, что из себя представляет BinValue.
По хорошему оно должно брать ownership над вектором.
Если оставить код таким, то через 10 400 000 вызовов этой функции с заполнение буфера 100-байтовыми значениями утечёт примерно 1 ГБ памяти
10 400 000 * 100 = как раз примерно гиг.
Если BinValue в действительности берёт ownership, то это вполне себе ожидаемое поведение, а не утечка.
4. Ещё я бы на всякий случай убрал #[inline(always)]