Beispiel #1
0
 def write(self, manifest: LocalFileManifest, content: bytes,
           offset: int) -> LocalFileManifest:
     # No-op
     if len(content) == 0:
         return manifest
     # Write
     manifest, write_operations, removed_ids = prepare_write(
         manifest, len(content), offset)
     for chunk, offset in write_operations:
         self.write_chunk(chunk, content, offset)
     for removed_id in removed_ids:
         self.clear_chunk_data(removed_id)
     return manifest
Beispiel #2
0
    async def fd_write(self,
                       fd: FileDescriptor,
                       content: bytes,
                       offset: int,
                       constrained: bool = False) -> int:
        # Fetch and lock
        async with self._load_and_lock_file(fd) as manifest:

            # Constrained - truncate content to the right length
            if constrained:
                end_offset = min(manifest.size, offset + len(content))
                length = max(end_offset - offset, 0)
                content = content[:length]

            # No-op
            if not content:
                return 0

            # Prepare
            updated = self.device.timestamp()
            offset = normalize_argument(offset, manifest)
            manifest, write_operations, removed_ids = prepare_write(
                manifest, len(content), offset, updated)

            # Writing
            for chunk, offset in write_operations:
                self._write_count[fd] += await self._write_chunk(
                    chunk, content, offset)

            # Atomic change
            await self.local_storage.set_manifest(manifest.id,
                                                  manifest,
                                                  cache_only=True,
                                                  removed_ids=removed_ids)

            # Reshaping
            if self._write_count[fd] >= manifest.blocksize:
                await self._manifest_reshape(manifest, cache_only=True)
                self._write_count.pop(fd, None)

        # Notify
        self._send_event(CoreEvent.FS_ENTRY_UPDATED, id=manifest.id)
        return len(content)