diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 086ac76..f34b956 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 + - uses: actions/cache@v4 env: cache-name: cache-artifacts with: diff --git a/Project.toml b/Project.toml index fd74038..4ffb702 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "WeakRefStrings" uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" authors = ["quinnj "] -version = "1.4.2" +version = "1.4.3" [deps] DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" diff --git a/src/WeakRefStrings.jl b/src/WeakRefStrings.jl index 12def29..a0571b7 100644 --- a/src/WeakRefStrings.jl +++ b/src/WeakRefStrings.jl @@ -58,9 +58,16 @@ function Base.cmp(a::WeakRefString{T}, b::WeakRefString{T}) where T return c < 0 ? -1 : c > 0 ? +1 : cmp(al,bl) end -function Base.hash(s::WeakRefString{T}, h::UInt) where {T} - h += Base.memhash_seed - ccall(Base.memhash, UInt, (Ptr{T}, Csize_t, UInt32), s.ptr, s.len, h % UInt32) + h +if isdefined(Base, :memhash) && isdefined(Base, :memhash_seed) + function Base.hash(s::WeakRefString{T}, h::UInt) where {T} + h += Base.memhash_seed + ccall(Base.memhash, UInt, (Ptr{T}, Csize_t, UInt32), s.ptr, s.len, h % UInt32) + h + end +elseif isdefined(Base, :hash_bytes) && isdefined(Base, :HASH_SECRET) + Base.hash(s::WeakRefString{UInt8}, h::UInt) = Base.hash_bytes(s.ptr, s.len, UInt64(h), Base.HASH_SECRET) % UInt + Base.hash(s::WeakRefString, h::UInt) = hash(String(s), h) +else + Base.hash(s::WeakRefString, h::UInt) = hash(String(s), h) end function Base.show(io::IO, x::WeakRefString{T}) where {T} diff --git a/src/poslenstrings.jl b/src/poslenstrings.jl index a8220c0..afc436e 100644 --- a/src/poslenstrings.jl +++ b/src/poslenstrings.jl @@ -94,16 +94,18 @@ function Base.cmp(a::PosLenString, b::PosLenString) return cmp(codeunits(a), codeunits(b)) end -function Base.hash(s::PosLenString, h::UInt) - h += Base.memhash_seed - if !escaped(s) - ccall(Base.memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), pointer(s), len(s), h % UInt32) + h - else - # TODO: this is expensive, even for rare escaped PosLenString - # this makes it about 4x slower than hash(::String) - # alternative is to maybe take what's needed from MurmurHash3.jl to operate by codeunit - x = copy(codeunits(s)) - ccall(Base.memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), pointer(x), sizeof(x), h % UInt32) + h +if isdefined(Base, :memhash) && isdefined(Base, :memhash_seed) + function Base.hash(s::PosLenString, h::UInt) + h += Base.memhash_seed + if !escaped(s) + ccall(Base.memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), pointer(s), len(s), h % UInt32) + h + else + # TODO: this is expensive, even for rare escaped PosLenString + # this makes it about 4x slower than hash(::String) + # alternative is to maybe take what's needed from MurmurHash3.jl to operate by codeunit + x = copy(codeunits(s)) + ccall(Base.memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), pointer(x), sizeof(x), h % UInt32) + h + end end end diff --git a/test/runtests.jl b/test/runtests.jl index abbe0c6..efbc4fe 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -15,6 +15,11 @@ include("poslenstrings.jl") @test str[1] === 'h' @test str[2] === 'e' @test str[3] === 'y' + @test hash(str) isa UInt + @test hash(str, UInt(0x1234)) isa UInt + if !isdefined(Base, :memhash_seed) + @test hash(str, UInt(0x1234)) == hash("hey", UInt(0x1234)) + end io = IOBuffer() show(io, str) @@ -32,6 +37,11 @@ end @test typeof(str) == WeakRefStrings.WeakRefString{UInt16} @test String(str) == "hey" @test str.len == 3 + @test hash(str) isa UInt + @test hash(str, UInt(0x1234)) isa UInt + if !isdefined(Base, :memhash_seed) + @test hash(str, UInt(0x1234)) == hash("hey", UInt(0x1234)) + end end @testset "WeakRefString{UInt32}" begin @@ -42,6 +52,11 @@ end @test typeof(str) == WeakRefStrings.WeakRefString{UInt32} @test String(str) == "hey" @test str.len == 4 + @test hash(str) isa UInt + @test hash(str, UInt(0x1234)) isa UInt + if !isdefined(Base, :memhash_seed) + @test hash(str, UInt(0x1234)) == hash("hey", UInt(0x1234)) + end end @testset "StringVector" begin