class AddRequest(UnFlaggedPayloadMixin, BinaryMultiValue('AddRequest', dict(hashenum=BSUInt, data=BSData))): ''' An add(bytes) request, returning the hashcode for the stored data. ''' RQTYPE = RqType.ADD @property def hashclass(self): ''' The hash class derived from the hashenum. ''' return HashCode.by_index(self.hashenum) def do(self, stream): ''' Add data to the local store, return serialised hashcode. ''' local_store = stream._local_store if local_store is None: raise ValueError("no local_store, request rejected") if self.hashclass is not local_store.hashclass: raise ValueError( "request hashclass=%s but local store %s.hashclass=%s" % (self.hashclass, local_store, local_store.hashclass)) # return the serialised hashcode of the added data return local_store.add(self.data).encode()
class LengthRequest(UnFlaggedPayloadMixin, BinaryMultiValue('LengthRequest', {})): ''' Request the length (number of indexed Blocks) of the remote Store. ''' RQTYPE = RqType.LENGTH @staticmethod def do(stream): ''' Return the number of indexed blocks in `local_store`. ''' local_store = stream._local_store if local_store is None: raise ValueError("no local_store, request rejected") return bytes(BSUInt(len(local_store)))
class FlushRequest(UnFlaggedPayloadMixin, BinaryMultiValue('FlushRequest', {})): ''' A flush request. ''' RQTYPE = RqType.FLUSH @staticmethod def do(stream): ''' Flush the `local_store`. ''' local_store = stream._local_store if local_store is None: raise ValueError("no local_store, request rejected") local_store.flush()
class ArchiveListRequest(UnFlaggedPayloadMixin, BinaryMultiValue('ArchiveListRequest', dict(s=BSString))): ''' List the entries in a remote Archive. ''' RQTYPE = RqType.ARCHIVE_LIST def do(self, stream): ''' Return ArchiveEntry transcriptions from the named Archive. ''' local_store = stream._local_store if local_store is None: raise ValueError("no local_store, request rejected") archive = local_store.get_Archive(self.s) return b''.join(bytes(entry) for entry in archive)
class ArchiveUpdateRequest(UnFlaggedPayloadMixin, BinaryMultiValue( 'ArchiveUpdateRequest', dict(archive_name=BSString, entry=ArchiveEntry))): ''' Add an entry to a remote Archive. ''' RQTYPE = RqType.ARCHIVE_UPDATE def do(self, stream): ''' Return data from the local store by hashcode. ''' local_store = stream._local_store if local_store is None: raise ValueError("no local_store, request rejected") archive = local_store.get_Archive(self.archive_name) entry = self.entry archive.update(entry.dirent, when=entry.when)
class ArchiveLastRequest(UnFlaggedPayloadMixin, BinaryMultiValue('ArchiveLastRequest', dict(s=BSString))): ''' Return the last entry in a remote Archive. ''' RQTYPE = RqType.ARCHIVE_LAST def do(self, stream): ''' Return data from the local store by hashcode. ''' local_store = stream._local_store if local_store is None: raise ValueError("no local_store, request rejected") archive = local_store.get_Archive(self.s) entry = archive.last if entry.dirent is None: return 0 return (1, bytes(entry))
class FileDataIndexEntry(BinaryMultiValue('FileDataIndexEntry', { 'filenum': BSUInt, 'data_offset': BSUInt, 'data_length': BSUInt, 'flags': BSUInt, })): ''' An index entry describing a data chunk in a `DataDir`. This has the following attributes: * `filenum`: the file number of the file containing the block * `data_offset`: the offset within the file of the data chunk * `data_length`: the length of the chunk * `flags`: information about the chunk These enable direct access to the raw data component. The only defined flag at present is `FLAG_COMPRESSED`, indicating that the raw data should be obtained by uncompressing the chunk using `zlib.uncompress`. ''' FLAG_COMPRESSED = 0x01 @property def is_compressed(self): ''' Whether the chunk data are compressed. ''' return self.flags & self.FLAG_COMPRESSED def fetch_fd(self, rfd): ''' Fetch the decompressed data from an open binary file. ''' bs = pread(rfd, self.data_length, self.data_offset) if len(bs) != self.data_length: raise RuntimeError( "%s.fetch_fd: pread(fd=%s) returned %d bytes, expected %d" % (self, rfd, len(bs), self.data_length) ) if self.is_compressed: bs = decompress(bs) return bs
class ArchiveEntry(BinaryMultiValue('ArchiveEntry', dict(when=BSSFloat, dirent=DirentRecord))): ''' An Archive entry record.
class BackingFileIndexEntry( BinaryMultiValue('BackingFileIndexEntry', dict(offset=BSUInt, length=BSUInt))): ''' An index entry for a backing file.