Exemple #1
0
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()
Exemple #2
0
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)))
Exemple #3
0
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()
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
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))
Exemple #7
0
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
Exemple #8
0
class ArchiveEntry(BinaryMultiValue('ArchiveEntry',
                                    dict(when=BSSFloat, dirent=DirentRecord))):
  ''' An Archive entry record.
Exemple #9
0
class BackingFileIndexEntry(
        BinaryMultiValue('BackingFileIndexEntry',
                         dict(offset=BSUInt, length=BSUInt))):
    ''' An index entry for a backing file.