Ejemplo n.º 1
0
Archivo: set.py Proyecto: pmem/pynvm
    def _add(self, key):
        mm = self._p_mm
        khash = fixed_hash(key)
        result = ADD_RESULT_RESTART
        with mm.transaction():
            while result == ADD_RESULT_RESTART:
                index, result = self._get_available_entry_slot(key, khash)
            if result == ADD_RESULT_FOUND_UNUSED or \
               result == ADD_RESULT_FOUND_DUMMY:
                table_data = ffi.cast('PSetEntry *',
                                      mm.direct(self._body.table))
                mm.snapshot_range(ffi.addressof(table_data, index),
                                  ffi.sizeof('PSetEntry'))
                oid = mm.persist(key)
                mm.incref(oid)
                p_obj = ffi.cast('PObject *', mm.direct(oid))
                table_data[index].key = oid
                table_data[index].hash = khash
                mm.snapshot_range(
                    ffi.addressof(self._body, 'fill'),
                    ffi.sizeof('PSetObject') - ffi.sizeof('PObject'))
                self._body.used += 1

                if result == ADD_RESULT_FOUND_UNUSED:
                    self._body.fill += 1
                    if self._body.fill * 3 >= self._body.mask * 2:
                        self._table_resize(self._body.used)
Ejemplo n.º 2
0
Archivo: set.py Proyecto: pdeng6/pynvm
    def _add(self, key):
        mm = self._p_mm
        khash = fixed_hash(key)
        result = ADD_RESULT_RESTART
        with mm.transaction():
            while result == ADD_RESULT_RESTART:
                index, result = self._get_available_entry_slot(key, khash)
            if result == ADD_RESULT_FOUND_UNUSED or \
               result == ADD_RESULT_FOUND_DUMMY:
                table_data = ffi.cast('PSetEntry *',
                                      mm.direct(self._body.table))
                mm.snapshot_range(ffi.addressof(table_data, index),
                                  ffi.sizeof('PSetEntry'))
                oid = mm.persist(key)
                mm.incref(oid)
                p_obj = ffi.cast('PObject *', mm.direct(oid))
                table_data[index].key = oid
                table_data[index].hash = khash
                mm.snapshot_range(
                    ffi.addressof(self._body, 'fill'),
                    ffi.sizeof('PSetObject') - ffi.sizeof('PObject'))
                self._body.used += 1

                if result == ADD_RESULT_FOUND_UNUSED:
                    self._body.fill += 1
                    if self._body.fill * 3 >= self._body.mask * 2:
                        self._table_resize(self._body.used)
Ejemplo n.º 3
0
Archivo: dict.py Proyecto: pdeng6/pynvm
 def _insertion_resize(self):
     # This is modeled on CPython's insertion_resize/dictresize, but
     # assuming we always have a combined dict.  We copy the keys and values
     # into a new dict structure and free the old one.  We don't touch the
     # refcounts.
     mm = self._p_mm
     minused = self._growth_rate()
     newsize = MIN_SIZE_COMBINED
     while newsize <= minused and newsize > 0:
         newsize = newsize << 1
     oldkeys = self._keys
     oldkeys_oid = mm.otuple(self._body.ma_keys)
     with mm.transaction():
         mm.snapshot_range(ffi.addressof(self._body, 'ma_keys'),
                           ffi.sizeof('PObjPtr'))
         self._body.ma_keys = self._new_keys_object(newsize)
         oldsize = oldkeys.dk_size
         old_ep0 = ffi.cast('PDictKeyEntry *',
                            ffi.addressof(oldkeys.dk_entries[0]))
         for i in range(oldsize):
             old_ep = old_ep0[i]
             me_value = mm.otuple(old_ep.me_value)
             if me_value != mm.OID_NULL:
                 me_key = mm.otuple(old_ep.me_key)
                 assert me_key != DUMMY
                 me_hash = old_ep.me_hash
                 new_ep = self._find_empty_slot(me_key, me_hash)
                 new_ep.me_key = me_key
                 new_ep.me_hash = me_hash
                 new_ep.me_value = me_value
         self._keys.dk_usable -= self._body.ma_used
         mm.free(oldkeys_oid)
Ejemplo n.º 4
0
Archivo: dict.py Proyecto: pdeng6/pynvm
 def _find_empty_slot(self, key, khash):
     # Find slot from hash when key is not in dict.
     mm = self._p_mm
     keys = self._keys
     mask = keys.dk_size - 1
     ep0 = ffi.cast('PDictKeyEntry *', ffi.addressof(keys.dk_entries[0]))
     i = khash & mask
     ep = ffi.addressof(ep0[i])
     perturb = khash
     while mm.otuple(ep.me_key) != mm.OID_NULL:
         i = (i << 2) + i + perturb + 1
         ep = ep0[i & mask]
         perturb = perturb >> PERTURB_SHIFT
     assert mm.otuple(ep.me_key) == mm.OID_NULL
     return ep
Ejemplo n.º 5
0
 def _resize(self, newsize):
     # Note that resize does *not* set self._size.  That needs to be done by
     # the caller such that that the we never expose invalid item cells.
     # The size field is covered by a snapshot done here, though.
     mm = self._p_mm
     allocated = self._allocated
     # Only realloc if we don't have enough space already.
     if (allocated >= newsize and newsize >= allocated >> 1):
         assert self._items != None or newsize == 0
         with mm.transaction():
             ob = ffi.cast('PVarObject *', self._body)
             mm.snapshot_range(ffi.addressof(ob, 'ob_size'),
                               ffi.sizeof('size_t'))
             ob.ob_size = newsize
         return
     # We use CPython's overallocation algorithm.
     new_allocated = (newsize >> 3) + (3 if newsize < 9 else 6) + newsize
     if newsize == 0:
         new_allocated = 0
     items = self._items
     with mm.transaction():
         if items is None:
             items = mm.zalloc(new_allocated * ffi.sizeof('PObjPtr'),
                               type_num=LIST_POBJPTR_ARRAY_TYPE_NUM)
         else:
             items = mm.zrealloc(self._body.ob_items,
                                 new_allocated * ffi.sizeof('PObjPtr'),
                                 LIST_POBJPTR_ARRAY_TYPE_NUM)
         mm.snapshot_range(self._body, ffi.sizeof('PListObject'))
         self._body.ob_items = items
         self._body.allocated = new_allocated
Ejemplo n.º 6
0
 def _resize(self, newsize):
     mm = self.__manager__
     allocated = self._allocated
     # Only realloc if we don't have enough space already.
     if (allocated >= newsize and newsize >= allocated >> 1):
         assert self._items != None or newsize == 0
         with mm.transaction():
             ob = ffi.cast('PVarObject *', self._body)
             mm.snapshot_range(ffi.addressof(ob, 'ob_size'),
                               ffi.sizeof('size_t'))
             ob.ob_size = newsize
         return
     # We use CPython's overallocation algorithm.
     new_allocated = (newsize >> 3) + (3 if newsize < 9 else 6) + newsize
     if newsize == 0:
         new_allocated = 0
     items = self._items
     with mm.transaction():
         if items is None:
             items = mm.malloc(new_allocated * ffi.sizeof('PObjPtr'),
                               type_num=LIST_POBJPTR_ARRAY_TYPE_NUM)
         else:
             items = mm.realloc(self._body.ob_items,
                                new_allocated * ffi.sizeof('PObjPtr'),
                                LIST_POBJPTR_ARRAY_TYPE_NUM)
         mm.snapshot_range(self._body, ffi.sizeof('PListObject'))
         self._body.ob_items = items
         self._body.allocated = new_allocated
         ffi.cast('PVarObject *', self._body).ob_size = newsize
Ejemplo n.º 7
0
Archivo: set.py Proyecto: pmem/pynvm
    def _insert_clean(self, table, mask, key_oid, khash):
        mm = self._p_mm
        perturb = khash
        i = khash & mask
        table_data = ffi.cast('PSetEntry *', mm.direct(table))
        found_index = -1

        while True:
            if table_data[i].hash == HASH_UNUSED:
                found_index = i
                break

            for j in range(i + 1, min(i + LINEAR_PROBES, mask) + 1):
                if table_data[j].hash == HASH_UNUSED:
                    found_index = j
                    break

            if found_index != -1:
                break

            perturb >>= PERTURB_SHIFT
            i = (i * 5 + 1 + perturb) & mask

        with mm.transaction():
            mm.snapshot_range(ffi.addressof(table_data, found_index),
                              ffi.sizeof('PSetEntry'))
            table_data[found_index].hash = khash
            table_data[found_index].key = key_oid
Ejemplo n.º 8
0
Archivo: list.py Proyecto: pmem/pynvm
 def _resize(self, newsize):
     # Note that resize does *not* set self._size.  That needs to be done by
     # the caller such that that the we never expose invalid item cells.
     # The size field is covered by a snapshot done here, though.
     mm = self._p_mm
     allocated = self._allocated
     # Only realloc if we don't have enough space already.
     if (allocated >= newsize and newsize >= allocated >> 1):
         assert self._items != None or newsize == 0
         with mm.transaction():
             ob = ffi.cast('PVarObject *', self._body)
             mm.snapshot_range(ffi.addressof(ob, 'ob_size'),
                               ffi.sizeof('size_t'))
             ob.ob_size = newsize
         return
     # We use CPython's overallocation algorithm.
     new_allocated = (newsize >> 3) + (3 if newsize < 9 else 6) + newsize
     if newsize == 0:
         new_allocated = 0
     items = self._items
     with mm.transaction():
         if items is None:
             items = mm.zalloc(new_allocated * ffi.sizeof('PObjPtr'),
                               type_num=LIST_POBJPTR_ARRAY_TYPE_NUM)
         else:
             items = mm.zrealloc(self._body.ob_items,
                                new_allocated * ffi.sizeof('PObjPtr'),
                                LIST_POBJPTR_ARRAY_TYPE_NUM)
         mm.snapshot_range(self._body, ffi.sizeof('PListObject'))
         self._body.ob_items = items
         self._body.allocated = new_allocated
Ejemplo n.º 9
0
Archivo: set.py Proyecto: pdeng6/pynvm
    def _insert_clean(self, table, mask, key_oid, khash):
        mm = self._p_mm
        perturb = khash
        i = khash & mask
        table_data = ffi.cast('PSetEntry *', mm.direct(table))
        found_index = -1

        while True:
            if table_data[i].hash == HASH_UNUSED:
                found_index = i
                break

            for j in range(i + 1, min(i + LINEAR_PROBES, mask) + 1):
                if table_data[j].hash == HASH_UNUSED:
                    found_index = j
                    break

            if found_index != -1:
                break

            perturb >>= PERTURB_SHIFT
            i = (i * 5 + 1 + perturb) & mask

        with mm.transaction():
            mm.snapshot_range(ffi.addressof(table_data, found_index),
                              ffi.sizeof('PSetEntry'))
            table_data[found_index].hash = khash
            table_data[found_index].key = key_oid
Ejemplo n.º 10
0
Archivo: dict.py Proyecto: pdeng6/pynvm
 def _free_keys_object(self, oid):
     mm = self._p_mm
     dk = ffi.cast('PDictKeysObject *', mm.direct(oid))
     ep = ffi.cast('PDictKeyEntry *', ffi.addressof(dk.dk_entries[0]))
     with mm.transaction():
         for i in range(dk.dk_size):
             mm.xdecref(ep[i].me_key)
             mm.xdecref(ep[i].me_value)
         mm.free(oid)
Ejemplo n.º 11
0
Archivo: pool.py Proyecto: pdeng6/pynvm
 def root(self, value):
     log.debug("setting 'root' to %r (discarding %s)", value, self.root)
     with self.mm.transaction(), self.lock:
         oid = self.mm.persist(value)
         self.mm.snapshot_range(ffi.addressof(self._pmem_root.root_object),
                                ffi.sizeof('PObjPtr'))
         self.mm.xdecref(self._pmem_root.root_object)
         self._pmem_root.root_object = oid
         self.mm.incref(oid)
Ejemplo n.º 12
0
Archivo: dict.py Proyecto: pdeng6/pynvm
 def _lookdict(self, key, khash):
     # Generalized key lookup method.
     mm = self._p_mm
     while True:
         keys_oid = mm.otuple(self._body.ma_keys)
         keys = ffi.cast('PDictKeysObject *', mm.direct(keys_oid))
         mask = keys.dk_size - 1
         ep0 = ffi.cast('PDictKeyEntry *', ffi.addressof(keys.dk_entries[0]))
         i = khash & mask
         ep = ffi.addressof(ep0[i])
         me_key = mm.otuple(ep.me_key)
         if me_key == mm.OID_NULL:
             return ep
         if me_key == DUMMY:
             freeslot = ep
         else:
             if ep.me_hash == khash:
                 match = mm.resurrect(me_key) == key  # dict could mutate
                 if (mm.otuple(self._body.ma_keys) == keys_oid
                         and mm.otuple(ep.me_key) == me_key):
                     if match:
                         return ep
                 else:
                     continue  # mutatation, start over from the top.
             freeslot = None
         perturb = khash
         while True:
             i = (i << 2) + i + perturb + 1
             ep = ep0[i & mask]
             me_key = mm.otuple(ep.me_key)
             if me_key == mm.OID_NULL:
                 return ep if freeslot is None else freeslot
             if ep.me_hash == khash and me_key != DUMMY:
                 match = mm.resurrect(me_key) == key  # dict could mutate
                 if (mm.otuple(self._body.ma_keys) == keys_oid
                         and mm.otuple(ep.me_key) == me_key):
                     if match:
                         return ep
                 else:
                     break  # mutation, start over from the top.
             elif me_key == DUMMY and freeslot is None:
                 freeslot = ep
             perturb = perturb >> PERTURB_SHIFT
Ejemplo n.º 13
0
Archivo: dict.py Proyecto: pdeng6/pynvm
 def __iter__(self):
     mm = self._p_mm
     keys = self._keys
     ep0 = ffi.cast('PDictKeyEntry *', ffi.addressof(keys.dk_entries[0]))
     for i in range(keys.dk_size):
         ep = ep0[i]
         if (ep.me_hash == ffi.NULL
                 or mm.otuple(ep.me_key) in (mm.OID_NULL, DUMMY)):
             continue
         yield mm.resurrect(ep.me_key)
Ejemplo n.º 14
0
Archivo: pool.py Proyecto: pmem/pynvm
 def root(self, value):
     log.debug("setting 'root' to %r (discarding %s)", value, self.root)
     with self.mm.transaction(), self.lock:
         oid = self.mm.persist(value)
         self.mm.snapshot_range(
             ffi.addressof(self._pmem_root.root_object),
             ffi.sizeof('PObjPtr'))
         self.mm.xdecref(self._pmem_root.root_object)
         self._pmem_root.root_object = oid
         self.mm.incref(oid)
Ejemplo n.º 15
0
Archivo: dict.py Proyecto: pdeng6/pynvm
 def _dumpdict(self):
     # This is for debugging.
     mm = self._p_mm
     keys = self._keys
     ep0 = ffi.cast('PDictKeyEntry *', ffi.addressof(keys.dk_entries[0]))
     log.debug('size: %s', keys.dk_size)
     for i in range(keys.dk_size):
         ep = ep0[i]
         log.debug('hash: %s, key oid: %s, value oid: %s',
                 ep.me_hash, mm.otuple(ep.me_key), mm.otuple(ep.me_value))
Ejemplo n.º 16
0
 def __setitem__(self, index, value):
     mm = self._p_mm
     index = self._normalize_index(index)
     items = self._items
     with mm.transaction():
         v_oid = mm.persist(value)
         mm.snapshot_range(ffi.addressof(items, index),
                           ffi.sizeof('PObjPtr *'))
         mm.xdecref(items[index])
         items[index] = v_oid
         mm.incref(v_oid)
Ejemplo n.º 17
0
Archivo: list.py Proyecto: pmem/pynvm
 def __setitem__(self, index, value):
     mm = self._p_mm
     index = self._normalize_index(index)
     items = self._items
     with mm.transaction():
         v_oid = mm.persist(value)
         mm.snapshot_range(ffi.addressof(items, index),
                           ffi.sizeof('PObjPtr *'))
         mm.xdecref(items[index])
         items[index] = v_oid
         mm.incref(v_oid)
Ejemplo n.º 18
0
 def incref(self, oid):
     """Increment the reference count of oid."""
     oid = self.otuple(oid)
     if oid == OID_NULL:
         # Unlike CPython, we don't ref-track our constants.
         return
     p_obj = ffi.cast('PObject *', self.direct(oid))
     log.debug('incref %r %r', oid, p_obj.ob_refcnt + 1)
     with self.transaction():
         self.snapshot_range(ffi.addressof(p_obj, 'ob_refcnt'),
                             ffi.sizeof('size_t'))
         p_obj.ob_refcnt += 1
Ejemplo n.º 19
0
    def __init__(self, *args, **kw):
        if not args:
            return
        if len(args) != 1:
            raise TypeError("PersistentTuple takes at most 1"
                            " argument, {} given".format(len(args)))
        item_count = len(args[0])
        mm = self._p_mm
        with mm.transaction():
            mm.snapshot_range(ffi.addressof(self._body, 'ob_items'),
                              ffi.sizeof('PObjPtr'))
            self._body.ob_items = mm.zalloc(
                item_count * ffi.sizeof('PObjPtr'),
                type_num=TUPLE_POBJPTR_ARRAY_TYPE_NUM)

            ob = ffi.cast('PVarObject *', self._body)
            mm.snapshot_range(ffi.addressof(ob, 'ob_size'),
                              ffi.sizeof('size_t'))
            ob.ob_size = item_count

            for index, value in enumerate(args[0]):
                super(self.__class__, self).__setitem__(index, value)
Ejemplo n.º 20
0
Archivo: set.py Proyecto: pmem/pynvm
 def _discard(self, key):
     mm = self._p_mm
     with mm.transaction():
         keyindex = self._lookkey(key, fixed_hash(key))
         if keyindex != -1:
             table_data = ffi.cast('PSetEntry *',
                                   mm.direct(self._body.table))
             mm.snapshot_range(ffi.addressof(table_data, keyindex),
                               ffi.sizeof('PSetEntry'))
             mm.decref(table_data[keyindex].key)
             table_data[keyindex].key = mm.OID_NULL
             table_data[keyindex].hash = HASH_DUMMY
             self._body.used -= 1
Ejemplo n.º 21
0
Archivo: set.py Proyecto: pdeng6/pynvm
 def _discard(self, key):
     mm = self._p_mm
     with mm.transaction():
         keyindex = self._lookkey(key, fixed_hash(key))
         if keyindex != -1:
             table_data = ffi.cast('PSetEntry *',
                                   mm.direct(self._body.table))
             mm.snapshot_range(ffi.addressof(table_data, keyindex),
                               ffi.sizeof('PSetEntry'))
             mm.decref(table_data[keyindex].key)
             table_data[keyindex].key = mm.OID_NULL
             table_data[keyindex].hash = HASH_DUMMY
             self._body.used -= 1
Ejemplo n.º 22
0
 def __delitem__(self, index):
     mm = self.__manager__
     index = self._normalize_index(index)
     size = self._size
     newsize = size - 1
     items = self._items
     with mm.transaction():
         mm.snapshot_range(ffi.addressof(items, index),
                           ffi.offsetof('PObjPtr *', size))
         mm.decref(items[index])
         for i in range(index, newsize):
             items[i] = items[i+1]
         self._resize(newsize)
Ejemplo n.º 23
0
 def decref(self, oid):
     """Decrement the reference count of oid, and free it if zero."""
     oid = self.otuple(oid)
     p_obj = ffi.cast('PObject *', self.direct(oid))
     log.debug('decref %r %r', oid, p_obj.ob_refcnt - 1)
     with self.transaction():
         self.snapshot_range(ffi.addressof(p_obj, 'ob_refcnt'),
                             ffi.sizeof('size_t'))
         assert p_obj.ob_refcnt > 0, "{} oid refcount {}".format(
                                     oid, p_obj.ob_refcnt)
         p_obj.ob_refcnt -= 1
         if p_obj.ob_refcnt < 1:
             self._deallocate(oid)
Ejemplo n.º 24
0
Archivo: pool.py Proyecto: pmem/pynvm
 def incref(self, oid):
     """Increment the reference count of oid if it is not a singleton"""
     oid = self.otuple(oid)
     assert oid != self.OID_NULL
     if not oid[0]:
         # Unlike CPython, we don't ref-track our constants.
         log.debug('not increfing %s', oid)
         return
     p_obj = ffi.cast('PObject *', self.direct(oid))
     log.debug('incref %r %r', oid, p_obj.ob_refcnt + 1)
     with self.transaction():
         self.snapshot_range(ffi.addressof(p_obj, 'ob_refcnt'),
                             ffi.sizeof('size_t'))
         p_obj.ob_refcnt += 1
Ejemplo n.º 25
0
Archivo: pool.py Proyecto: pdeng6/pynvm
 def incref(self, oid):
     """Increment the reference count of oid if it is not a singleton"""
     oid = self.otuple(oid)
     assert oid != self.OID_NULL
     if not oid[0]:
         # Unlike CPython, we don't ref-track our constants.
         log.debug('not increfing %s', oid)
         return
     p_obj = ffi.cast('PObject *', self.direct(oid))
     log.debug('incref %r %r', oid, p_obj.ob_refcnt + 1)
     with self.transaction():
         self.snapshot_range(ffi.addressof(p_obj, 'ob_refcnt'),
                             ffi.sizeof('size_t'))
         p_obj.ob_refcnt += 1
Ejemplo n.º 26
0
Archivo: pool.py Proyecto: pmem/pynvm
 def decref(self, oid):
     """Decrement the reference count of oid, and free it if zero."""
     oid = self.otuple(oid)
     if not oid[0]:
         # Unlike CPython we do not ref-track our constants.
         log.debug('not decrefing %s', oid)
         return
     p_obj = ffi.cast('PObject *', self.direct(oid))
     log.debug('decref %r %r', oid, p_obj.ob_refcnt - 1)
     with self.transaction():
         self.snapshot_range(ffi.addressof(p_obj, 'ob_refcnt'),
                             ffi.sizeof('size_t'))
         assert p_obj.ob_refcnt > 0, "{} oid refcount {}".format(
                                     oid, p_obj.ob_refcnt)
         p_obj.ob_refcnt -= 1
         if p_obj.ob_refcnt < 1:
             self._deallocate(oid)
Ejemplo n.º 27
0
Archivo: list.py Proyecto: pmem/pynvm
 def __delitem__(self, index):
     mm = self._p_mm
     index = self._normalize_index(index)
     size = self._size
     newsize = size - 1
     items = self._items
     with mm.transaction():
         ffi.cast('PVarObject *', self._body).ob_size = newsize
         # We can't completely hide the process of transformation...this
         # really needs a lock (or translation to GIL-locked C).
         mm.snapshot_range(ffi.addressof(items, index),
                           ffi.offsetof('PObjPtr *', size))
         oid = mm.otuple(items[index])
         for i in range(index, newsize):
             items[i] = items[i+1]
         mm.decref(oid)
         self._resize(newsize)
Ejemplo n.º 28
0
Archivo: pool.py Proyecto: pdeng6/pynvm
 def decref(self, oid):
     """Decrement the reference count of oid, and free it if zero."""
     oid = self.otuple(oid)
     if not oid[0]:
         # Unlike CPython we do not ref-track our constants.
         log.debug('not decrefing %s', oid)
         return
     p_obj = ffi.cast('PObject *', self.direct(oid))
     log.debug('decref %r %r', oid, p_obj.ob_refcnt - 1)
     with self.transaction():
         self.snapshot_range(ffi.addressof(p_obj, 'ob_refcnt'),
                             ffi.sizeof('size_t'))
         assert p_obj.ob_refcnt > 0, "{} oid refcount {}".format(
             oid, p_obj.ob_refcnt)
         p_obj.ob_refcnt -= 1
         if p_obj.ob_refcnt < 1:
             self._deallocate(oid)
Ejemplo n.º 29
0
 def __delitem__(self, index):
     mm = self._p_mm
     index = self._normalize_index(index)
     size = self._size
     newsize = size - 1
     items = self._items
     with mm.transaction():
         ffi.cast('PVarObject *', self._body).ob_size = newsize
         # We can't completely hide the process of transformation...this
         # really needs a lock (or translation to GIL-locked C).
         mm.snapshot_range(ffi.addressof(items, index),
                           ffi.offsetof('PObjPtr *', size))
         oid = mm.otuple(items[index])
         for i in range(index, newsize):
             items[i] = items[i + 1]
         mm.decref(oid)
         self._resize(newsize)
Ejemplo n.º 30
0
Archivo: set.py Proyecto: pmem/pynvm
    def _table_resize(self, minused):
        mm = self._p_mm

        if minused > 50000:
            minused = (minused << 1)
        else:
            minused = (minused << 2)

        newsize = PERM_SET_MINSIZE

        while(newsize <= minused):
            newsize = (newsize << 1)

        newsize = ffi.cast('size_t', newsize)

        if newsize == 0:
            raise MemoryError("Out of memory")

        newsize = int(newsize)

        with mm.transaction():
            oldtable = mm.otuple(self._body.table)
            oldtable_data = ffi.cast('PSetEntry *', mm.direct(oldtable))
            newtable = self._alloc_empty_table(newsize)

            newmask = newsize - 1

            for i in range(0, self._body.mask + 1):
                if oldtable_data[i].hash == HASH_UNUSED or \
                   oldtable_data[i].hash == HASH_DUMMY:
                    continue
                self._insert_clean(newtable, newmask,
                                   oldtable_data[i].key,
                                   oldtable_data[i].hash)

            mm.snapshot_range(ffi.addressof(self._body, 'fill'),
                              ffi.sizeof('PSetObject') - ffi.sizeof('PObject'))

            self._body.mask = newmask
            self._body.fill = self._body.used
            self._body.table = newtable

            mm.free(oldtable)
Ejemplo n.º 31
0
Archivo: dict.py Proyecto: pdeng6/pynvm
 def _new_keys_object(self, size):
     assert size >= MIN_SIZE_SPLIT
     mm = self._p_mm
     with mm.transaction():
         dk_oid = mm.zalloc(ffi.sizeof('PDictKeysObject')
                            + ffi.sizeof('PDictKeyEntry') * (size - 1),
                            type_num=PDICTKEYSOBJECT_TYPE_NUM)
         dk = ffi.cast('PDictKeysObject *', mm.direct(dk_oid))
         dk.dk_refcnt = 1
         dk.dk_size = size
         dk.dk_usable = _usable_fraction(size)
         ep = ffi.cast('PDictKeyEntry *', ffi.addressof(dk.dk_entries[0]))
         # Hash value of slot 0 is used by popitem, so it must be initizlied
         ep[0].me_hash = 0
         for i in range(size):
             ep[i].me_key = mm.OID_NULL
             ep[i].me_value = mm.OID_NULL
         # XXX Set dk_lookup to lookdict_unicode_nodummy if we end up using it.
     return dk_oid
Ejemplo n.º 32
0
Archivo: set.py Proyecto: pdeng6/pynvm
    def _table_resize(self, minused):
        mm = self._p_mm

        if minused > 50000:
            minused = (minused << 1)
        else:
            minused = (minused << 2)

        newsize = PERM_SET_MINSIZE

        while (newsize <= minused):
            newsize = (newsize << 1)

        newsize = ffi.cast('size_t', newsize)

        if newsize == 0:
            raise MemoryError("Out of memory")

        newsize = int(newsize)

        with mm.transaction():
            oldtable = mm.otuple(self._body.table)
            oldtable_data = ffi.cast('PSetEntry *', mm.direct(oldtable))
            newtable = self._alloc_empty_table(newsize)

            newmask = newsize - 1

            for i in range(0, self._body.mask + 1):
                if oldtable_data[i].hash == HASH_UNUSED or \
                   oldtable_data[i].hash == HASH_DUMMY:
                    continue
                self._insert_clean(newtable, newmask, oldtable_data[i].key,
                                   oldtable_data[i].hash)

            mm.snapshot_range(ffi.addressof(self._body, 'fill'),
                              ffi.sizeof('PSetObject') - ffi.sizeof('PObject'))

            self._body.mask = newmask
            self._body.fill = self._body.used
            self._body.table = newtable

            mm.free(oldtable)