summary refs log tree commit diff stats
path: root/lib/ptrset.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ptrset.nim')
-rw-r--r--lib/ptrset.nim205
1 files changed, 0 insertions, 205 deletions
diff --git a/lib/ptrset.nim b/lib/ptrset.nim
deleted file mode 100644
index 95f01b16f..000000000
--- a/lib/ptrset.nim
+++ /dev/null
@@ -1,205 +0,0 @@
-# This implements a new pointer set. Access time O(1). For 32 bit systems, we
-# currently need 3 memory accesses. 
-
-const
-  PageSize = 1024 * sizeof(int)
-  MemAlignment = 8 # minimal memory block that can be allocated
-  BitsPerUnit = sizeof(int)*8 
-    # a "unit" is a word, i.e. 4 bytes
-    # on a 32 bit system; I do not use the term "word" because under 32-bit
-    # Windows it is sometimes only 16 bits
-
-  BitsPerPage = PageSize div MemAlignment
-  UnitsPerPage = BitsPerPage div BitsPerUnit
-    # how many units do we need to describe a page:
-    # on 32 bit systems this is only 16 (!)
-
-type
-  PPointer = ptr pointer
-
-  TCollectorData = int
-  TCell {.final.} = object
-    refcount: TCollectorData  # the refcount and bit flags
-    typ: PNimType                  
-    stackcount: int           # stack counter for debugging
-    drefc: int                # real reference counter for debugging
-
-  PCell = ptr TCell
-
-proc cellToUsr(cell: PCell): pointer {.inline.} =
-  # convert object (=pointer to refcount) to pointer to userdata
-  result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell)))
-
-proc usrToCell(usr: pointer): PCell {.inline.} =
-  # convert pointer to userdata to object (=pointer to refcount)
-  result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell)))
-
-proc gcAlloc(size: int): pointer =
-  result = alloc0(size)
-  if result == nil: raiseOutOfMem() 
-
-# ------------------ Zero count table (ZCT) and any table (AT) -------------
-
-# this that has to equals zero, otherwise we have to round up UnitsPerPage:
-when BitsPerPage mod BitsPerUnit != 0:
-  {.error: "(BitsPerPage mod BitsPerUnit) should be zero!".}
-
-# ------------------- cell set handling ------------------------------
-# A cellset consists of a hash table of page descriptors. A page
-# descriptor has a bit for
-# every Memalignment'th byte in the page.
-# However, only bits corresponding to addresses that start memory blocks
-# are set.
-# Page descriptors are also linked to a list; the list
-# is used for easy traversing of all page descriptors; this allows a
-# fast iterator.
-# We use a specialized hashing scheme; the formula is :
-# hash = Page bitand max
-# We use linear probing with the formular: (5*h)+1
-# Thus we likely get no collisions at all if the pages are given to us
-# in a sequential manner by the operating system!
-const
-  bitsPerNode = 10 # we use 10 bits per node; this means 3 memory accesses on
-                   # 32 bit systems
-
-type
-  PPageDesc = ptr TPageDesc
-
-  TBitIndex = range[0..UnitsPerPage-1]
-
-  TPageDesc {.final.} = object
-    next: PPageDesc # all nodes are connected with this pointer
-    key: TAddress   # start address at bit 0
-    bits: array[TBitIndex, int] # a bit vector
-
-  PPageDescArray = ptr array[0..1000_000, PPageDesc]
-  TCellSet {.final.} = object
-    counter, max: int
-    head: PPageDesc
-    data: PPageDescArray
-    
-  TSetNode {.final.} = object
-    n: array[0.. (1 shl bitsPerNode)-1, PSetNode]
-  PSetNode = ptr TSetNode
-
-const
-  InitCellSetSize = 1024 # must be a power of two!
-
-proc CellSetInit(s: var TCellSet) =
-  s.data = gcAlloc(InitCellSetSize * sizeof(PPageDesc))
-  s.max = InitCellSetSize-1
-  s.counter = 0
-  s.head = nil
-
-proc CellSetDeinit(s: var TCellSet) =
-  var it = s.head
-  while it != nil:
-    var n = it.next
-    dealloc(it)
-    it = n
-  s.head = nil # play it safe here
-  dealloc(s.data)
-  s.data = nil
-  s.counter = 0
-
-proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc =
-  var h = cast[int](key) and t.max
-  while t.data[h] != nil:
-    if t.data[h].key == key: return t.data[h]
-    h = nextTry(h, t.max)
-  return nil
-
-proc CellSetRawInsert(t: TCellSet, data: PPageDescArray,
-                      desc: PPageDesc) =
-  var h = cast[int](desc.key) and t.max
-  while data[h] != nil:
-    assert(data[h] != desc)
-    h = nextTry(h, t.max)
-  assert(data[h] == nil)
-  data[h] = desc
-
-proc CellSetEnlarge(t: var TCellSet) =
-  var
-    n: PPageDescArray
-    oldMax = t.max
-  t.max = ((t.max+1)*2)-1
-  n = gcAlloc((t.max + 1) * sizeof(PPageDesc))
-  for i in 0 .. oldmax:
-    if t.data[i] != nil:
-      CellSetRawInsert(t, n, t.data[i])
-  dealloc(t.data)
-  t.data = n
-
-proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
-  var h = cast[int](key) and t.max
-  while true:
-    var x = t.data[h]
-    if x == nil: break
-    if x.key == key: return x
-    h = nextTry(h, t.max)
-
-  if (t.max+1) * 2 < t.counter * 3: CellSetEnlarge(t)
-  inc(t.counter)
-  h = cast[int](key) and t.max
-  while t.data[h] != nil: h = nextTry(h, t.max)
-  assert(t.data[h] == nil)
-  # the new page descriptor goes into result
-  result = gcAlloc(sizeof(TPageDesc))
-  result.next = t.head
-  result.key = key
-  t.head = result
-  t.data[h] = result
-
-# ---------- slightly higher level procs ----------------------------------
-
-proc in_Operator(s: TCellSet, cell: PCell): bool =
-  var
-    u: TAddress
-    t: PPageDesc
-  u = cast[TAddress](cell)
-  t = CellSetGet(s, u /% PageSize)
-  if t != nil:
-    u = (u %% PageSize) /% MemAlignment
-    result = (t.bits[u /% BitsPerUnit] and (1 shl (u %% BitsPerUnit))) != 0
-  else:
-    result = false
-
-proc incl(s: var TCellSet, cell: PCell) =
-  var
-    u: TAddress
-    t: PPageDesc
-  u = cast[TAddress](cell)
-  t = CellSetPut(s, u /% PageSize)
-  u = (u %% PageSize) /% MemAlignment
-  t.bits[u /% BitsPerUnit] = t.bits[u /% BitsPerUnit] or 
-    (1 shl (u %% BitsPerUnit))
-
-proc excl(s: var TCellSet, cell: PCell) =
-  var
-    u: TAddress
-    t: PPageDesc
-  u = cast[TAddress](cell)
-  t = CellSetGet(s, u /% PageSize)
-  if t != nil:
-    u = (u %% PageSize) /% MemAlignment
-    t.bits[u %% BitsPerUnit] = (t.bits[u /% BitsPerUnit] and
-                                  not (1 shl (u %% BitsPerUnit)))
-
-iterator elements(t: TCellSet): PCell {.inline.} =
-  # while traversing it is forbidden to add pointers to the tree!
-  var r = t.head
-  while r != nil:
-    var i = 0
-    while i <= high(r.bits):
-      var w = r.bits[i] # taking a copy of r.bits[i] here is correct, because
-      # modifying operations are not allowed during traversation
-      var j = 0
-      while w != 0:         # test all remaining bits for zero
-        if (w and 1) != 0:  # the bit is set!
-          yield cast[PCell]((r.key *% PageSize) +%
-                              (i*%BitsPerUnit+%j) *% MemAlignment)
-        inc(j)
-        w = w shr 1
-      inc(i)
-    r = r.next
-