Skip to content

Commit

Permalink
ArrayPool allocates arrays larger than expected, so complement with s…
Browse files Browse the repository at this point in the history
…pans
  • Loading branch information
tahina-pro committed Feb 17, 2024
1 parent 842fe06 commit 908137f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 14 deletions.
39 changes: 27 additions & 12 deletions src/3d/hashchk/Hashing_Op.fs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
module Hashing_Op

let debug_hash = false

type byte_array(ap: System.Buffers.ArrayPool<byte>, len: int32) =
let ar : byte[] = ap.Rent(len)
member val array = ar
member this.rw = System.Span(ar, 0, len)
member this.ro = System.ReadOnlySpan(ar, 0, len)
interface System.IDisposable with
member this.Dispose() = ap.Return(ar, false)

Expand All @@ -11,14 +14,14 @@ let hex_digits = [| "0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "a"; "b";
let byte_to_hex (b: byte) =
System.String.Concat (hex_digits.[int b / 16], hex_digits.[int b % 16])

let rec bytes_to_hex0 (b: byte[]) (i: int) : string =
let rec bytes_to_hex0 (b: System.ReadOnlySpan<byte>) (i: int) : string =
if i <= 0
then ""
else
let j = i - 1
System.String.Concat (bytes_to_hex0 b j, byte_to_hex b.[j])

let bytes_to_hex (b: byte[]) : string =
let bytes_to_hex (b: System.ReadOnlySpan<byte>) : string =
bytes_to_hex0 b b.Length

type hash_state() =
Expand All @@ -28,15 +31,25 @@ type hash_state() =
System.Security.Cryptography.IncrementalHash.CreateHash(System.Security.Cryptography.HashAlgorithmName.SHA256)
member this.encoding = enc
member this.AppendData(ar: byte_array) =
h.AppendData(ar.array)
if debug_hash then begin
let s = bytes_to_hex ar.ro
System.Console.WriteLine ("Trying to update with: " ^ s)
end
h.AppendData(ar.ro)
if debug_hash then begin
let len = h.HashLengthInBytes
use arr = this.new_array(len)
ignore (h.GetCurrentHash(arr.rw))
let s = bytes_to_hex arr.ro
System.Console.WriteLine ("Update: " ^ s)
end
member this.new_array(len: int32) : byte_array =
new byte_array(ap, len)
member this.finish() : string =
let len = h.HashLengthInBytes
use arr = this.new_array(len)
let dest = System.Span(arr.array)
ignore (h.GetHashAndReset(dest))
bytes_to_hex arr.array
ignore (h.GetHashAndReset(arr.rw))
bytes_to_hex arr.ro
interface System.IDisposable with
member this.Dispose() =
h.Dispose()
Expand All @@ -47,21 +60,20 @@ let hash_init () : hash_state =
let hash_bool (h: hash_state) (b: bool) : unit =
let byte : byte = System.Convert.ToByte (if b then 1 else 0)
use arr = h.new_array(1)
arr.array.[0] <- byte
arr.rw.[0] <- byte
h.AppendData arr

let hash_int (h: hash_state) (i: int32) : unit =
use arr = h.new_array(4)
let sp = System.Span(arr.array)
System.Buffers.Binary.BinaryPrimitives.WriteInt32BigEndian (sp, i)
System.Buffers.Binary.BinaryPrimitives.WriteInt32BigEndian (arr.rw, i)
h.AppendData arr

let hash_file (h: hash_state) (f: string) : unit =
use file = System.IO.File.Open(f, System.IO.FileMode.Open, System.IO.FileAccess.Read)
let len = int32 file.Length
hash_int h len
use arr = h.new_array(len)
let read = file.Read(arr.array, 0, len)
let read = file.Read(arr.rw)
assert (read = len)
h.AppendData arr

Expand All @@ -71,10 +83,13 @@ let hash_file_option (h: hash_state) (s: FStar_Pervasives_Native.option<string>)
| FStar_Pervasives_Native.Some f -> hash_bool h true; hash_file h f

let hash_string (h: hash_state) (s: string) : unit =
if debug_hash then begin
System.Console.WriteLine("hash_string: \"" ^ s ^ "\"")
end
let len = int32 (h.encoding.GetByteCount(s))
hash_int h len
use arr = h.new_array(len)
let encoded = h.encoding.GetBytes(s, 0, s.Length, arr.array, 0)
let encoded = h.encoding.GetBytes(System.String.op_Implicit(s), arr.rw)
assert (encoded = len)
h.AppendData arr

Expand Down
5 changes: 5 additions & 0 deletions src/3d/ocaml/Hashing_Op.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
type t = HashingBase.t

let debug_hash = false

(* Hash a boolean *)

let hash_bool h b =
Expand Down Expand Up @@ -32,6 +34,9 @@ let hash_file_option h = function
(* Hash a string *)

let hash_string h s =
if debug_hash then begin
print_endline ("hash_string: \"" ^ s ^ "\"")
end;
hash_int h (String.length s);
HashingBase.update h (Bytes.of_string s)

Expand Down
35 changes: 33 additions & 2 deletions src/3d/ocaml/sha/HashingBase.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
type t = Sha256.ctx

let init () = Sha256.init ()
let debug_hash = false

let update h b = Sha256.update_string h (Bytes.to_string b)
let init () = Sha256.init ()

let finish h = Bytes.of_string (Sha256.to_bin (Sha256.finalize h))

let char_of_int4 x =
assert (0 <= x && x < 16);
if x < 10
then char_of_int (int_of_char '0' + x)
else char_of_int (int_of_char 'a' + x - 10)

let hex_of_char c =
let i = int_of_char c in
assert (0 <= i && i < 256);
char_of_int4 (i / 16), char_of_int4 (i mod 16)

let hex_of_bytes buf =
let hex = Bytes.create (Bytes.length buf * 2) in
Bytes.iteri (fun idx c ->
let hi, lo = hex_of_char c in
Bytes.set hex (2 * idx) hi;
Bytes.set hex (2 * idx + 1) lo
) buf;
Bytes.to_string hex

let update h b =
if debug_hash then begin
print_endline ("Trying to update with: " ^ hex_of_bytes b);
end;
Sha256.update_string h (Bytes.to_string b);
if debug_hash then begin
let h' = Sha256.copy h in
let s = finish h' in
print_endline ("Update: " ^ hex_of_bytes s)
end

0 comments on commit 908137f

Please sign in to comment.