refactor: lake: introduce lowerHexUInt64 (#13455)
This PR adds a `lowerHexUInt64` utility to Lake which is used to optimize `Hash.hex`.
This commit is contained in:
parent
592eb02bb2
commit
0fa749f71b
2 changed files with 39 additions and 3 deletions
|
|
@ -9,7 +9,7 @@ prelude
|
|||
public import Lean.Data.Json
|
||||
import Init.Data.Nat.Fold
|
||||
meta import Init.Data.Nat.Fold
|
||||
import Lake.Util.String
|
||||
public import Lake.Util.String
|
||||
public import Init.Data.String.Search
|
||||
public import Init.Data.String.Extra
|
||||
import Init.Data.Option.Coe
|
||||
|
|
@ -141,8 +141,8 @@ public def ofHex? (s : String) : Option Hash :=
|
|||
if s.utf8ByteSize = 16 && isHex s then ofHex s else none
|
||||
|
||||
/-- Returns the hash as 16-digit lowercase hex string. -/
|
||||
public def hex (self : Hash) : String :=
|
||||
lpad (String.ofList <| Nat.toDigits 16 self.val.toNat) '0' 16
|
||||
@[inline] public def hex (self : Hash) : String :=
|
||||
lowerHexUInt64 self.val
|
||||
|
||||
/-- Parse a hash from a string of decimal digits. -/
|
||||
public def ofDecimal? (s : String) : Option Hash :=
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ module
|
|||
|
||||
prelude
|
||||
public import Init.Data.ToString.Basic
|
||||
import Init.Data.UInt.Lemmas
|
||||
import Init.Data.String.Basic
|
||||
import Init.Data.Nat.Fold
|
||||
|
||||
|
|
@ -33,3 +34,38 @@ public def isHex (s : String) : Bool :=
|
|||
65 ≤ c -- 'A'
|
||||
else
|
||||
false
|
||||
|
||||
def lowerHexByte (n : UInt8) : UInt8 :=
|
||||
if n ≤ 9 then
|
||||
n + 48 -- + '0'
|
||||
else
|
||||
n + 87 -- + ('a' - 10)
|
||||
|
||||
theorem isValidChar_of_lt_256 (h : n < 256) : isValidChar n :=
|
||||
Or.inl <| Nat.lt_trans h (by decide)
|
||||
|
||||
def lowerHexChar (n : UInt8) : Char :=
|
||||
⟨lowerHexByte n |>.toUInt32, isValidChar_of_lt_256 <|
|
||||
UInt32.lt_iff_toNat_lt.mpr <| (lowerHexByte n).toNat_lt⟩
|
||||
|
||||
public def lowerHexUInt64 (n : UInt64) : String :=
|
||||
String.ofByteArray (ByteArray.emptyWithCapacity 16) ByteArray.isValidUTF8_empty
|
||||
|>.push (lowerHexChar (n >>> 60 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 56 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 52 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 48 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 44 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 40 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 36 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 32 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 28 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 24 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 20 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 16 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 12 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 8 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n >>> 4 &&& 0xf).toUInt8)
|
||||
|>.push (lowerHexChar (n &&& 0xf).toUInt8)
|
||||
|
||||
-- sanity check
|
||||
example : "0123456789abcdef" = lowerHexUInt64 0x0123456789abcdef := by decide
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue