Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 4.39 KB | None | 0 0
  1. import ../cseries/cseries
  2.  
  3. const
  4.     DATA_SIGNATURE = Tag(0x40744064)
  5.     DATA_ITERATOR_SIGNATURE = Tag(0x72657469)
  6.  
  7. type
  8.     DatumIndex* = distinct uint32
  9.  
  10. proc `index`*(self: DatumIndex): uint16 =
  11.     cast[uint16](cast[uint32](self) and 0xFFFF)
  12.  
  13. proc `salt`*(index: DatumIndex): uint16 =
  14.     cast[uint16]((cast[uint32](index) shr 16) and 0xFFFF)
  15.  
  16. proc `index=`*(self: var DatumIndex, value: uint16) =
  17.     self = cast[DatumIndex](cast[uint32](value) or (cast[uint32](self.salt) shl 16))
  18.  
  19. proc `salt=`*(self: var DatumIndex, value: uint16) =
  20.     self = cast[DatumIndex](cast[uint32](self.index) or (cast[uint32](value) shl 16))
  21.  
  22. type
  23.     Datum* {.inheritable.} = object
  24.         salt*: uint16
  25.    
  26.     DataAlignment* {.pure.} = enum
  27.         Byte,
  28.         Word,
  29.         DWord,
  30.         QWord
  31.  
  32.     DataArray*[T] = object
  33.         name*: TagString
  34.         capacity*: uint16
  35.         valid*: bool
  36.         threaded*: bool
  37.         signature*: Tag
  38.         nextIndex*: uint16
  39.         lastDatum*: uint16
  40.         nextDatum*: DatumIndex
  41.         baseAddress*: ptr Datum
  42.  
  43. proc `[]`*[T: Datum](self: ptr DataArray[T], index: uint16): ptr T =
  44.     result = cast[ptr T](cast[int](self.baseAddress) + (cast[int](index) * sizeof(T)))
  45.  
  46. proc `[]`*[T: Datum](self: ptr DataArray[T], index: DatumIndex): ptr T =
  47.     result = self[index.index]
  48.     assert(result.salt == index.salt)
  49.  
  50. iterator items*[T: Datum](data: ptr DataArray[T]): ptr T {.inline.} =
  51.     assert(not data.isNil)
  52.     assert(data.valid)
  53.     var i = 0
  54.     while true:
  55.         let datum = data[i]
  56.         if datum.salt != 0:
  57.             yield datum
  58.         inc(i)
  59.  
  60. proc allocData*[T: Datum](name: cstring, capacity: int, threaded: bool): ptr DataArray[T] =
  61.     let
  62.         size = sizeof(DataArray[T]) + (capacity * sizeof(T))
  63.         address = if threaded:
  64.             allocShared0(size)
  65.         else:
  66.             alloc0(size)
  67.     result = cast[ptr DataArray[T]](address)
  68.     assert(not result.isNil)
  69.     assert(not name.isNil)
  70.     assert(capacity > 0)
  71.     for i in 0..<name.len:
  72.         result.name[i] = name[i]
  73.     result.capacity = cast[uint16](capacity)
  74.     result.signature = DATA_SIGNATURE
  75.     result.valid = false
  76.     result.threaded = threaded
  77.     result.baseAddress = cast[ptr Datum](cast[int](result) + sizeof(DataArray[T]))
  78.  
  79. proc deallocData*[T: Datum](data: ptr DataArray[T]) =
  80.     assert(not data.isNil)
  81.     if data.threaded:
  82.         deallocShared(data)
  83.     else:
  84.         dealloc(data)
  85.  
  86. proc allocDatum*[T: Datum](data: ptr DataArray[T]): DatumIndex =
  87.     assert(not data.isNil)
  88.     assert(data.valid)
  89.     var
  90.         nextIndex = data.nextIndex
  91.         datum = data[nextIndex]
  92.     if nextIndex >= data.capacity:
  93.         return cast[DatumIndex](NONE)
  94.     while datum.salt != 0:
  95.         inc(nextIndex)
  96.         datum = data[nextIndex]
  97.         if nextIndex >= data.capacity:
  98.             return cast[DatumIndex](NONE)
  99.     data.nextDatum.salt = data.nextDatum.salt + 1
  100.     datum.salt = data.nextDatum.salt
  101.     if data.nextDatum.salt == 0:
  102.         data.nextDatum.salt = cast[uint16](0x8000)
  103.     data.nextDatum.index = data.nextDatum.index + 1
  104.     if data.lastDatum == nextIndex or data.lastDatum < nextIndex:
  105.         data.lastDatum = nextIndex + 1
  106.     result = cast[DatumIndex](cast[uint32](nextIndex) or (cast[uint32](datum.salt) shl 16))
  107.  
  108. proc deallocDatum*[T: Datum](data: ptr DataArray[T], index: DatumIndex) =
  109.     assert(not data.isNil)
  110.     var
  111.         datum = data[index]
  112.     datum.salt = 0
  113.     if index.index < data.nextIndex:
  114.         data.nextIndex = index.index
  115.     if data.lastDatum == index.index + 1:
  116.         while datum.salt == 0 and cast[int](data.lastDatum) - 1 > 0:
  117.             dec data.lastDatum
  118.             datum = data[data.lastDatum]
  119.     data.nextDatum.index = data.nextDatum.index - 1
  120.  
  121. proc deallocAllDatums*[T: Datum](data: ptr DataArray[T]) =
  122.     assert(not data.isNil)
  123.     assert(data.valid)
  124.     data.lastDatum = 0
  125.     data.nextIndex = 0
  126.     data.nextDatum.index = 0
  127.     data.nextDatum.salt = data.nextDatum.salt or cast[uint16](0x8000)
  128.     for i in 0 ..< cast[int](data.capacity):
  129.         var datum = data[cast[uint16](i)]
  130.         datum.salt = 0
  131.  
  132. proc makeDataValid*[T: Datum](data: ptr DataArray[T]) =
  133.     assert(not data.isNil)
  134.     data.valid = true
  135.     data.deallocAllDatums()
  136.  
  137. proc makeDataInvalid*[T: Datum](data: ptr DataArray[T]) =
  138.     assert(not data.isNil)
  139.     data.valid = false
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement