You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/10/21 16:04:39 UTC
svn commit: r1709846 - in /subversion/trunk/subversion/libsvn_fs_x: ./
cached_data.c temp_serializer.c temp_serializer.h transaction.c
Author: stefan2
Date: Wed Oct 21 14:04:39 2015
New Revision: 1709846
URL: http://svn.apache.org/viewvc?rev=1709846&view=rev
Log:
Merge the in-txn directory handling speedup from FSFS to FSX, resolve text
conflicts and use proper svn_fs_x__* identifiers.
This merges revisions r1706617, 1706619, 1706675-1706676, 1706679 and 1707308
from FSFS to FSX.
Modified:
subversion/trunk/subversion/libsvn_fs_x/ (props changed)
subversion/trunk/subversion/libsvn_fs_x/cached_data.c
subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c
subversion/trunk/subversion/libsvn_fs_x/temp_serializer.h
subversion/trunk/subversion/libsvn_fs_x/transaction.c
Propchange: subversion/trunk/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Oct 21 14:04:39 2015
@@ -93,5 +93,5 @@
/subversion/branches/verify-at-commit/subversion/libsvn_fs_x:1462039-1462408
/subversion/branches/verify-keep-going/subversion/libsvn_fs_x:1439280-1492639,1546002-1546110
/subversion/branches/wc-collate-path/subversion/libsvn_fs_x:1402685-1480384
-/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1649590,
1651567,1652068,1652076,1652441,1653608,1654932,1654934,1654937,1655635,1655664,1657525,1657972,1657978,1658482,1659212,1659217,1659314,1659509,1662668,1665318,1665854,1665894,1667090,1667101,1667538,1669743,1669746,1669749,1669945,1670139,1670953,1673170,1673445,1673454,1673685,1673689,1673875,1674165,1674341,1674400,1674404,1674631,1674669,1674673,1675396,1676667,1677431,1678151,1678718,1678725,1679169,1679907,1679920-1679924,1679926,1680347,1681949,1681966,1682008,1682076,1682739,1682864,1683311,1683553,1684047,1686232,1686546,1687061,1687064,1688425,1692650,1693886,1694489,1694848,1696171,1696185,1696627-1696628,1696630,1696758,1697372,1697381,1697387,1697393,1697403,1697405,1701017,1702600,1702922,1703142,1703237,1703240,1705266,1705638,1705643,1705724,1705730,1705739,1707971-1707973,1707986,1707988-1707989,1708004
+/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1649590,
1651567,1652068,1652076,1652441,1653608,1654932,1654934,1654937,1655635,1655664,1657525,1657972,1657978,1658482,1659212,1659217,1659314,1659509,1662668,1665318,1665854,1665894,1667090,1667101,1667538,1669743,1669746,1669749,1669945,1670139,1670953,1673170,1673445,1673454,1673685,1673689,1673875,1674165,1674341,1674400,1674404,1674631,1674669,1674673,1675396,1676667,1677431,1678151,1678718,1678725,1679169,1679907,1679920-1679924,1679926,1680347,1681949,1681966,1682008,1682076,1682739,1682864,1683311,1683553,1684047,1686232,1686546,1687061,1687064,1688425,1692650,1693886,1694489,1694848,1696171,1696185,1696627-1696628,1696630,1696758,1697372,1697381,1697387,1697393,1697403,1697405,1701017,1702600,1702922,1703142,1703237,1703240,1705266,1705638,1705643,1705724,1705730,1705739,1706617,1706619,1706675-1706676,1706679,1707308,1707971-1707973,1707986,1707988-1707989,1708004
/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914
Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.c?rev=1709846&r1=1709845&r2=1709846&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.c Wed Oct 21 14:04:39 2015
@@ -2578,26 +2578,24 @@ locate_dir_cache(svn_fs_t *fs,
svn_fs_x__noderev_t *noderev)
{
svn_fs_x__data_t *ffd = fs->fsap_data;
- if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
+
+ if (!noderev->data_rep)
+ {
+ /* no data rep -> empty directory.
+ Use a key that does definitely not clash with non-NULL reps. */
+ key->change_set = SVN_FS_X__INVALID_CHANGE_SET;
+ key->number = SVN_FS_X__ITEM_INDEX_UNUSED;
+ }
+ else if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
{
- /* data in txns must be addressed by ID since the representation has
- not been created, yet. */
+ /* data in txns must be addressed by noderev ID since the
+ representation has not been created, yet. */
*key = noderev->noderev_id;
}
else
{
/* committed data can use simple rev,item pairs */
- if (noderev->data_rep)
- {
- *key = noderev->data_rep->id;
- }
- else
- {
- /* no data rep -> empty directory.
- Use a key that does definitely not clash with non-NULL reps. */
- key->change_set = SVN_FS_X__INVALID_CHANGE_SET;
- key->number = SVN_FS_X__ITEM_INDEX_UNUSED;
- }
+ *key = noderev->data_rep->id;
}
return ffd->dir_cache;
Modified: subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c?rev=1709846&r1=1709845&r2=1709846&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c Wed Oct 21 14:04:39 2015
@@ -1038,6 +1038,18 @@ svn_fs_x__replace_dir_entry(void **data,
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_fs_x__reset_txn_filesize(void **data,
+ apr_size_t *data_len,
+ void *baton,
+ apr_pool_t *pool)
+{
+ dir_data_t *dir_data = (dir_data_t *)*data;
+ dir_data->txn_filesize = SVN_INVALID_FILESIZE;
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_fs_x__serialize_rep_header(void **data,
apr_size_t *data_len,
Modified: subversion/trunk/subversion/libsvn_fs_x/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/temp_serializer.h?rev=1709846&r1=1709845&r2=1709846&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/temp_serializer.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/temp_serializer.h Wed Oct 21 14:04:39 2015
@@ -232,6 +232,17 @@ svn_fs_x__replace_dir_entry(void **data,
apr_pool_t *pool);
/**
+ * Implements #svn_cache__partial_setter_func_t for a #svn_fs_x__dir_data_t
+ * at @a *data, resetting its txn_filesize field to SVN_INVALID_FILESIZE.
+ * &a baton should be NULL.
+ */
+svn_error_t *
+svn_fs_x__reset_txn_filesize(void **data,
+ apr_size_t *data_len,
+ void *baton,
+ apr_pool_t *pool);
+
+/**
* Implements #svn_cache__serialize_func_t for a #svn_fs_x__rep_header_t.
*/
svn_error_t *
Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.c?rev=1709846&r1=1709845&r2=1709846&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.c Wed Oct 21 14:04:39 2015
@@ -860,16 +860,63 @@ unparse_dir_entry(svn_fs_x__dirent_t *di
svn_stream_t *stream,
apr_pool_t *scratch_pool)
{
- const char *val
- = apr_psprintf(scratch_pool, "%s %s",
- (dirent->kind == svn_node_file) ? SVN_FS_X__KIND_FILE
- : SVN_FS_X__KIND_DIR,
- svn_fs_x__id_unparse(&dirent->id, scratch_pool)->data);
-
- SVN_ERR(svn_stream_printf(stream, scratch_pool, "K %" APR_SIZE_T_FMT
- "\n%s\nV %" APR_SIZE_T_FMT "\n%s\n",
- strlen(dirent->name), dirent->name,
- strlen(val), val));
+ apr_size_t to_write;
+ svn_string_t *id_str = svn_fs_x__id_unparse(&dirent->id, scratch_pool);
+ apr_size_t name_len = strlen(dirent->name);
+
+ /* Note that sizeof == len + 1, i.e. accounts for the space between
+ * type and ID. */
+ apr_size_t type_len = (dirent->kind == svn_node_file)
+ ? sizeof(SVN_FS_X__KIND_FILE)
+ : sizeof(SVN_FS_X__KIND_DIR);
+ apr_size_t value_len = type_len + id_str->len;
+
+ /* A buffer with sufficient space for
+ * - both string lines
+ * - 4 newlines
+ * - 2 lines K/V lines containing a number each
+ */
+ char *buffer = apr_palloc(scratch_pool, name_len + value_len
+ + 4
+ + 2 * (2 + SVN_INT64_BUFFER_SIZE));
+
+ /* Now construct the value. */
+ char *p = buffer;
+
+ /* The "K length(name)\n" line. */
+ p[0] = 'K';
+ p[1] = ' ';
+ p += 2;
+ p += svn__i64toa(p, name_len);
+ *(p++) = '\n';
+
+ /* The line with the key, i.e. dir entry name. */
+ memcpy(p, dirent->name, name_len);
+ p += name_len;
+ *(p++) = '\n';
+
+ /* The "V length(type+id)\n" line. */
+ p[0] = 'V';
+ p[1] = ' ';
+ p += 2;
+ p += svn__i64toa(p, value_len);
+ *(p++) = '\n';
+
+ /* The line with the type and ID. */
+ memcpy(p,
+ (dirent->kind == svn_node_file) ? SVN_FS_X__KIND_FILE
+ : SVN_FS_X__KIND_DIR,
+ type_len - 1);
+ p += type_len - 1;
+ *(p++) = ' ';
+ memcpy(p, id_str->data, id_str->len);
+ p+=id_str->len;
+ *(p++) = '\n';
+
+ /* Add the entry to the output stream. */
+ to_write = p - buffer;
+ SVN_ERR(svn_stream_write(stream, buffer, &to_write));
+
return SVN_NO_ERROR;
}
@@ -1795,10 +1842,12 @@ svn_fs_x__set_entry(svn_fs_t *fs,
svn_filesize_t filesize;
svn_fs_x__data_t *ffd = fs->fsap_data;
apr_pool_t *subpool = svn_pool_create(scratch_pool);
+ const svn_fs_x__id_t *key = &(parent_noderev->noderev_id);
if (!rep || !svn_fs_x__is_txn(rep->id.change_set))
{
apr_array_header_t *entries;
+ svn_fs_x__dir_data_t dir_data;
/* Before we can modify the directory, we need to dump its old
contents into a mutable representation file. */
@@ -1810,8 +1859,6 @@ svn_fs_x__set_entry(svn_fs_t *fs,
out = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
SVN_ERR(unparse_dir_entries(entries, out, subpool));
- svn_pool_clear(subpool);
-
/* Provide the parent with a data rep if it had none before
(directories so far empty). */
if (!rep)
@@ -1826,10 +1873,25 @@ svn_fs_x__set_entry(svn_fs_t *fs,
/* Save noderev to disk. */
SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev, subpool));
+
+ /* Immediately populate the txn dir cache to avoid re-reading
+ * the file we just wrote. */
+
+ /* Flush APR buffers. */
+ SVN_ERR(svn_io_file_flush(file, subpool));
+
+ /* Obtain final file size to update txn_dir_cache. */
+ SVN_ERR(svn_io_file_size_get(&filesize, file, subpool));
+
+ /* Store in the cache. */
+ dir_data.entries = entries;
+ dir_data.txn_filesize = filesize;
+ SVN_ERR(svn_cache__set(ffd->dir_cache, key, &dir_data, subpool));
+
+ svn_pool_clear(subpool);
}
else
{
- const svn_fs_x__id_t *key = &(parent_noderev->noderev_id);
svn_boolean_t found;
svn_filesize_t cached_filesize;
@@ -1890,7 +1952,6 @@ svn_fs_x__set_entry(svn_fs_t *fs,
/* update directory cache */
{
/* build parameters: name, new entry, new file size */
- const svn_fs_x__id_t *key = &(parent_noderev->noderev_id);
replace_baton_t baton;
baton.name = name;
@@ -2338,6 +2399,10 @@ get_shared_rep(svn_fs_x__representation_
if (!ffd->rep_sharing_allowed)
return SVN_NO_ERROR;
+ /* Can't look up if we don't know the key (happens for directories). */
+ if (!rep->has_sha1)
+ return SVN_NO_ERROR;
+
/* Check and see if we already have a representation somewhere that's
identical to the one we just wrote out. Start with the hash lookup
because it is cheapest. */
@@ -2457,6 +2522,7 @@ get_shared_rep(svn_fs_x__representation_
}
/* Copy the hash sum calculation results from MD5_CTX, SHA1_CTX into REP.
+ * SHA1 results are only be set if SHA1_CTX is not NULL.
* Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
@@ -2469,10 +2535,12 @@ digests_final(svn_fs_x__representation_t
SVN_ERR(svn_checksum_final(&checksum, md5_ctx, scratch_pool));
memcpy(rep->md5_digest, checksum->digest, svn_checksum_size(checksum));
- SVN_ERR(svn_checksum_final(&checksum, sha1_ctx, scratch_pool));
- rep->has_sha1 = checksum != NULL;
+ rep->has_sha1 = sha1_ctx != NULL;
if (rep->has_sha1)
- memcpy(rep->sha1_digest, checksum->digest, svn_checksum_size(checksum));
+ {
+ SVN_ERR(svn_checksum_final(&checksum, sha1_ctx, scratch_pool));
+ memcpy(rep->sha1_digest, checksum->digest, svn_checksum_size(checksum));
+ }
return SVN_NO_ERROR;
}
@@ -2676,6 +2744,8 @@ typedef struct write_container_baton_t
apr_size_t size;
svn_checksum_ctx_t *md5_ctx;
+
+ /* SHA1 calculation is optional. If not needed, this will be NULL. */
svn_checksum_ctx_t *sha1_ctx;
} write_container_baton_t;
@@ -2690,7 +2760,8 @@ write_container_handler(void *baton,
write_container_baton_t *whb = baton;
SVN_ERR(svn_checksum_update(whb->md5_ctx, data, *len));
- SVN_ERR(svn_checksum_update(whb->sha1_ctx, data, *len));
+ if (whb->sha1_ctx)
+ SVN_ERR(svn_checksum_update(whb->sha1_ctx, data, *len));
SVN_ERR(svn_stream_write(whb->stream, data, len));
whb->size += *len;
@@ -2820,7 +2891,8 @@ write_container_delta_rep(svn_fs_x__repr
scratch_pool);
whb->size = 0;
whb->md5_ctx = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
- whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, scratch_pool);
+ if (item_type != SVN_FS_X__ITEM_TYPE_DIR_REP)
+ whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, scratch_pool);
/* serialize the hash */
stream = svn_stream_create(whb, scratch_pool);
@@ -2965,6 +3037,9 @@ get_final_id(svn_fs_x__id_t *part,
INITIAL_OFFSET is the offset of the proto-rev-file on entry to
commit_body.
+ Collect the pair_cache_key_t of all directories written to the
+ committed cache in DIRECTORY_IDS.
+
If REPS_TO_CACHE is not NULL, append to it a copy (allocated in
REPS_POOL) of each data rep that is new in this revision.
@@ -2984,6 +3059,7 @@ write_final_rev(svn_fs_x__id_t *new_id_p
svn_fs_t *fs,
const svn_fs_x__id_t *id,
apr_off_t initial_offset,
+ apr_array_header_t *directory_ids,
apr_array_header_t *reps_to_cache,
apr_hash_t *reps_hash,
apr_pool_t *reps_pool,
@@ -3028,7 +3104,8 @@ write_final_rev(svn_fs_x__id_t *new_id_p
svn_pool_clear(subpool);
SVN_ERR(write_final_rev(&new_id, file, rev, fs, &dirent->id,
- initial_offset, reps_to_cache, reps_hash,
+ initial_offset, directory_ids,
+ reps_to_cache, reps_hash,
reps_pool, FALSE, subpool));
if ( svn_fs_x__id_used(&new_id)
&& (svn_fs_x__get_revnum(new_id.change_set) == rev))
@@ -3038,6 +3115,9 @@ write_final_rev(svn_fs_x__id_t *new_id_p
if (noderev->data_rep
&& ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
{
+ svn_fs_x__pair_cache_key_t *key;
+ svn_fs_x__dir_data_t dir_data;
+
/* Write out the contents of this directory as a text rep. */
noderev->data_rep->id.change_set = change_set;
SVN_ERR(write_container_delta_rep(noderev->data_rep, file,
@@ -3046,6 +3126,23 @@ write_final_rev(svn_fs_x__id_t *new_id_p
fs, txn_id, noderev, NULL,
SVN_FS_X__ITEM_TYPE_DIR_REP,
rev, scratch_pool));
+
+ /* Cache the new directory contents. Otherwise, subsequent reads
+ * or commits will likely have to reconstruct, verify and parse
+ * it again. */
+ key = apr_array_push(directory_ids);
+ key->revision = noderev->data_rep->id.change_set;
+ key->second = noderev->data_rep->id.number;
+
+ /* Store directory contents under the new revision number but mark
+ * it as "stale" by setting the file length to 0. Committed dirs
+ * will report -1, in-txn dirs will report > 0, so that this can
+ * never match. We reset that to -1 after the commit is complete.
+ */
+ dir_data.entries = entries;
+ dir_data.txn_filesize = 0;
+
+ SVN_ERR(svn_cache__set(ffd->dir_cache, key, &dir_data, subpool));
}
}
else
@@ -3591,6 +3688,41 @@ bump_ids(void *baton,
return SVN_NO_ERROR;
}
+/* Mark the directories cached in FS with the keys from DIRECTORY_IDS
+ * as "valid" now. Use SCRATCH_POOL for temporaries. */
+static svn_error_t *
+promote_cached_directories(svn_fs_t *fs,
+ apr_array_header_t *directory_ids,
+ apr_pool_t *scratch_pool)
+{
+ svn_fs_x__data_t *ffd = fs->fsap_data;
+ apr_pool_t *iterpool;
+ int i;
+
+ if (!ffd->dir_cache)
+ return SVN_NO_ERROR;
+
+ iterpool = svn_pool_create(scratch_pool);
+ for (i = 0; i < directory_ids->nelts; ++i)
+ {
+ const svn_fs_x__pair_cache_key_t *key
+ = &APR_ARRAY_IDX(directory_ids, i, svn_fs_x__pair_cache_key_t);
+
+ svn_pool_clear(iterpool);
+
+ /* Currently, the entry for KEY - if it still exists - is marked
+ * as "stale" and would not be used. Mark it as current for in-
+ * revison data. */
+ SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key,
+ svn_fs_x__reset_txn_filesize, NULL,
+ iterpool));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
/* Baton used for commit_body below. */
typedef struct commit_baton_t {
svn_revnum_t *new_rev_p;
@@ -3620,6 +3752,8 @@ commit_body(void *baton,
apr_hash_t *changed_paths;
svn_fs_x__batch_fsync_t *batch;
bump_ids_baton_t bump_ids_baton;
+ apr_array_header_t *directory_ids
+ = apr_array_make(scratch_pool, 4, sizeof(svn_fs_x__pair_cache_key_t));
/* We perform a sequence of (potentially) large allocations.
Keep the peak memory usage low by using a SUBPOOL and cleaning it
@@ -3681,8 +3815,8 @@ commit_body(void *baton,
/* Write out all the node-revisions and directory contents. */
svn_fs_x__init_txn_root(&root_id, txn_id);
SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, &root_id,
- initial_offset, cb->reps_to_cache, cb->reps_hash,
- cb->reps_pool, TRUE, subpool));
+ initial_offset, directory_ids, cb->reps_to_cache,
+ cb->reps_hash, cb->reps_pool, TRUE, subpool));
svn_pool_clear(subpool);
/* Write the changed-path information. */
@@ -3735,6 +3869,10 @@ commit_body(void *baton,
ffd->youngest_rev_cache = new_rev;
+ /* Make the directory contents already cached for the new revision
+ * visible. */
+ SVN_ERR(promote_cached_directories(cb->fs, directory_ids, subpool));
+
/* Remove this transaction directory. */
SVN_ERR(svn_fs_x__purge_txn(cb->fs, cb->txn->id, subpool));