| |
| |
| |
| |
| """Contains the MemoryDatabase implementation""" |
| from gitdb.db.loose import LooseObjectDB |
| from gitdb.db.base import ( |
| ObjectDBR, |
| ObjectDBW |
| ) |
|
|
| from gitdb.base import ( |
| OStream, |
| IStream, |
| ) |
|
|
| from gitdb.exc import ( |
| BadObject, |
| UnsupportedOperation |
| ) |
|
|
| from gitdb.stream import ( |
| ZippedStoreShaWriter, |
| DecompressMemMapReader, |
| ) |
|
|
| from io import BytesIO |
|
|
| __all__ = ("MemoryDB", ) |
|
|
|
|
| class MemoryDB(ObjectDBR, ObjectDBW): |
|
|
| """A memory database stores everything to memory, providing fast IO and object |
| retrieval. It should be used to buffer results and obtain SHAs before writing |
| it to the actual physical storage, as it allows to query whether object already |
| exists in the target storage before introducing actual IO""" |
|
|
| def __init__(self): |
| super().__init__() |
| self._db = LooseObjectDB("path/doesnt/matter") |
|
|
| |
| self._cache = dict() |
|
|
| def set_ostream(self, stream): |
| raise UnsupportedOperation("MemoryDB's always stream into memory") |
|
|
| def store(self, istream): |
| zstream = ZippedStoreShaWriter() |
| self._db.set_ostream(zstream) |
|
|
| istream = self._db.store(istream) |
| zstream.close() |
| zstream.seek(0) |
|
|
| |
| |
| decomp_stream = DecompressMemMapReader(zstream.getvalue(), close_on_deletion=False) |
| self._cache[istream.binsha] = OStream(istream.binsha, istream.type, istream.size, decomp_stream) |
|
|
| return istream |
|
|
| def has_object(self, sha): |
| return sha in self._cache |
|
|
| def info(self, sha): |
| |
| return self.stream(sha) |
|
|
| def stream(self, sha): |
| try: |
| ostream = self._cache[sha] |
| |
| ostream.stream.seek(0) |
| return ostream |
| except KeyError as e: |
| raise BadObject(sha) from e |
| |
|
|
| def size(self): |
| return len(self._cache) |
|
|
| def sha_iter(self): |
| return self._cache.keys() |
|
|
| |
| def stream_copy(self, sha_iter, odb): |
| """Copy the streams as identified by sha's yielded by sha_iter into the given odb |
| The streams will be copied directly |
| **Note:** the object will only be written if it did not exist in the target db |
| |
| :return: amount of streams actually copied into odb. If smaller than the amount |
| of input shas, one or more objects did already exist in odb""" |
| count = 0 |
| for sha in sha_iter: |
| if odb.has_object(sha): |
| continue |
| |
|
|
| ostream = self.stream(sha) |
| |
| sio = BytesIO(ostream.stream.data()) |
| istream = IStream(ostream.type, ostream.size, sio, sha) |
|
|
| odb.store(istream) |
| count += 1 |
| |
| return count |
| |
|
|