Skip to content

Instantly share code, notes, and snippets.

@JeffreySarnoff
Created September 9, 2017 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeffreySarnoff/c9c91c9e99dca962be4592fae9115e2a to your computer and use it in GitHub Desktop.
Save JeffreySarnoff/c9c91c9e99dca962be4592fae9115e2a to your computer and use it in GitHub Desktop.
Nulls as nibble sized bitflag sentinals
#=
proof of concept
multidimensional indicies are not treated
no comparative benchmarking has been done
=#
module NibbleNulls
export notnull, isnull, setnull!, clearnull!,
NibbleVec
const NibbleVec = Vector{UInt8}
function notnull(nibbles::NibbleVec, index::U) where U<:Unsigned
mask = isodd(index) ? 0x0F : 0xF0
index = index >>> one(U)
@inbounds nibble = getindex(nibbles, index)
nibble = nibble & mask
return nibble === zero(UInt8)
end
@inline function notnull(nibbles::NibbleVec, index::S) where S<:Signed
index >= one(S) && return notnull(nibbles, reinterp(Unsigned, index))
exception_as_false("Illegal index value")
end
function isnull(nibbles::NibbleVec, index::U) where U<:Unsigned
mask = isodd(index) ? 0x0F : 0xF0
index = index >>> one(U)
@inbounds nibble = getindex(nibbles, index)
nibble = nibble & mask
return nibble !== zero(UInt8)
end
@inline function isnull(nibbles::NibbleVec, index::S) where S<:Signed
index >= one(S) && return isnull(nibbles, reinterp(Unsigned, index))
exception_as_false("Illegal index value")
end
function setnull!(nibbles::NibbleVec, index::U) where U<:Unsigned
mask = isodd(index) ? 0x01 : 0x10
index = index >>> one(U)
@inbounds begin
nibble = getindex(nibbles, index)
nibble = nibble | mask
setindex!(nibbles, nibble, index)
end
return nothing
end
@inline function setnull!(nibbles::NibbleVec, index::S) where S<:Signed
index >= one(S) && return setnull!(nibbles, reinterp(Unsigned, index))
exception_as_nothing("Illegal index value")
end
function clearnull!(nibbles::NibbleVec, index::U) where U<:Unsigned
mask = isodd(index) ? 0x10 : 0x01
index = index >>> one(U)
@inbounds begin
nibble = getindex(nibbles, index)
nibble = nibble & mask
setindex!(nibbles, nibble, index)
end
return nothing
end
@inline function clearnull!(nibbles::NibbleVec, index::S) where S<:Signed
!signbit(index - one(S)) && return clearnull!(nibbles, reinterp(Unsigned, index))
exception_as_nothing("Illegal index value")
end
reinterp(::Type{Unsigned}, index::Int8) = reinterpret(UInt8, index)
reinterp(::Type{Unsigned}, index::Int16) = reinterpret(UInt16, index)
reinterp(::Type{Unsigned}, index::Int32) = reinterpret(UInt32, index)
reinterp(::Type{Unsigned}, index::Int64) = reinterpret(UInt64, index)
reinterp(::Type{Unsigned}, index::Int128) = reinterpret(UInt128, index)
# somehow exception(str)::nothing
function exception_as_nothing(str::String)
println(string("*Runtime Exception*:", str))
return nothing
end
end # module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment