comparison mercurial/revlog.py @ 51178:dcaa2df1f688

changelog: never inline changelog The test suite mostly use small repositories, that implies that most changelog in the tests are inlined. As a result, non-inlined changelog are quite poorly tested. Since non-inline changelog are most common case for serious repositories, this lack of testing is a significant problem that results in high profile issue like the one recently fixed by 66417f55ea33 and 849745d7da89. Inlining the changelog does not bring much to the table, the number of total file saved is negligible, and the changelog will be read by most operation anyway. So this changeset is make it so we never inline the changelog, and de-inline the one that are still inlined whenever we touch them. By doing that, we remove the "dual code path" situation for writing new entry to the changelog and move to a "single code path" situation. Having a single code path simplify the code and make sure it is covered by test (if test cover that situation obviously) This impact all tests that care about the number of file and the exchange size, but there is nothing too complicated in them just a lot of churn. The churn is made "worse" by the fact rust will use the persistent nodemap on any changelog now. Which is overall a win as it means testing the persistent nodemap more and having less special cases. In short, having inline changelog is mostly useless and an endless source of pain. We get rid of it.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 11 Dec 2023 22:27:59 +0100
parents 849745d7da89
children a93e52f0b6ff
comparison
equal deleted inserted replaced
51177:2e0b2a387502 51178:dcaa2df1f688
1389 1389
1390 chunk_cache = self._loadindex() 1390 chunk_cache = self._loadindex()
1391 self._load_inner(chunk_cache) 1391 self._load_inner(chunk_cache)
1392 self._concurrencychecker = concurrencychecker 1392 self._concurrencychecker = concurrencychecker
1393 1393
1394 @property
1395 def _generaldelta(self):
1396 """temporary compatibility proxy"""
1397 util.nouideprecwarn(
1398 b"use revlog.delta_config.general_delta", b"6.6", stacklevel=2
1399 )
1400 return self.delta_config.general_delta
1401
1402 @property
1403 def _checkambig(self):
1404 """temporary compatibility proxy"""
1405 util.nouideprecwarn(
1406 b"use revlog.data_config.checkambig", b"6.6", stacklevel=2
1407 )
1408 return self.data_config.check_ambig
1409
1410 @property
1411 def _mmaplargeindex(self):
1412 """temporary compatibility proxy"""
1413 util.nouideprecwarn(
1414 b"use revlog.data_config.mmap_large_index", b"6.6", stacklevel=2
1415 )
1416 return self.data_config.mmap_large_index
1417
1418 @property
1419 def _censorable(self):
1420 """temporary compatibility proxy"""
1421 util.nouideprecwarn(
1422 b"use revlog.feature_config.censorable", b"6.6", stacklevel=2
1423 )
1424 return self.feature_config.censorable
1425
1426 @property
1427 def _chunkcachesize(self):
1428 """temporary compatibility proxy"""
1429 util.nouideprecwarn(
1430 b"use revlog.data_config.chunk_cache_size", b"6.6", stacklevel=2
1431 )
1432 return self.data_config.chunk_cache_size
1433
1434 @property
1435 def _maxchainlen(self):
1436 """temporary compatibility proxy"""
1437 util.nouideprecwarn(
1438 b"use revlog.delta_config.max_chain_len", b"6.6", stacklevel=2
1439 )
1440 return self.delta_config.max_chain_len
1441
1442 @property
1443 def _deltabothparents(self):
1444 """temporary compatibility proxy"""
1445 util.nouideprecwarn(
1446 b"use revlog.delta_config.delta_both_parents", b"6.6", stacklevel=2
1447 )
1448 return self.delta_config.delta_both_parents
1449
1450 @property
1451 def _candidate_group_chunk_size(self):
1452 """temporary compatibility proxy"""
1453 util.nouideprecwarn(
1454 b"use revlog.delta_config.candidate_group_chunk_size",
1455 b"6.6",
1456 stacklevel=2,
1457 )
1458 return self.delta_config.candidate_group_chunk_size
1459
1460 @property
1461 def _debug_delta(self):
1462 """temporary compatibility proxy"""
1463 util.nouideprecwarn(
1464 b"use revlog.delta_config.debug_delta", b"6.6", stacklevel=2
1465 )
1466 return self.delta_config.debug_delta
1467
1468 @property
1469 def _compengine(self):
1470 """temporary compatibility proxy"""
1471 util.nouideprecwarn(
1472 b"use revlog.feature_config.compression_engine",
1473 b"6.6",
1474 stacklevel=2,
1475 )
1476 return self.feature_config.compression_engine
1477
1478 @property
1479 def upperboundcomp(self):
1480 """temporary compatibility proxy"""
1481 util.nouideprecwarn(
1482 b"use revlog.delta_config.upper_bound_comp",
1483 b"6.6",
1484 stacklevel=2,
1485 )
1486 return self.delta_config.upper_bound_comp
1487
1488 @property
1489 def _compengineopts(self):
1490 """temporary compatibility proxy"""
1491 util.nouideprecwarn(
1492 b"use revlog.feature_config.compression_engine_options",
1493 b"6.6",
1494 stacklevel=2,
1495 )
1496 return self.feature_config.compression_engine_options
1497
1498 @property
1499 def _maxdeltachainspan(self):
1500 """temporary compatibility proxy"""
1501 util.nouideprecwarn(
1502 b"use revlog.delta_config.max_deltachain_span", b"6.6", stacklevel=2
1503 )
1504 return self.delta_config.max_deltachain_span
1505
1506 @property
1507 def _withsparseread(self):
1508 """temporary compatibility proxy"""
1509 util.nouideprecwarn(
1510 b"use revlog.data_config.with_sparse_read", b"6.6", stacklevel=2
1511 )
1512 return self.data_config.with_sparse_read
1513
1514 @property
1515 def _sparserevlog(self):
1516 """temporary compatibility proxy"""
1517 util.nouideprecwarn(
1518 b"use revlog.delta_config.sparse_revlog", b"6.6", stacklevel=2
1519 )
1520 return self.delta_config.sparse_revlog
1521
1522 @property
1523 def hassidedata(self):
1524 """temporary compatibility proxy"""
1525 util.nouideprecwarn(
1526 b"use revlog.feature_config.has_side_data", b"6.6", stacklevel=2
1527 )
1528 return self.feature_config.has_side_data
1529
1530 @property
1531 def _srdensitythreshold(self):
1532 """temporary compatibility proxy"""
1533 util.nouideprecwarn(
1534 b"use revlog.data_config.sr_density_threshold",
1535 b"6.6",
1536 stacklevel=2,
1537 )
1538 return self.data_config.sr_density_threshold
1539
1540 @property
1541 def _srmingapsize(self):
1542 """temporary compatibility proxy"""
1543 util.nouideprecwarn(
1544 b"use revlog.data_config.sr_min_gap_size", b"6.6", stacklevel=2
1545 )
1546 return self.data_config.sr_min_gap_size
1547
1548 @property
1549 def _compute_rank(self):
1550 """temporary compatibility proxy"""
1551 util.nouideprecwarn(
1552 b"use revlog.feature_config.compute_rank", b"6.6", stacklevel=2
1553 )
1554 return self.feature_config.compute_rank
1555
1556 @property
1557 def canonical_parent_order(self):
1558 """temporary compatibility proxy"""
1559 util.nouideprecwarn(
1560 b"use revlog.feature_config.canonical_parent_order",
1561 b"6.6",
1562 stacklevel=2,
1563 )
1564 return self.feature_config.canonical_parent_order
1565
1566 @property
1567 def _lazydelta(self):
1568 """temporary compatibility proxy"""
1569 util.nouideprecwarn(
1570 b"use revlog.delta_config.lazy_delta", b"6.6", stacklevel=2
1571 )
1572 return self.delta_config.lazy_delta
1573
1574 @property
1575 def _lazydeltabase(self):
1576 """temporary compatibility proxy"""
1577 util.nouideprecwarn(
1578 b"use revlog.delta_config.lazy_delta_base", b"6.6", stacklevel=2
1579 )
1580 return self.delta_config.lazy_delta_base
1581
1582 def _init_opts(self): 1394 def _init_opts(self):
1583 """process options (from above/config) to setup associated default revlog mode 1395 """process options (from above/config) to setup associated default revlog mode
1584 1396
1585 These values might be affected when actually reading on disk information. 1397 These values might be affected when actually reading on disk information.
1586 1398
3024 2836
3025 if self._docket is not None: 2837 if self._docket is not None:
3026 msg = b"inline revlog should not have a docket" 2838 msg = b"inline revlog should not have a docket"
3027 raise error.ProgrammingError(msg) 2839 raise error.ProgrammingError(msg)
3028 2840
2841 # In the common case, we enforce inline size because the revlog has
2842 # been appened too. And in such case, it must have an initial offset
2843 # recorded in the transaction.
3029 troffset = tr.findoffset(self._inner.canonical_index_file) 2844 troffset = tr.findoffset(self._inner.canonical_index_file)
3030 if troffset is None: 2845 pre_touched = troffset is not None
2846 if not pre_touched and self.target[0] != KIND_CHANGELOG:
3031 raise error.RevlogError( 2847 raise error.RevlogError(
3032 _(b"%s not found in the transaction") % self._indexfile 2848 _(b"%s not found in the transaction") % self._indexfile
3033 ) 2849 )
3034 if troffset: 2850
3035 tr.addbackup(self._inner.canonical_index_file, for_offset=True) 2851 tr.addbackup(self._inner.canonical_index_file, for_offset=pre_touched)
3036 tr.add(self._datafile, 0) 2852 tr.add(self._datafile, 0)
3037 2853
3038 new_index_file_path = None 2854 new_index_file_path = None
3039 if side_write: 2855 if side_write:
3040 old_index_file_path = self._indexfile 2856 old_index_file_path = self._indexfile