Exemple #1
0
 def load(self, oid, version=''):
     pos = self.index.get(oid)
     if pos is None:
         return self._storage.load(oid)
     self._file.seek(pos)
     h = self._file.read(8)
     oidlen = u64(h)
     read_oid = self._file.read(oidlen)
     if read_oid != oid:
         raise POSException.StorageSystemError('Bad temporary storage')
     h = self._file.read(16)
     size = u64(h[8:])
     serial = h[:8]
     return self._file.read(size), serial
Exemple #2
0
    def tpc_begin(self, transaction, tid=None, status=' '):
        if self._is_read_only:
            raise POSException.ReadOnlyError()
        self._lock_acquire()
        try:
            if self._transaction is transaction:
                raise POSException.StorageTransactionError(
                    "Duplicate tpc_begin calls for same transaction")
            self._lock_release()
            self._commit_lock_acquire()
            self._lock_acquire()
            self._transaction = transaction
            self._clear_temp()

            user = transaction.user
            desc = transaction.description
            ext = transaction._extension
            if ext:
                ext = cPickle.dumps(ext, 1)
            else:
                ext = ""

            self._ude = user, desc, ext

            if tid is None:
                now = time.time()
                t = TimeStamp(*(time.gmtime(now)[:5] + (now % 60,)))
                self._ts = t = t.laterThan(self._ts)
                self._tid = repr(t)
            else:
                self._ts = TimeStamp(tid)
                self._tid = tid

            self._tstatus = status
            self._begin(self._tid, user, desc, ext)
        finally:
            self._lock_release()
Exemple #3
0
    def __init__(self, name='Demo Storage', base=None, quota=None):
        BaseStorage.__init__(self, name, base)

        # We use a BTree because the items are sorted!
        self._data = OOBTree.OOBTree()
        self._index = {}
        self._vindex = {}
        self._base = base
        self._size = 0
        self._quota = quota
        self._ltid = None
        self._clear_temp()
        if base is not None and base.versions():
            raise POSException.StorageError(
                "Demo base storage has version data")
Exemple #4
0
 def loadSerial(self, oid, serial, marker=[]):
     """ this is only useful to make conflict resolution work.  It
     does not actually implement all the semantics that a revisioning
     storage needs! """
     self._lock_acquire()
     try:
         data = self._conflict_cache.get((oid, serial), marker)
         if data is marker:
             # XXX Need 2 serialnos to pass them to ConflictError--
             # the old and the new
             raise POSException.ConflictError(oid=oid)
         else:
             return data[0] # data here is actually (data, t)
     finally:
         self._lock_release()
Exemple #5
0
 def new_oid(self):
     if self._is_read_only:
         raise POSException.ReadOnlyError()
     self._lock_acquire()
     try:
         last = self._oid
         d = ord(last[-1])
         if d < 255:  # fast path for the usual case
             last = last[:-1] + chr(d + 1)
         else:  # there's a carry out of the last byte
             last_as_long, = _structunpack(">Q", last)
             last = _structpack(">Q", last_as_long + 1)
         self._oid = last
         return last
     finally:
         self._lock_release()
 def load(self, oid, version=''):
     with self._lock:
         try:
             s = self._index[oid]
             p = self._opickle[oid]
             return p, s  # pickle, serial
         except KeyError:
             # this oid was probably garbage collected while a thread held
             # on to an object that had a reference to it; we can probably
             # force the loader to sync their connection by raising a
             # ConflictError (at least if Zope is the loader, because it
             # will resync its connection on a retry).  This isn't
             # perfect because the length of the recently gc'ed oids list
             # is finite and could be overrun through a mass gc, but it
             # should be adequate in common-case usage.
             if oid in self._recently_gc_oids:
                 raise POSException.ConflictError(oid=oid)
             else:
                 raise
Exemple #7
0
    def tpc_finish(self, transaction, f=None):
        # It's important that the storage calls the function we pass
        # while it still has its lock.  We don't want another thread
        # to be able to read any updated data until we've had a chance
        # to send an invalidation message to all of the other
        # connections!

        self._lock_acquire()
        try:
            if transaction is not self._transaction:
                raise POSException.StorageTransactionError(
                    "tpc_finish called with wrong transaction")
            try:
                if f is not None:
                    f(self._tid)
                u, d, e = self._ude
                self._finish(self._tid, u, d, e)
                self._clear_temp()
            finally:
                self._ude = None
                self._transaction = None
                self._commit_lock_release()
        finally:
            self._lock_release()
Exemple #8
0
 def load(self, oid, version=''):
     result = self.loadBefore(oid, utils.maxtid)
     if result is None:
         raise POSException.POSKeyError(oid)
     return result[:2]
Exemple #9
0
 def loadSerial(self, oid, serial):
     raise POSException.Unsupported(
         "Retrieval of historical revisions is not supported")
Exemple #10
0
 def pack(self, t, referencesf):
     if self._is_read_only:
         raise POSException.ReadOnlyError()
Exemple #11
0
 def undo(self, transaction_id, txn):
     if self._is_read_only:
         raise POSException.ReadOnlyError()
     raise POSException.UndoError('non-undoable transaction')
Exemple #12
0
 def loadEx(self, oid, version):
     try:
         data, serial, _ = self.app.load(oid)
     except NEOStorageNotFoundError:
         raise POSException.POSKeyError(oid)
     return data, serial, ''
Exemple #13
0
 def commitVersion(self, src, dest, transaction):
     if transaction is not self._transaction:
         raise POSException.StorageTransactionError(self, transaction)
     return self._tid, []
Exemple #14
0
 def history(self, oid, *args, **kw):
     try:
         return self.app.history(oid, *args, **kw)
     except NEOStorageNotFoundError:
         raise POSException.POSKeyError(oid)
Exemple #15
0
 def loadSerial(self, oid, serial):
     try:
         return self.app.load(oid, serial)[0]
     except NEOStorageNotFoundError:
         raise POSException.POSKeyError(oid)
Exemple #16
0
def raiseReadOnlyError(*args, **kw):
    raise POSException.ReadOnlyError()
Exemple #17
0
    def store(self, oid, h64, data, version, transaction):
        if transaction is not self._transaction:
            raise POSException.StorageTransactionError(self, transaction)

        if version:
            raise POSException.Unsupported, "Versions aren't supported"

        self._lock_acquire()
        try:
            self.conf_resource.access(self)  # Update configuration

            # First detect conflicts.
            # The "h64" argument, if its value is not 0,
            # was previously generated by hash64().
            if h64 == HASH0:
                # Writing a new object.
                is_new = True
            else:
                # Overwriting an old object.  Use the hash to verify
                # that the new data was derived from the old data.
                is_new = False
                event, old_c, old_state, old_hash = self._gwio.load(oid)
                old_h64 = self.hash64(old_hash)
                if h64 != old_h64:
                    h = None
                    if self.debug_conflicts:
                        h = self._loaded_hashes.get(oid)
                    if h is None:
                        h = h64
                        old_hash = old_h64
                    error = ("Storing %s based on old data.  %s != %s." %
                             (repr(oid), repr(h), repr(old_hash)))
                    if self.debug_conflicts:
                        # Expose the error for debugging..
                        raise RuntimeError(error)
                    else:
                        # Use normal ZODB conflict errors.
                        raise POSException.ConflictError(error)

            # Now unpickle and store the data.
            file = StringIO(data)
            u = Unpickler(file)
            classification = u.load()
            state = u.load()
            event, new_hash = self._gwio.store(oid, classification, state,
                                               is_new)
            new_h64 = self.hash64(new_hash)
            if self.debug_conflicts:
                self._loaded_hashes[oid] = new_hash

            # Remember that this OID changed (for scanning)
            tid = self.getTransactionId()
            t = self.changed.get(tid)
            if t is None:
                t = {}
                self.changed[tid] = t
            t[oid] = 1
        finally:
            self._lock_release()

        return new_h64