diff --git a/src/util/Bitvec.ml b/src/util/Bitvec.ml index 0c043858..74024e4f 100644 --- a/src/util/Bitvec.ml +++ b/src/util/Bitvec.ml @@ -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 diff --git a/src/util/VecI32.ml b/src/util/VecI32.ml index e595d30d..3be2aacc 100644 --- a/src/util/VecI32.ml +++ b/src/util/VecI32.ml @@ -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 = diff --git a/src/util/VecI32.mli b/src/util/VecI32.mli index d0f733ac..af50d61b 100644 --- a/src/util/VecI32.mli +++ b/src/util/VecI32.mli @@ -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