Skip to content

Instantly share code, notes, and snippets.

@jbe
Last active August 29, 2015 13:58
Show Gist options
  • Save jbe/10091773 to your computer and use it in GitHub Desktop.
Save jbe/10091773 to your computer and use it in GitHub Desktop.
type
TChunkyNode[IX, T] = tuple
elms: array[IX, T]
next: PChunkyNode[IX, T]
PChunkyNode[IX, T] = ptr TChunkyNode[IX, T]
TChunkyArray*[IX, T] = object
first: PChunkyNode[IX, T]
size: int
template chunk_size*[IX, T](ca: TChunkyArray[IX, T]): int = high(IX) + 1
template len*[IX, T](ca: TChunkyArray[IX, T]): int = ca.size
template is_empty*[IX, T](ca: TChunkyArray[IX, T]): bool = len(ca) == 0
template new_node_for[IX, T](ca: TChunkyArray[IX, T]): PChunkyNode[IX,T] =
cast[PChunkyNode[IX,T]](allocShared(sizeof(TChunkyNode[IX, T])))
template check_init*[IX, T](ca: var TChunkyArray[IX, T]) =
if ca.first.isNil:
ca.first = new_node_for(ca)
proc `[]`*[IX, T](ca: TChunkyArray[IX, T], i: int): T =
if is_empty(ca): raise newException(EInvalidIndex,
"tried to index empty TChunkyArray")
var node = ca.first
for j in 0 .. <(i div chunk_size(ca)):
if node.next.isNil: raise newException(EInvalidIndex,
"index out of bounds: " & $i)
node = node.next
return node.elms[i mod chunk_size(ca)]
proc `[]=`*[IX, T](ca: var TChunkyArray[IX, T], i: int, e: T) =
check_init(ca)
var node = ca.first
for j in 0 .. <(i div chunk_size(ca)):
if node.next.isNil:
node.next = new_node_for(ca)
node = node.next
node.elms[i mod chunk_size(ca)] = e # SEGFAULT OCCURS ON THIS LINE (but in gc.nim:206 (canbeCycleRoot(c)))
if ca.size <= i: ca.size = i + 1
import ChunkyArrays, RedHuntingHat
test("game/ADTs/ChunkyArrays"): # Just ignore these lines
test("with blocks of 16"): # that's my test suite lib
var ca: TChunkyArray[range[0..15], string]
req(is_empty(ca), "is_empty at init") # req is eqivalent to assert
req(len(ca) == 0, "len==0 at init")
ca[0] = "hello"
req(ca[0] == "hello", "insertion and retrieval at index 0")
req(len(ca) == 1, "correct length")
ca[100] = "ugh"
req(ca[100] == "ugh", "insertion and retrieval at index 100")
ca[15] = "ugh"
req(ca[15] == "ugh", "insertion and retrieval at index 15")
ca[16] = "ugh"
req(ca[16] == "ugh", "insertion and retrieval at index 16")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment