示例#1
0
文件: list.py 项目: 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
示例#2
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
示例#3
0
文件: set.py 项目: 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)
示例#4
0
文件: list.py 项目: bitdancer/pynvm
 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
示例#5
0
文件: set.py 项目: 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)
示例#6
0
文件: pool.py 项目: bitdancer/pynvm
    def __init__(self, filename, flag='w',
                       pool_size=MIN_POOL_SIZE, mode=0o666, debug=False):
        """Open or create a persistent object pool backed by filename.

        If flag is 'w', raise an OSError if the file does not exist and
        otherwise open it for reading and writing.  If flag is 'x', raise an
        OSError if the file *does* exist, otherwise create it and open it for
        reading and writing.  If flag is 'c', create the file if it does not
        exist, otherwise use the existing file.

        If the file gets created, use pool_size as the size of the new pool in
        bytes and mode as its access mode, otherwise ignore these parameters
        and open the existing file.

        If debug is True, generate some additional logging, including turning
        on some additional sanity-check warnings.  This may have an impact
        on performance.

        See also the open and create functions of nvm.pmemobj, which are
        convenience functions for the 'w' and 'x' flags, respectively.
        """
        log.debug('PersistentObjectPool.__init__: %r, %r %r, %r',
                  filename, flag, pool_size, mode)
        self.filename = filename
        self.debug = debug
        exists = os.path.exists(filename)
        if flag == 'w' or (flag == 'c' and exists):
            self._pool_ptr = _check_null(
                lib.pmemobj_open(_coerce_fn(filename),
                                 layout_version))
        elif flag == 'x' or (flag == 'c' and not exists):
            self._pool_ptr = _check_null(
                lib.pmemobj_create(_coerce_fn(filename),
                                   layout_version,
                                   pool_size,
                                   mode))
        elif flag == 'r':
            raise ValueError("Read-only mode is not supported")
        else:
            raise ValueError("Invalid flag value {}".format(flag))
        mm = self.mm = MemoryManager(self._pool_ptr)
        pmem_root = lib.pmemobj_root(self._pool_ptr, ffi.sizeof('PRoot'))
        pmem_root = ffi.cast('PRoot *', mm.direct(pmem_root))
        type_table_oid = mm.otuple(pmem_root.type_table)
        if type_table_oid == mm.OID_NULL:
            with mm.transaction():
                type_table_oid = mm._create_type_table()
                mm.snapshot_range(pmem_root, ffi.sizeof('PObjPtr'))
                pmem_root.type_table = type_table_oid
        else:
            mm._resurrect_type_table(type_table_oid)
        self._pmem_root = pmem_root
        if exists:
            # Make sure any objects orphaned by a crash are cleaned up.
            # XXX should fix this to only be called when there is a crash.
            self.gc()
示例#7
0
文件: pool.py 项目: pdeng6/pynvm
 def _persist_builtins_str(self, s):
     type_code = self._get_type_code(s.__class__)
     if sys.version_info[0] > 2:
         s = s.encode('utf-8')
     with self.transaction():
         p_str_oid = self.zalloc(ffi.sizeof('PObject') + len(s) + 1)
         p_str = ffi.cast('PObject *', self.direct(p_str_oid))
         p_str.ob_type = type_code
         body = ffi.cast('char *', p_str) + ffi.sizeof('PObject')
         ffi.buffer(body, len(s))[:] = s
     return p_str_oid
示例#8
0
文件: pool.py 项目: pmem/pynvm
 def _persist_builtins_str(self, s):
     type_code = self._get_type_code(s.__class__)
     if sys.version_info[0] > 2:
         s = s.encode('utf-8')
     with self.transaction():
         p_str_oid = self.zalloc(ffi.sizeof('PObject') + len(s) + 1)
         p_str = ffi.cast('PObject *', self.direct(p_str_oid))
         p_str.ob_type = type_code
         body = ffi.cast('char *', p_str) + ffi.sizeof('PObject')
         ffi.buffer(body, len(s))[:] = s
     return p_str_oid
示例#9
0
文件: pool.py 项目: pmem/pynvm
 def _persist_nvm_pmemobj_pool_PICKLE_SENTINEL(self, obj):
     type_code = self._get_type_code(PICKLE_SENTINEL)
     s = dumps(obj)
     print(s)
     with self.transaction():
         p_obj_oid = self.zalloc(ffi.sizeof('PVarObject') + len(s))
         p_pickle = ffi.cast('PVarObject *', self.direct(p_obj_oid))
         p_pickle.ob_base.ob_type = type_code
         p_pickle.ob_size = len(s)
         body = ffi.cast('char *', p_pickle) + ffi.sizeof('PVarObject')
         ffi.buffer(body, len(s))[:] = s
     return p_obj_oid
示例#10
0
文件: pool.py 项目: pdeng6/pynvm
 def _persist_nvm_pmemobj_pool_PICKLE_SENTINEL(self, obj):
     type_code = self._get_type_code(PICKLE_SENTINEL)
     s = dumps(obj)
     print(s)
     with self.transaction():
         p_obj_oid = self.zalloc(ffi.sizeof('PVarObject') + len(s))
         p_pickle = ffi.cast('PVarObject *', self.direct(p_obj_oid))
         p_pickle.ob_base.ob_type = type_code
         p_pickle.ob_size = len(s)
         body = ffi.cast('char *', p_pickle) + ffi.sizeof('PVarObject')
         ffi.buffer(body, len(s))[:] = s
     return p_obj_oid
示例#11
0
文件: dict.py 项目: 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)
示例#12
0
文件: set.py 项目: 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
示例#13
0
文件: set.py 项目: 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
示例#14
0
文件: list.py 项目: pmem/pynvm
 def _p_new(self, manager):
     mm = self._p_mm = manager
     with mm.transaction():
         # XXX Will want to implement a freelist here, like CPython
         self._p_oid = mm.zalloc(ffi.sizeof('PListObject'))
         ob = ffi.cast('PObject *', mm.direct(self._p_oid))
         ob.ob_type = mm._get_type_code(PersistentList)
     self._body = ffi.cast('PListObject *', mm.direct(self._p_oid))
示例#15
0
 def _p_new(self, manager):
     mm = self._p_mm = manager
     with mm.transaction():
         # XXX Will want to implement a freelist here, like CPython
         self._p_oid = mm.zalloc(ffi.sizeof('PListObject'))
         ob = ffi.cast('PObject *', mm.direct(self._p_oid))
         ob.ob_type = mm._get_type_code(PersistentList)
     self._body = ffi.cast('PListObject *', mm.direct(self._p_oid))
示例#16
0
文件: pool.py 项目: pmem/pynvm
 def _persist_builtins_float(self, f):
     type_code = self._get_type_code(f.__class__)
     with self.transaction():
         p_float_oid = self.zalloc(ffi.sizeof('PFloatObject'))
         p_float = ffi.cast('PObject *', self.direct(p_float_oid))
         p_float.ob_type = type_code
         p_float = ffi.cast('PFloatObject *', p_float)
         p_float.fval = f
     return p_float_oid
示例#17
0
文件: pool.py 项目: pdeng6/pynvm
 def _persist_builtins_float(self, f):
     type_code = self._get_type_code(f.__class__)
     with self.transaction():
         p_float_oid = self.zalloc(ffi.sizeof('PFloatObject'))
         p_float = ffi.cast('PObject *', self.direct(p_float_oid))
         p_float.ob_type = type_code
         p_float = ffi.cast('PFloatObject *', p_float)
         p_float.fval = f
     return p_float_oid
示例#18
0
文件: pool.py 项目: 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)
示例#19
0
文件: tuple.py 项目: pdeng6/pynvm
    def _p_new(self, manager):
        mm = self._p_mm = manager
        with mm.transaction():
            self._p_oid = mm.zalloc(ffi.sizeof('PTupleObject'))

            ob = ffi.cast('PObject *', mm.direct(self._p_oid))
            ob.ob_type = mm._get_type_code(PersistentTuple)

            self._body = ffi.cast('PTupleObject *', mm.direct(self._p_oid))
            self._body.ob_items = mm.OID_NULL
示例#20
0
文件: dict.py 项目: 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
示例#21
0
文件: pool.py 项目: 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)
示例#22
0
文件: set.py 项目: 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)
示例#23
0
文件: set.py 项目: 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)
示例#24
0
文件: set.py 项目: pdeng6/pynvm
 def _p_new(self, manager):
     mm = self._p_mm = manager
     with mm.transaction():
         self._p_oid = mm.zalloc(ffi.sizeof('PSetObject'))
         ob = ffi.cast('PObject *', mm.direct(self._p_oid))
         ob.ob_type = mm._get_type_code(self.__class__)
         size = PERM_SET_MINSIZE
         self._body = ffi.cast('PSetObject *', mm.direct(self._p_oid))
         self._body.mask = (size - 1)
         self._body.hash = HASH_INVALID
         self._body.table = self._alloc_empty_table(PERM_SET_MINSIZE)
示例#25
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)
示例#26
0
文件: set.py 项目: pmem/pynvm
 def _p_new(self, manager):
     mm = self._p_mm = manager
     with mm.transaction():
         self._p_oid = mm.zalloc(ffi.sizeof('PSetObject'))
         ob = ffi.cast('PObject *', mm.direct(self._p_oid))
         ob.ob_type = mm._get_type_code(self.__class__)
         size = PERM_SET_MINSIZE
         self._body = ffi.cast('PSetObject *', mm.direct(self._p_oid))
         self._body.mask = (size - 1)
         self._body.hash = HASH_INVALID
         self._body.table = self._alloc_empty_table(PERM_SET_MINSIZE)
示例#27
0
文件: list.py 项目: 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)
示例#28
0
文件: dict.py 项目: pdeng6/pynvm
 def _p_new(self, manager):
     mm = self._p_mm = manager
     with mm.transaction():
         # XXX will want to implement a freelist here.
         self._p_oid = mm.zalloc(ffi.sizeof('PDictObject'))
         ob = ffi.cast('PObject *', mm.direct(self._p_oid))
         ob.ob_type = mm._get_type_code(PersistentDict)
         d = self._body = ffi.cast('PDictObject *', mm.direct(self._p_oid))
         # This code may get moved to a _new_dict method when we implement
         # split dicts.
         d.ma_keys = self._new_keys_object(MIN_SIZE_COMBINED)
         d.ma_values = mm.OID_NULL
示例#29
0
文件: pool.py 项目: bitdancer/pynvm
 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
示例#30
0
文件: set.py 项目: 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
示例#31
0
文件: pool.py 项目: bitdancer/pynvm
 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)
示例#32
0
文件: set.py 项目: 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
示例#33
0
文件: tuple.py 项目: pdeng6/pynvm
    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)
示例#34
0
 def _p_new(self, manager):
     self._p_dict = {}    # This makes __getattribute__ simpler
     mm = self._p_mm = manager
     with mm.transaction():
         # XXX will want to implement a freelist here.
         self._p_oid = mm.zalloc(ffi.sizeof('PObjectObject'))
         ob = ffi.cast('PObject *', mm.direct(self._p_oid))
         ob.ob_type = mm._get_type_code(self.__class__)
         d = self._p_body = ffi.cast('PObjectObject *',
                                     mm.direct(self._p_oid))
         self._p_dict = mm.new(PersistentDict)
         d.ob_dict = self._p_dict._p_oid
         mm.incref(self._p_dict._p_oid)
     self._v__init__()
示例#35
0
文件: pool.py 项目: 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
示例#36
0
文件: pool.py 项目: 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
示例#37
0
文件: pool.py 项目: 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)
示例#38
0
文件: pool.py 项目: 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)
示例#39
0
文件: list.py 项目: bitdancer/pynvm
 def __init__(self, *args, **kw):
     if '__manager__' not in kw:
         raise ValueError("__manager__ is required")
     mm = self.__manager__ = kw.pop('__manager__')
     if '_oid' not in kw:
         with mm.transaction():
             # XXX Will want to implement a freelist here, like CPython
             self._oid = mm.malloc(ffi.sizeof('PListObject'))
             ob = ffi.cast('PObject *', mm.direct(self._oid))
             ob.ob_type = mm._get_type_code(PersistentList)
     else:
         self._oid = kw.pop('_oid')
     if kw:
         raise TypeError("Unrecognized keyword argument(s) {}".format(kw))
     self._body = ffi.cast('PListObject *', mm.direct(self._oid))
     if args:
         if len(args) != 1:
             raise TypeError("PersistentList takes at most 1"
                             " argument, {} given".format(len(args)))
         self.extend(args[0])
示例#40
0
文件: set.py 项目: pdeng6/pynvm
 def _alloc_empty_table(self, tablesize):
     return self._p_mm.zalloc(ffi.sizeof('PSetEntry') * tablesize,
                              type_num=SET_POBJPTR_ARRAY_TYPE_NUM)
示例#41
0
文件: pool.py 项目: pmem/pynvm
 def _resurrect_builtins_str(self, obj_ptr):
     body = ffi.cast('char *', obj_ptr) + ffi.sizeof('PObject')
     s = ffi.string(body)
     if sys.version_info[0] > 2:
         s = s.decode('utf-8')
     return s
示例#42
0
文件: pool.py 项目: pdeng6/pynvm
 def _resurrect_nvm_pmemobj_pool_PICKLE_SENTINEL(self, obj_ptr):
     obj_ptr = ffi.cast('PVarObject *', obj_ptr)
     body = ffi.cast('char *', obj_ptr) + ffi.sizeof('PVarObject')
     s = ffi.buffer(body, obj_ptr.ob_size)[:]
     obj = loads(s)
     return obj
示例#43
0
文件: pool.py 项目: pdeng6/pynvm
 def _resurrect_builtins_str(self, obj_ptr):
     body = ffi.cast('char *', obj_ptr) + ffi.sizeof('PObject')
     s = ffi.string(body)
     if sys.version_info[0] > 2:
         s = s.decode('utf-8')
     return s
示例#44
0
文件: pool.py 项目: pdeng6/pynvm
    def __init__(self,
                 filename,
                 flag='w',
                 pool_size=MIN_POOL_SIZE,
                 mode=0o666,
                 debug=False):
        """Open or create a persistent object pool backed by filename.

        If flag is 'w', raise an OSError if the file does not exist and
        otherwise open it for reading and writing.  If flag is 'x', raise an
        OSError if the file *does* exist, otherwise create it and open it for
        reading and writing.  If flag is 'c', create the file if it does not
        exist, otherwise use the existing file.

        If the file gets created, use pool_size as the size of the new pool in
        bytes and mode as its access mode, otherwise ignore these parameters
        and open the existing file.

        If debug is True, generate some additional logging, including turning
        on some additional sanity-check warnings.  This may have an impact
        on performance.

        When the pool is opened, if the previous shutdown was not clean the
        pool is cleaned up, including running the 'gc' method.

        See also the open and create functions of nvm.pmemobj, which are
        convenience functions for the 'w' and 'x' flags, respectively.
        """
        log.debug('PersistentObjectPool.__init__: %r, %r %r, %r', filename,
                  flag, pool_size, mode)
        self.filename = filename
        self.debug = debug
        exists = os.path.exists(filename)
        if flag == 'w' or (flag == 'c' and exists):
            self._pool_ptr = _err_check.check_null(
                lib.pmemobj_open(_coerce_fn(filename), layout_version))
        elif flag == 'x' or (flag == 'c' and not exists):
            self._pool_ptr = _err_check.check_null(
                lib.pmemobj_create(_coerce_fn(filename), layout_version,
                                   pool_size, mode))
        elif flag == 'r':
            raise ValueError("Read-only mode is not supported")
        else:
            raise ValueError("Invalid flag value {}".format(flag))
        mm = self.mm = MemoryManager(self._pool_ptr)
        pmem_root = lib.pmemobj_root(self._pool_ptr, ffi.sizeof('PRoot'))
        pmem_root = ffi.cast('PRoot *', mm.direct(pmem_root))
        type_table_oid = mm.otuple(pmem_root.type_table)
        if type_table_oid == mm.OID_NULL:
            with mm.transaction():
                type_table_oid = mm._create_type_table()
                mm.snapshot_range(pmem_root, ffi.sizeof('PObjPtr'))
                pmem_root.type_table = type_table_oid
                pmem_root.root_object = self.mm.persist(None)
                pmem_root.clean_shutdown = self.mm.persist(False)
                gc_needed = False
        else:
            mm._resurrect_type_table(type_table_oid)
            gc_needed = not self.mm.resurrect(pmem_root.clean_shutdown)
        self._pmem_root = pmem_root
        # Make sure any objects orphaned by a crash are cleaned up.
        if gc_needed:
            self.gc()
示例#45
0
文件: pool.py 项目: pmem/pynvm
 def _resurrect_nvm_pmemobj_pool_PICKLE_SENTINEL(self, obj_ptr):
     obj_ptr = ffi.cast('PVarObject *', obj_ptr)
     body = ffi.cast('char *', obj_ptr) + ffi.sizeof('PVarObject')
     s = ffi.buffer(body, obj_ptr.ob_size)[:]
     obj = loads(s)
     return obj
示例#46
0
文件: set.py 项目: pmem/pynvm
 def _alloc_empty_table(self, tablesize):
     return self._p_mm.zalloc(ffi.sizeof('PSetEntry') * tablesize,
                              type_num=SET_POBJPTR_ARRAY_TYPE_NUM)