Mercurial > hg
comparison mercurial/store.py @ 50639:5e60abf811f3
stream-clone: make it the responsability of the store entry to stream content
The store entry has more context, this will especially be true when it comes to
revlogs. So we move the details of how to retrieve binary content to the
StoreEntry. The stream clone code now focus on the protocol bits.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Sun, 28 May 2023 05:52:58 +0200 |
parents | 8fc10bfd9887 |
children | 9caa860dcbec |
comparison
equal
deleted
inserted
replaced
50638:8fc10bfd9887 | 50639:5e60abf811f3 |
---|---|
467 _file_size = attr.ib(default=None) | 467 _file_size = attr.ib(default=None) |
468 is_volatile = attr.ib(default=False) | 468 is_volatile = attr.ib(default=False) |
469 | 469 |
470 def file_size(self, vfs): | 470 def file_size(self, vfs): |
471 if self._file_size is None: | 471 if self._file_size is None: |
472 if vfs is None: | |
473 msg = b"calling vfs-less file_size without prior call: %s" | |
474 msg %= self.unencoded_path | |
475 raise error.ProgrammingError(msg) | |
472 try: | 476 try: |
473 self._file_size = vfs.stat(self.unencoded_path).st_size | 477 self._file_size = vfs.stat(self.unencoded_path).st_size |
474 except FileNotFoundError: | 478 except FileNotFoundError: |
475 self._file_size = 0 | 479 self._file_size = 0 |
476 return self._file_size | 480 return self._file_size |
477 | 481 |
482 def get_stream(self, vfs, copies): | |
483 """return data "stream" information for this file | |
484 | |
485 (unencoded_file_path, content_iterator, content_size) | |
486 """ | |
487 size = self.file_size(None) | |
488 | |
489 def get_stream(): | |
490 actual_path = copies[vfs.join(self.unencoded_path)] | |
491 with open(actual_path, 'rb') as fp: | |
492 yield None # ready to stream | |
493 if size <= 65536: | |
494 yield fp.read(size) | |
495 else: | |
496 yield from util.filechunkiter(fp, limit=size) | |
497 | |
498 s = get_stream() | |
499 next(s) | |
500 return (self.unencoded_path, s, size) | |
501 | |
478 | 502 |
479 @attr.s(slots=True, init=False) | 503 @attr.s(slots=True, init=False) |
480 class BaseStoreEntry: | 504 class BaseStoreEntry: |
481 """An entry in the store | 505 """An entry in the store |
482 | 506 |
483 This is returned by `store.walk` and represent some data in the store.""" | 507 This is returned by `store.walk` and represent some data in the store.""" |
484 | 508 |
485 def files(self) -> List[StoreFile]: | 509 def files(self) -> List[StoreFile]: |
486 raise NotImplementedError | 510 raise NotImplementedError |
511 | |
512 def get_streams(self, vfs, copies=None): | |
513 """return a list of data stream associated to files for this entry | |
514 | |
515 return [(unencoded_file_path, content_iterator, content_size), …] | |
516 """ | |
517 assert vfs is not None | |
518 return [f.get_stream(vfs, copies) for f in self.files()] | |
487 | 519 |
488 | 520 |
489 @attr.s(slots=True, init=False) | 521 @attr.s(slots=True, init=False) |
490 class SimpleStoreEntry(BaseStoreEntry): | 522 class SimpleStoreEntry(BaseStoreEntry): |
491 """A generic entry in the store""" | 523 """A generic entry in the store""" |