comparison rust/hg-core/src/revlog/index.rs @ 51260:c4f1a790bda8

rust-index: use a `BitVec` instead of plain `Vec` for heads computation The `Vec` method uses one byte per revision, this uses 1 per 8 revisions, which improves our memory footprint. For large graphs (10+ millions), this can make a measurable difference server-side. I have seen no measurable impact on execution speed.
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 29 Nov 2023 15:58:24 -0500
parents ed6683d4cb29
children 9088c6d65ef6
comparison
equal deleted inserted replaced
51259:ed6683d4cb29 51260:c4f1a790bda8
1 use std::collections::{HashMap, HashSet}; 1 use std::collections::{HashMap, HashSet};
2 use std::fmt::Debug; 2 use std::fmt::Debug;
3 use std::ops::Deref; 3 use std::ops::Deref;
4 use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; 4 use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
5 5
6 use bitvec::prelude::*;
6 use byteorder::{BigEndian, ByteOrder}; 7 use byteorder::{BigEndian, ByteOrder};
7 use bytes_cast::{unaligned, BytesCast}; 8 use bytes_cast::{unaligned, BytesCast};
8 9
9 use super::REVIDX_KNOWN_FLAGS; 10 use super::REVIDX_KNOWN_FLAGS;
10 use crate::errors::HgError; 11 use crate::errors::HgError;
566 } 567 }
567 568
568 let as_vec = if self.is_empty() { 569 let as_vec = if self.is_empty() {
569 vec![NULL_REVISION] 570 vec![NULL_REVISION]
570 } else { 571 } else {
571 let mut not_heads = vec![false; self.len()]; 572 let mut not_heads = bitvec![0; self.len()];
572 dagops::retain_heads_fast(self, &mut not_heads, filtered_revs)?; 573 dagops::retain_heads_fast(
574 self,
575 not_heads.as_mut_bitslice(),
576 filtered_revs,
577 )?;
573 not_heads 578 not_heads
574 .into_iter() 579 .into_iter()
575 .enumerate() 580 .enumerate()
576 .filter_map(|(idx, is_not_head)| { 581 .filter_map(|(idx, is_not_head)| {
577 if is_not_head { 582 if is_not_head {