Wow, I didn’t expect it to be so complicated, getting some datastructures instantiated, that should really be extremely simple. But it turns out, I’m running into error after error… 
So I got some sort of rudimentary hashtable-code up and running, for my chess-engine…
using Formatting
using Printf
import Base: length
import Base.@propagate_inbounds
const fF = generate_formatter("%5.3'f") # format for typical float-output (3-digit-prec after .)
const fD = generate_formatter("%'d") # format for typical decimal-output (with 1000s-sep)
const fH = generate_formatter("0x%016x") # format for typical hex-output
const SI(x) = formatted(x, :SI, ndigits=4) # scientific not. (kilo, mega, ...)
mutable struct HashTable{T}
entries::Vector{T}
size::UInt64
hashKeyMask::UInt64
function HashTable{T}(n::UInt64) where T
@assert checkPow2(n) "Spec-mismatch: size is not a pow of 2 (size= $size)."
en = Vector{T}(undef, n)
new(en,n,n-1)
end
end
function length(ht::HashTable) return ht.size end
function checkPow2(v) return ( (v & (v-1))==0 && v>0 ) end
function hashKey2Index(ht::HashTable, hashkey) return (hashkey & ht.hashKeyMask) + 1 end
@propagate_inbounds function putForced(ht::HashTable{T}, hashkey::UInt64, entry::T) where T
# no checking for collisions - potential overwrite...
ht.entries[ hashKey2Index(ht, hashkey) ] = entry
nothing
end
function get(ht::HashTable{T}, hashkey::UInt64) where T
index = hashKey2Index(ht, hashkey)
@inbounds return ht.entries[index]::T
end
…so far so good…
Then I made a function setupTable(...), which actually creates a (preinitialized) hashtable for me.
(Note: I’ve, for now, fallen back to just using UInt64s as my ht-entries. Just to make stuff simpler and not have another struct in the array, of the mutable struct HashTable…
…also, because I don’t really understand, whether those entries should then be mutable or immutable - I’ve read so much, now, but it still really doesn’t make sense to me, how to change immutable elements.
function setupTable(sizeInBits, default)
tableSize = 1 << sizeInBits
entrySize = sizeof(UInt64)
nEntries = (tableSize ÷ entrySize) % UInt64
table = HashTable{UInt64}(nEntries::UInt64)
for i = 1 : nEntries
# init just with dummy-data, for getting it to work...
putForced(table, i, (default + i)%UInt64)
end
tableSize = nEntries * entrySize
@assert nEntries > 0 "Tablesize to small => 0 elements fit."
printfmt("size of table {1}: {2} elements [{3} bytes @ {4} B/el.]\n"
, SI(tableSize), fD(nEntries), fD(tableSize), fD(entrySize) )
return table
end
…but even with all these simplifications, which are still quite a bit away, from the problem, I tried to understand earlier - I still don’t even get this simple variation to work, when I try to create a bunch of these Hashtables and put them into a StaticArray, to perform some benchmarks and comparisons on them (with different sizes)…
This snippet…
# maxSize: In bits -> 20=1MB, 30=1GB, etc.
function tables1(maxSize, default::UInt64)
tmp = Vector{HashTable{UInt64}}(undef, maxSize)
for i = 12 : maxSize
tmp[i] = setupTable(i, default)
end
# construct SVector, explicitly from the 21 HashTables in tmp
tables = SVector{maxSize, HashTable{UInt64}}(tmp)
return tables
end
…was supposed to produce 21 HashTables for benchmarking, but it yields an error, and I don’t understand, why…
julia> test = tables1(30,0x80000000000)
size of table 4.096k: 512 elements [4,096 bytes @ 8 B/el.]
size of table 8.192k: 1,024 elements [8,192 bytes @ 8 B/el.]
size of table 16.38k: 2,048 elements [16,384 bytes @ 8 B/el.]
size of table 32.77k: 4,096 elements [32,768 bytes @ 8 B/el.]
size of table 65.54k: 8,192 elements [65,536 bytes @ 8 B/el.]
size of table 131.1k: 16,384 elements [131,072 bytes @ 8 B/el.]
size of table 262.1k: 32,768 elements [262,144 bytes @ 8 B/el.]
size of table 524.3k: 65,536 elements [524,288 bytes @ 8 B/el.]
size of table 1.049M: 131,072 elements [1,048,576 bytes @ 8 B/el.]
size of table 2.097M: 262,144 elements [2,097,152 bytes @ 8 B/el.]
size of table 4.194M: 524,288 elements [4,194,304 bytes @ 8 B/el.]
size of table 8.389M: 1,048,576 elements [8,388,608 bytes @ 8 B/el.]
size of table 16.78M: 2,097,152 elements [16,777,216 bytes @ 8 B/el.]
size of table 33.55M: 4,194,304 elements [33,554,432 bytes @ 8 B/el.]
size of table 67.11M: 8,388,608 elements [67,108,864 bytes @ 8 B/el.]
size of table 134.2M: 16,777,216 elements [134,217,728 bytes @ 8 B/el.]
size of table 268.4M: 33,554,432 elements [268,435,456 bytes @ 8 B/el.]
size of table 536.9M: 67,108,864 elements [536,870,912 bytes @ 8 B/el.]
size of table 1.074G: 134,217,728 elements [1,073,741,824 bytes @ 8 B/el.]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[1] getindex
@ .\array.jl:924 [inlined]
[2] macro expansion
@ C:\Users\rober\.julia\packages\StaticArrays\PUoe1\src\convert.jl:212 [inlined]
[3] unroll_tuple
@ C:\Users\rober\.julia\packages\StaticArrays\PUoe1\src\convert.jl:207 [inlined]
[4] convert
@ C:\Users\rober\.julia\packages\StaticArrays\PUoe1\src\convert.jl:199 [inlined]
[5] SVector{30, Vector{HashTable{UInt64}}}(a::Vector{HashTable{UInt64}})
@ StaticArrays C:\Users\rober\.julia\packages\StaticArrays\PUoe1\src\convert.jl:169
[6] tables1(maxSize::Int64, default::UInt64)
@ Main .\Untitled-2:58
[7] top-level scope
…creation of the ht is effortless, even at large sizes, but I don’t understand, what kind of undefined reference the static array is complaining about?
The constructor-signature seems to match, what I’ve found, elsewhere, in a (toy-) example?
v2 = SVector{3,Float64}(1, 2, 3) # length 3, eltype Float64
Since it didn’t work, I also tried this macro-variant of creating a SVector, like this…
function tables2(maxSize, default::UInt64)
# try with a macro
tables = @SVector [ setupTable(i, default) for i = 10 : maxSize ]
return tables
end
…which gives me a compile-time-error:
ERROR: LoadError: UndefVarError: maxSize not defined
Stacktrace:
[1] top-level scope
@ none:1
in expression starting at Untitled-2:64
Interpolating maxSize with a $ then gives this error…
ERROR: LoadError: syntax: "$" expression outside quote
Stacktrace:
[1] top-level scope
@ none:1
in expression starting at Untitled-2:64


Edit: Admittely, I’ve resorted to guessing, only, now - but I feel like I have no clue, what is going on - when all I wanted, was to allocated some simple block of memory, for some extremely simple array of primitive data-types. 