mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 03:05:31 -05:00
wip: perf(bitvec): use a VecI32.t underneath
This commit is contained in:
parent
c81d10426f
commit
76df299a36
3 changed files with 22 additions and 25 deletions
|
|
@ -1,55 +1,45 @@
|
|||
|
||||
type t = {
|
||||
mutable chunks: bytes; (* TODO: use a in32vec with bigarray *)
|
||||
}
|
||||
type t = VecI32.t
|
||||
|
||||
let create () : t = {
|
||||
chunks = Bytes.make 32 '\x00';
|
||||
}
|
||||
|
||||
let i2c = Char.chr
|
||||
let c2i = Char.code
|
||||
let create () : t = VecI32.create ~cap:16 ()
|
||||
|
||||
(* from index to offset in bytes *)
|
||||
let[@inline] idx_bytes_ (i:int) : int = i lsr 3
|
||||
let[@inline] idx_in_vec_ (i:int) : int = i lsr 5
|
||||
|
||||
(* from index to offset in a single char *)
|
||||
let mask_ = 0b111
|
||||
(* from index to offset in a single chunk *)
|
||||
let mask_ = 0b11111
|
||||
|
||||
(* number of bytes *)
|
||||
let[@inline] len_ (self:t) : int = Bytes.length self.chunks
|
||||
let[@inline] len_ (self:t) : int = VecI32.size self
|
||||
|
||||
let[@inline never] resize_ self idx : unit =
|
||||
let new_size =
|
||||
min Sys.max_string_length
|
||||
(max (idx+2) (let l = len_ self in l + 10 + l / 2))
|
||||
in
|
||||
let new_chunks = Bytes.make new_size (i2c 0) in
|
||||
Bytes.blit self.chunks 0 new_chunks 0 (len_ self);
|
||||
self.chunks <- new_chunks;
|
||||
VecI32.ensure_size self new_size;
|
||||
assert (len_ self > idx)
|
||||
|
||||
let[@inline] ensure_size self i =
|
||||
let idx = idx_bytes_ i in
|
||||
let idx = idx_in_vec_ i in
|
||||
if idx >= len_ self then (
|
||||
resize_ self idx
|
||||
)
|
||||
|
||||
let[@inline] get self i : bool =
|
||||
let idx = idx_bytes_ i in
|
||||
let c = c2i (Bytes.get self.chunks idx) in
|
||||
let idx = idx_in_vec_ i in
|
||||
let c = VecI32.get self idx in
|
||||
(c land (1 lsl (i land mask_))) <> 0
|
||||
|
||||
let set self i b : unit =
|
||||
let idx = idx_bytes_ i in
|
||||
let c = c2i (Bytes.get self.chunks idx) in
|
||||
let idx = idx_in_vec_ i in
|
||||
let c = VecI32.get self idx in
|
||||
let c =
|
||||
if b
|
||||
then c lor (1 lsl (i land mask_))
|
||||
else c land (lnot (1 lsl (i land mask_)))
|
||||
in
|
||||
Bytes.set self.chunks idx (i2c c)
|
||||
VecI32.set self idx c
|
||||
|
||||
let clear_all self =
|
||||
Bytes.fill self.chunks 0 (len_ self) '\x00'
|
||||
let clear_all self = VecI32.fill self 0
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ let[@inline] shrink self n = if n < self.sz then self.sz <- n
|
|||
let[@inline] size self = self.sz
|
||||
let[@inline] is_empty self = self.sz = 0
|
||||
|
||||
let[@inline] fill self x = A.fill self.data (Int32.of_int x)
|
||||
|
||||
(* ensure capacity is [new_cap] *)
|
||||
let resize_cap_ self new_cap =
|
||||
assert (A.dim self.data < new_cap);
|
||||
|
|
@ -34,7 +36,10 @@ let ensure_cap self (n:int) =
|
|||
let ensure_size self n =
|
||||
if n > self.sz then (
|
||||
ensure_cap self n;
|
||||
self.sz <- n
|
||||
for i=self.sz to n-1 do
|
||||
A.set self.data i 0l;
|
||||
done;
|
||||
self.sz <- n;
|
||||
)
|
||||
|
||||
let[@inline] push (self:t) i : unit =
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ val ensure_size : t -> int -> unit
|
|||
|
||||
val size : t -> int
|
||||
|
||||
val fill : t -> int -> unit
|
||||
|
||||
val clear : t -> unit
|
||||
|
||||
val is_empty : t -> bool
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue