Skip to content

Instantly share code, notes, and snippets.

@camden-smallwood-zz
Created March 24, 2019 02:10
Show Gist options
  • Save camden-smallwood-zz/e0a3aaf5ce228711e97d0fdd0975cd92 to your computer and use it in GitHub Desktop.
Save camden-smallwood-zz/e0a3aaf5ce228711e97d0fdd0975cd92 to your computer and use it in GitHub Desktop.
import ../cseries/cseries
const
DATA_SIGNATURE = Tag(0x40744064)
DATA_ITERATOR_SIGNATURE = Tag(0x72657469)
type
DatumIndex* = distinct uint32
proc `index`*(self: DatumIndex): uint16 =
cast[uint16](cast[uint32](self) and 0xFFFF)
proc `salt`*(index: DatumIndex): uint16 =
cast[uint16]((cast[uint32](index) shr 16) and 0xFFFF)
proc `index=`*(self: var DatumIndex, value: uint16) =
self = cast[DatumIndex](cast[uint32](value) or (cast[uint32](self.salt) shl 16))
proc `salt=`*(self: var DatumIndex, value: uint16) =
self = cast[DatumIndex](cast[uint32](self.index) or (cast[uint32](value) shl 16))
type
Datum* {.inheritable.} = object
salt*: uint16
DataAlignment* {.pure.} = enum
Byte,
Word,
DWord,
QWord
DataArray*[T] = object
name*: TagString
capacity*: uint16
valid*: bool
threaded*: bool
signature*: Tag
nextIndex*: uint16
lastDatum*: uint16
nextDatum*: DatumIndex
baseAddress*: ptr Datum
proc `[]`*[T: Datum](self: ptr DataArray[T], index: uint16): ptr T =
result = cast[ptr T](cast[int](self.baseAddress) + (cast[int](index) * sizeof(T)))
proc `[]`*[T: Datum](self: ptr DataArray[T], index: DatumIndex): ptr T =
result = self[index.index]
assert(result.salt == index.salt)
iterator items*[T: Datum](data: ptr DataArray[T]): ptr T {.inline.} =
assert(not data.isNil)
assert(data.valid)
var i = 0
while true:
let datum = data[i]
if datum.salt != 0:
yield datum
inc(i)
proc allocData*[T: Datum](name: cstring, capacity: int, threaded: bool): ptr DataArray[T] =
let
size = sizeof(DataArray[T]) + (capacity * sizeof(T))
address = if threaded:
allocShared0(size)
else:
alloc0(size)
result = cast[ptr DataArray[T]](address)
assert(not result.isNil)
assert(not name.isNil)
assert(capacity > 0)
for i in 0..<name.len:
result.name[i] = name[i]
result.capacity = cast[uint16](capacity)
result.signature = DATA_SIGNATURE
result.valid = false
result.threaded = threaded
result.baseAddress = cast[ptr Datum](cast[int](result) + sizeof(DataArray[T]))
proc deallocData*[T: Datum](data: ptr DataArray[T]) =
assert(not data.isNil)
if data.threaded:
deallocShared(data)
else:
dealloc(data)
proc allocDatum*[T: Datum](data: ptr DataArray[T]): DatumIndex =
assert(not data.isNil)
assert(data.valid)
var
nextIndex = data.nextIndex
datum = data[nextIndex]
if nextIndex >= data.capacity:
return cast[DatumIndex](NONE)
while datum.salt != 0:
inc(nextIndex)
datum = data[nextIndex]
if nextIndex >= data.capacity:
return cast[DatumIndex](NONE)
data.nextDatum.salt = data.nextDatum.salt + 1
datum.salt = data.nextDatum.salt
if data.nextDatum.salt == 0:
data.nextDatum.salt = cast[uint16](0x8000)
data.nextDatum.index = data.nextDatum.index + 1
if data.lastDatum == nextIndex or data.lastDatum < nextIndex:
data.lastDatum = nextIndex + 1
result = cast[DatumIndex](cast[uint32](nextIndex) or (cast[uint32](datum.salt) shl 16))
proc deallocDatum*[T: Datum](data: ptr DataArray[T], index: DatumIndex) =
assert(not data.isNil)
var
datum = data[index]
datum.salt = 0
if index.index < data.nextIndex:
data.nextIndex = index.index
if data.lastDatum == index.index + 1:
while datum.salt == 0 and cast[int](data.lastDatum) - 1 > 0:
dec data.lastDatum
datum = data[data.lastDatum]
data.nextDatum.index = data.nextDatum.index - 1
proc deallocAllDatums*[T: Datum](data: ptr DataArray[T]) =
assert(not data.isNil)
assert(data.valid)
data.lastDatum = 0
data.nextIndex = 0
data.nextDatum.index = 0
data.nextDatum.salt = data.nextDatum.salt or cast[uint16](0x8000)
for i in 0 ..< cast[int](data.capacity):
var datum = data[cast[uint16](i)]
datum.salt = 0
proc makeDataValid*[T: Datum](data: ptr DataArray[T]) =
assert(not data.isNil)
data.valid = true
data.deallocAllDatums()
proc makeDataInvalid*[T: Datum](data: ptr DataArray[T]) =
assert(not data.isNil)
data.valid = false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment