Show More
@@ -66,17 +66,24 b' class simplestoreerror(error.StorageErro' | |||||
66 | pass |
|
66 | pass | |
67 |
|
67 | |||
68 | @interfaceutil.implementer(repository.irevisiondelta) |
|
68 | @interfaceutil.implementer(repository.irevisiondelta) | |
69 |
@attr.s(slots=True |
|
69 | @attr.s(slots=True) | |
70 | class simplestorerevisiondelta(object): |
|
70 | class simplestorerevisiondelta(object): | |
71 | node = attr.ib() |
|
71 | node = attr.ib() | |
72 | p1node = attr.ib() |
|
72 | p1node = attr.ib() | |
73 | p2node = attr.ib() |
|
73 | p2node = attr.ib() | |
74 | basenode = attr.ib() |
|
74 | basenode = attr.ib() | |
75 | linknode = attr.ib() |
|
|||
76 | flags = attr.ib() |
|
75 | flags = attr.ib() | |
77 | baserevisionsize = attr.ib() |
|
76 | baserevisionsize = attr.ib() | |
78 | revision = attr.ib() |
|
77 | revision = attr.ib() | |
79 | delta = attr.ib() |
|
78 | delta = attr.ib() | |
|
79 | linknode = attr.ib(default=None) | |||
|
80 | ||||
|
81 | @interfaceutil.implementer(repository.iverifyproblem) | |||
|
82 | @attr.s(frozen=True) | |||
|
83 | class simplefilestoreproblem(object): | |||
|
84 | warning = attr.ib(default=None) | |||
|
85 | error = attr.ib(default=None) | |||
|
86 | node = attr.ib(default=None) | |||
80 |
|
87 | |||
81 | @interfaceutil.implementer(repository.ifilestorage) |
|
88 | @interfaceutil.implementer(repository.ifilestorage) | |
82 | class filestorage(object): |
|
89 | class filestorage(object): | |
@@ -192,6 +199,13 b' class filestorage(object):' | |||||
192 |
|
199 | |||
193 | return self._indexbyrev[rev][b'node'] |
|
200 | return self._indexbyrev[rev][b'node'] | |
194 |
|
201 | |||
|
202 | def hasnode(self, node): | |||
|
203 | validatenode(node) | |||
|
204 | return node in self._indexbynode | |||
|
205 | ||||
|
206 | def censorrevision(self, tr, censornode, tombstone=b''): | |||
|
207 | raise NotImplementedError('TODO') | |||
|
208 | ||||
195 | def lookup(self, node): |
|
209 | def lookup(self, node): | |
196 | if isinstance(node, int): |
|
210 | if isinstance(node, int): | |
197 | return self.node(node) |
|
211 | return self.node(node) | |
@@ -290,7 +304,11 b' class filestorage(object):' | |||||
290 | raise simplestoreerror(_("integrity check failed on %s") % |
|
304 | raise simplestoreerror(_("integrity check failed on %s") % | |
291 | self._path) |
|
305 | self._path) | |
292 |
|
306 | |||
293 | def revision(self, node, raw=False): |
|
307 | def revision(self, nodeorrev, raw=False): | |
|
308 | if isinstance(nodeorrev, int): | |||
|
309 | node = self.node(nodeorrev) | |||
|
310 | else: | |||
|
311 | node = nodeorrev | |||
294 | validatenode(node) |
|
312 | validatenode(node) | |
295 |
|
313 | |||
296 | if node == nullid: |
|
314 | if node == nullid: | |
@@ -409,6 +427,44 b' class filestorage(object):' | |||||
409 |
|
427 | |||
410 | return [b'/'.join((self._storepath, f)) for f in entries] |
|
428 | return [b'/'.join((self._storepath, f)) for f in entries] | |
411 |
|
429 | |||
|
430 | def storageinfo(self, exclusivefiles=False, sharedfiles=False, | |||
|
431 | revisionscount=False, trackedsize=False, | |||
|
432 | storedsize=False): | |||
|
433 | # TODO do a real implementation of this | |||
|
434 | return { | |||
|
435 | 'exclusivefiles': [], | |||
|
436 | 'sharedfiles': [], | |||
|
437 | 'revisionscount': len(self), | |||
|
438 | 'trackedsize': 0, | |||
|
439 | 'storedsize': None, | |||
|
440 | } | |||
|
441 | ||||
|
442 | def verifyintegrity(self, state): | |||
|
443 | state['skipread'] = set() | |||
|
444 | for rev in self: | |||
|
445 | node = self.node(rev) | |||
|
446 | try: | |||
|
447 | self.revision(node) | |||
|
448 | except Exception as e: | |||
|
449 | yield simplefilestoreproblem( | |||
|
450 | error='unpacking %s: %s' % (node, e), | |||
|
451 | node=node) | |||
|
452 | state['skipread'].add(node) | |||
|
453 | ||||
|
454 | def emitrevisions(self, nodes, nodesorder=None, revisiondata=False, | |||
|
455 | assumehaveparentrevisions=False, | |||
|
456 | deltamode=repository.CG_DELTAMODE_STD): | |||
|
457 | # TODO this will probably break on some ordering options. | |||
|
458 | nodes = [n for n in nodes if n != nullid] | |||
|
459 | if not nodes: | |||
|
460 | return | |||
|
461 | for delta in storageutil.emitrevisions( | |||
|
462 | self, nodes, nodesorder, simplestorerevisiondelta, | |||
|
463 | revisiondata=revisiondata, | |||
|
464 | assumehaveparentrevisions=assumehaveparentrevisions, | |||
|
465 | deltamode=deltamode): | |||
|
466 | yield delta | |||
|
467 | ||||
412 | def add(self, text, meta, transaction, linkrev, p1, p2): |
|
468 | def add(self, text, meta, transaction, linkrev, p1, p2): | |
413 | if meta or text.startswith(b'\1\n'): |
|
469 | if meta or text.startswith(b'\1\n'): | |
414 | text = storageutil.packmeta(meta, text) |
|
470 | text = storageutil.packmeta(meta, text) | |
@@ -489,15 +545,26 b' class filestorage(object):' | |||||
489 |
|
545 | |||
490 | if addrevisioncb: |
|
546 | if addrevisioncb: | |
491 | addrevisioncb(self, node) |
|
547 | addrevisioncb(self, node) | |
|
548 | return nodes | |||
492 |
|
549 | |||
493 | return nodes |
|
550 | def _headrevs(self): | |
|
551 | # Assume all revisions are heads by default. | |||
|
552 | revishead = {rev: True for rev in self._indexbyrev} | |||
|
553 | ||||
|
554 | for rev, entry in self._indexbyrev.items(): | |||
|
555 | # Unset head flag for all seen parents. | |||
|
556 | revishead[self.rev(entry[b'p1'])] = False | |||
|
557 | revishead[self.rev(entry[b'p2'])] = False | |||
|
558 | ||||
|
559 | return [rev for rev, ishead in sorted(revishead.items()) | |||
|
560 | if ishead] | |||
494 |
|
561 | |||
495 | def heads(self, start=None, stop=None): |
|
562 | def heads(self, start=None, stop=None): | |
496 | # This is copied from revlog.py. |
|
563 | # This is copied from revlog.py. | |
497 | if start is None and stop is None: |
|
564 | if start is None and stop is None: | |
498 | if not len(self): |
|
565 | if not len(self): | |
499 | return [nullid] |
|
566 | return [nullid] | |
500 | return [self.node(r) for r in self.headrevs()] |
|
567 | return [self.node(r) for r in self._headrevs()] | |
501 |
|
568 | |||
502 | if start is None: |
|
569 | if start is None: | |
503 | start = nullid |
|
570 | start = nullid | |
@@ -537,41 +604,9 b' class filestorage(object):' | |||||
537 | return c |
|
604 | return c | |
538 |
|
605 | |||
539 | def getstrippoint(self, minlink): |
|
606 | def getstrippoint(self, minlink): | |
540 |
|
607 | return storageutil.resolvestripinfo( | ||
541 | # This is largely a copy of revlog.getstrippoint(). |
|
608 | minlink, len(self) - 1, self._headrevs(), self.linkrev, | |
542 | brokenrevs = set() |
|
609 | self.parentrevs) | |
543 | strippoint = len(self) |
|
|||
544 |
|
||||
545 | heads = {} |
|
|||
546 | futurelargelinkrevs = set() |
|
|||
547 | for head in self.heads(): |
|
|||
548 | headlinkrev = self.linkrev(self.rev(head)) |
|
|||
549 | heads[head] = headlinkrev |
|
|||
550 | if headlinkrev >= minlink: |
|
|||
551 | futurelargelinkrevs.add(headlinkrev) |
|
|||
552 |
|
||||
553 | # This algorithm involves walking down the rev graph, starting at the |
|
|||
554 | # heads. Since the revs are topologically sorted according to linkrev, |
|
|||
555 | # once all head linkrevs are below the minlink, we know there are |
|
|||
556 | # no more revs that could have a linkrev greater than minlink. |
|
|||
557 | # So we can stop walking. |
|
|||
558 | while futurelargelinkrevs: |
|
|||
559 | strippoint -= 1 |
|
|||
560 | linkrev = heads.pop(strippoint) |
|
|||
561 |
|
||||
562 | if linkrev < minlink: |
|
|||
563 | brokenrevs.add(strippoint) |
|
|||
564 | else: |
|
|||
565 | futurelargelinkrevs.remove(linkrev) |
|
|||
566 |
|
||||
567 | for p in self.parentrevs(strippoint): |
|
|||
568 | if p != nullrev: |
|
|||
569 | plinkrev = self.linkrev(p) |
|
|||
570 | heads[p] = plinkrev |
|
|||
571 | if plinkrev >= minlink: |
|
|||
572 | futurelargelinkrevs.add(plinkrev) |
|
|||
573 |
|
||||
574 | return strippoint, brokenrevs |
|
|||
575 |
|
610 | |||
576 | def strip(self, minlink, transaction): |
|
611 | def strip(self, minlink, transaction): | |
577 | if not len(self): |
|
612 | if not len(self): | |
@@ -631,9 +666,9 b' def reposetup(ui, repo):' | |||||
631 | def featuresetup(ui, supported): |
|
666 | def featuresetup(ui, supported): | |
632 | supported.add(REQUIREMENT) |
|
667 | supported.add(REQUIREMENT) | |
633 |
|
668 | |||
634 | def newreporequirements(orig, ui): |
|
669 | def newreporequirements(orig, ui, createopts): | |
635 | """Modifies default requirements for new repos to use the simple store.""" |
|
670 | """Modifies default requirements for new repos to use the simple store.""" | |
636 | requirements = orig(ui) |
|
671 | requirements = orig(ui, createopts) | |
637 |
|
672 | |||
638 | # These requirements are only used to affect creation of the store |
|
673 | # These requirements are only used to affect creation of the store | |
639 | # object. We have our own store. So we can remove them. |
|
674 | # object. We have our own store. So we can remove them. | |
@@ -665,5 +700,5 b' def extsetup(ui):' | |||||
665 |
|
700 | |||
666 | extensions.wrapfunction(localrepo, 'newreporequirements', |
|
701 | extensions.wrapfunction(localrepo, 'newreporequirements', | |
667 | newreporequirements) |
|
702 | newreporequirements) | |
668 |
extensions.wrapfunction( |
|
703 | extensions.wrapfunction(localrepo, 'makestore', makestore) | |
669 | extensions.wrapfunction(verify.verifier, '__init__', verifierinit) |
|
704 | extensions.wrapfunction(verify.verifier, '__init__', verifierinit) |
General Comments 0
You need to be logged in to leave comments.
Login now