comparison mercurial/revlog.py @ 45788:a5206e71c536

revlog: extend addgroup() with callback for duplicates The addgroup() interface currently doesn't allow the caller to keep track of duplicated nodes except by looking at the returned node list. Add an optional second callback for this purpose and change the return type to a boolean. This allows follow-up changes to use more efficient storage for the node list in places that are memory-sensitive. Differential Revision: https://phab.mercurial-scm.org/D9231
author Joerg Sonnenberger <joerg@bec.de>
date Sun, 18 Oct 2020 22:18:02 +0200
parents 8719a5b68419
children 11842aad3195
comparison
equal deleted inserted replaced
45787:225e513c444e 45788:a5206e71c536
2366 ifh.write(data[0]) 2366 ifh.write(data[0])
2367 ifh.write(data[1]) 2367 ifh.write(data[1])
2368 self._enforceinlinesize(transaction, ifh) 2368 self._enforceinlinesize(transaction, ifh)
2369 nodemaputil.setup_persistent_nodemap(transaction, self) 2369 nodemaputil.setup_persistent_nodemap(transaction, self)
2370 2370
2371 def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None): 2371 def addgroup(
2372 self,
2373 deltas,
2374 linkmapper,
2375 transaction,
2376 addrevisioncb=None,
2377 duplicaterevisioncb=None,
2378 ):
2372 """ 2379 """
2373 add a delta group 2380 add a delta group
2374 2381
2375 given a set of deltas, add them to the revision log. the 2382 given a set of deltas, add them to the revision log. the
2376 first delta is against its parent, which should be in our 2383 first delta is against its parent, which should be in our
2380 this revlog and the node that was added. 2387 this revlog and the node that was added.
2381 """ 2388 """
2382 2389
2383 if self._writinghandles: 2390 if self._writinghandles:
2384 raise error.ProgrammingError(b'cannot nest addgroup() calls') 2391 raise error.ProgrammingError(b'cannot nest addgroup() calls')
2385
2386 nodes = []
2387 2392
2388 r = len(self) 2393 r = len(self)
2389 end = 0 2394 end = 0
2390 if r: 2395 if r:
2391 end = self.end(r - 1) 2396 end = self.end(r - 1)
2403 if dfh: 2408 if dfh:
2404 dfh.flush() 2409 dfh.flush()
2405 ifh.flush() 2410 ifh.flush()
2406 2411
2407 self._writinghandles = (ifh, dfh) 2412 self._writinghandles = (ifh, dfh)
2413 empty = True
2408 2414
2409 try: 2415 try:
2410 deltacomputer = deltautil.deltacomputer(self) 2416 deltacomputer = deltautil.deltacomputer(self)
2411 # loop through our set of deltas 2417 # loop through our set of deltas
2412 for data in deltas: 2418 for data in deltas:
2413 node, p1, p2, linknode, deltabase, delta, flags = data 2419 node, p1, p2, linknode, deltabase, delta, flags = data
2414 link = linkmapper(linknode) 2420 link = linkmapper(linknode)
2415 flags = flags or REVIDX_DEFAULT_FLAGS 2421 flags = flags or REVIDX_DEFAULT_FLAGS
2416 2422
2417 nodes.append(node)
2418
2419 if self.index.has_node(node): 2423 if self.index.has_node(node):
2424 # this can happen if two branches make the same change
2420 self._nodeduplicatecallback(transaction, node) 2425 self._nodeduplicatecallback(transaction, node)
2421 # this can happen if two branches make the same change 2426 if duplicaterevisioncb:
2427 duplicaterevisioncb(self, node)
2428 empty = False
2422 continue 2429 continue
2423 2430
2424 for p in (p1, p2): 2431 for p in (p1, p2):
2425 if not self.index.has_node(p): 2432 if not self.index.has_node(p):
2426 raise error.LookupError( 2433 raise error.LookupError(
2470 deltacomputer=deltacomputer, 2477 deltacomputer=deltacomputer,
2471 ) 2478 )
2472 2479
2473 if addrevisioncb: 2480 if addrevisioncb:
2474 addrevisioncb(self, node) 2481 addrevisioncb(self, node)
2482 empty = False
2475 2483
2476 if not dfh and not self._inline: 2484 if not dfh and not self._inline:
2477 # addrevision switched from inline to conventional 2485 # addrevision switched from inline to conventional
2478 # reopen the index 2486 # reopen the index
2479 ifh.close() 2487 ifh.close()
2484 self._writinghandles = None 2492 self._writinghandles = None
2485 2493
2486 if dfh: 2494 if dfh:
2487 dfh.close() 2495 dfh.close()
2488 ifh.close() 2496 ifh.close()
2489 2497 return not empty
2490 return nodes
2491 2498
2492 def iscensored(self, rev): 2499 def iscensored(self, rev):
2493 """Check if a file revision is censored.""" 2500 """Check if a file revision is censored."""
2494 if not self._censorable: 2501 if not self._censorable:
2495 return False 2502 return False