You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2015/08/19 04:35:15 UTC
svn commit: r1696514 [4/10] - in /subversion/branches/patch-exec: ./
build/ac-macros/ notes/ subversion/bindings/javahl/native/
subversion/bindings/swig/ subversion/include/ subversion/include/private/
subversion/libsvn_client/ subversion/libsvn_fs_fs/...
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/index.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/index.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/index.c Wed Aug 19 02:35:12 2015
@@ -61,15 +61,9 @@ const apr_uint64_t off_t_max = (sizeof(a
*/
#define P2L_PROTO_INDEX_ENTRY_SIZE (6 * sizeof(apr_uint64_t))
-/* We put this string in front of the L2P index header. */
-#define L2P_STREAM_PREFIX "L2P-INDEX\n"
-
-/* We put this string in front of the P2L index header. */
-#define P2L_STREAM_PREFIX "P2L-INDEX\n"
-
/* Size of the buffer that will fit the index header prefixes. */
-#define STREAM_PREFIX_LEN MAX(sizeof(L2P_STREAM_PREFIX), \
- sizeof(P2L_STREAM_PREFIX))
+#define STREAM_PREFIX_LEN MAX(sizeof(SVN_FS_X__L2P_STREAM_PREFIX), \
+ sizeof(SVN_FS_X__P2L_STREAM_PREFIX))
/* Page tables in the log-to-phys index file exclusively contain entries
* of this type to describe position and size of a given page.
@@ -348,20 +342,15 @@ packed_stream_read(svn_fs_x__packed_numb
return SVN_NO_ERROR;
}
-/* Create and open a packed number stream reading from offsets START to
- * END in FILE and return it in *STREAM. Access the file in chunks of
- * BLOCK_SIZE bytes. Expect the stream to be prefixed by STREAM_PREFIX.
- * Allocate *STREAM in RESULT_POOL and use SCRATCH_POOL for temporaries.
- */
-static svn_error_t *
-packed_stream_open(svn_fs_x__packed_number_stream_t **stream,
- apr_file_t *file,
- apr_off_t start,
- apr_off_t end,
- const char *stream_prefix,
- apr_size_t block_size,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_error_t *
+svn_fs_x__packed_stream_open(svn_fs_x__packed_number_stream_t **stream,
+ apr_file_t *file,
+ apr_off_t start,
+ apr_off_t end,
+ const char *stream_prefix,
+ apr_size_t block_size,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
char buffer[STREAM_PREFIX_LEN + 1] = { 0 };
apr_size_t len = strlen(stream_prefix);
@@ -702,7 +691,8 @@ svn_fs_x__l2p_proto_index_add_entry(apr_
* read operations only.
*/
static apr_size_t
-encode_uint(unsigned char *p, apr_uint64_t value)
+encode_uint(unsigned char *p,
+ apr_uint64_t value)
{
unsigned char *start = p;
while (value >= 0x80)
@@ -720,7 +710,8 @@ encode_uint(unsigned char *p, apr_uint64
* This maps signed ints onto unsigned ones.
*/
static apr_size_t
-encode_int(unsigned char *p, apr_int64_t value)
+encode_int(unsigned char *p,
+ apr_int64_t value)
{
return encode_uint(p, (apr_uint64_t)(value < 0 ? -1 - 2*value : 2*value));
}
@@ -742,7 +733,9 @@ stream_write_encoded(svn_stream_t *strea
* Return the number of remaining entries in ARRAY after START.
*/
static int
-rle_array(apr_array_header_t *array, int start, int end)
+rle_array(apr_array_header_t *array,
+ int start,
+ int end)
{
int i;
int target = start;
@@ -1038,7 +1031,7 @@ svn_fs_x__l2p_index_append(svn_checksum_
/* write header info */
- SVN_ERR(svn_stream_puts(stream, L2P_STREAM_PREFIX));
+ SVN_ERR(svn_stream_puts(stream, SVN_FS_X__L2P_STREAM_PREFIX));
SVN_ERR(stream_write_encoded(stream, revision));
SVN_ERR(stream_write_encoded(stream, page_counts->nelts));
SVN_ERR(stream_write_encoded(stream, ffd->l2p_page_size));
@@ -1074,7 +1067,8 @@ svn_fs_x__l2p_index_append(svn_checksum_
* REVISION in FS.
*/
static svn_revnum_t
-base_revision(svn_fs_t *fs, svn_revnum_t revision)
+base_revision(svn_fs_t *fs,
+ svn_revnum_t revision)
{
svn_fs_x__data_t *ffd = fs->fsap_data;
return svn_fs_x__is_packed_rev(fs, revision)
@@ -1231,32 +1225,6 @@ expand_rle(apr_array_header_t *values,
return SVN_NO_ERROR;
}
-/* If REV_FILE->L2P_STREAM is NULL, create a new stream for the log-to-phys
- * index for REVISION in FS and return it in REV_FILE.
- */
-static svn_error_t *
-auto_open_l2p_index(svn_fs_x__revision_file_t *rev_file,
- svn_fs_t *fs,
- svn_revnum_t revision)
-{
- if (rev_file->l2p_stream == NULL)
- {
- svn_fs_x__data_t *ffd = fs->fsap_data;
-
- SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
- SVN_ERR(packed_stream_open(&rev_file->l2p_stream,
- rev_file->file,
- rev_file->l2p_offset,
- rev_file->p2l_offset,
- L2P_STREAM_PREFIX,
- (apr_size_t)ffd->block_size,
- rev_file->pool,
- rev_file->pool));
- }
-
- return SVN_NO_ERROR;
-}
-
/* Read the header data structure of the log-to-phys index for REVISION
* in FS and return it in *HEADER, allocated in RESULT_POOL. Use REV_FILE
* to access on-disk data. Use SCRATCH_POOL for temporary allocations.
@@ -1279,41 +1247,48 @@ get_l2p_header_body(l2p_header_t **heade
svn_revnum_t next_rev;
apr_array_header_t *expanded_values
= apr_array_make(scratch_pool, 16, sizeof(apr_uint64_t));
+ svn_fs_x__packed_number_stream_t *stream;
+ svn_fs_x__rev_file_info_t file_info;
+ svn_fs_x__index_info_t index_info;
+ /* What to look for. */
svn_fs_x__pair_cache_key_t key;
- key.revision = rev_file->start_revision;
- key.second = rev_file->is_packed;
-
- SVN_ERR(auto_open_l2p_index(rev_file, fs, revision));
- packed_stream_seek(rev_file->l2p_stream, 0);
+ SVN_ERR(svn_fs_x__rev_file_info(&file_info, rev_file));
+ key.revision = file_info.start_revision;
+ key.second = file_info.is_packed;
+
+ /* Access the L2P index stream. */
+ SVN_ERR(svn_fs_x__rev_file_l2p_index(&stream, rev_file));
+ SVN_ERR(svn_fs_x__rev_file_l2p_info(&index_info, rev_file));
+ packed_stream_seek(stream, 0);
/* Read the table sizes. Check the data for plausibility and
* consistency with other bits. */
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->first_revision = (svn_revnum_t)value;
- if (result->first_revision != rev_file->start_revision)
+ if (result->first_revision != file_info.start_revision)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Index rev / pack file revision numbers do not match"));
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->revision_count = (int)value;
if ( result->revision_count != 1
&& result->revision_count != (apr_uint64_t)ffd->max_files_per_dir)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Invalid number of revisions in L2P index"));
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->page_size = (apr_uint32_t)value;
if (!result->page_size || (result->page_size & (result->page_size - 1)))
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("L2P index page size is not a power of two"));
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
page_count = (apr_size_t)value;
if (page_count < result->revision_count)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Fewer L2P index pages than revisions"));
- if (page_count > (rev_file->p2l_offset - rev_file->l2p_offset) / 2)
+ if (page_count > (index_info.end - index_info.start) / 2)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("L2P index page count implausibly large"));
@@ -1333,8 +1308,7 @@ get_l2p_header_body(l2p_header_t **heade
/* read per-revision page table sizes (i.e. number of pages per rev) */
page_table_index = 0;
result->page_table_index[0] = page_table_index;
- SVN_ERR(expand_rle(expanded_values, rev_file->l2p_stream,
- result->revision_count));
+ SVN_ERR(expand_rle(expanded_values, stream, result->revision_count));
for (i = 0; i < result->revision_count; ++i)
{
value = (apr_size_t)APR_ARRAY_IDX(expanded_values, i, apr_uint64_t);
@@ -1357,13 +1331,13 @@ get_l2p_header_body(l2p_header_t **heade
/* read actual page tables */
for (page = 0; page < page_count; ++page)
{
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
if (value == 0)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Empty L2P index page"));
result->page_table[page].size = (apr_uint32_t)value;
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
if (value > result->page_size)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Page exceeds L2P index page size"));
@@ -1372,7 +1346,7 @@ get_l2p_header_body(l2p_header_t **heade
}
/* correct the page description offsets */
- offset = packed_stream_offset(rev_file->l2p_stream);
+ offset = packed_stream_offset(stream);
for (page = 0; page < page_count; ++page)
{
result->page_table[page].offset = offset;
@@ -1437,11 +1411,13 @@ get_l2p_header(l2p_header_t **header,
{
svn_fs_x__data_t *ffd = fs->fsap_data;
svn_boolean_t is_cached = FALSE;
+ svn_fs_x__rev_file_info_t file_info;
/* first, try cache lookop */
svn_fs_x__pair_cache_key_t key;
- key.revision = rev_file->start_revision;
- key.second = rev_file->is_packed;
+ SVN_ERR(svn_fs_x__rev_file_info(&file_info, rev_file));
+ key.revision = file_info.start_revision;
+ key.second = file_info.is_packed;
SVN_ERR(svn_cache__get((void**)header, &is_cached, ffd->l2p_header_cache,
&key, result_pool));
if (is_cached)
@@ -1454,16 +1430,12 @@ get_l2p_header(l2p_header_t **header,
return SVN_NO_ERROR;
}
-/* From the log-to-phys index file starting at START_REVISION in FS, read
- * the mapping page identified by TABLE_ENTRY and return it in *PAGE.
- * Use REV_FILE to access on-disk files.
- * Use RESULT_POOL for allocations.
+/* From the log-to-phys index in REV_FILE, read the mapping page identified
+ * by TABLE_ENTRY and return it in *PAGE, allocated in RESULT_POOL.
*/
static svn_error_t *
get_l2p_page(l2p_page_t **page,
svn_fs_x__revision_file_t *rev_file,
- svn_fs_t *fs,
- svn_revnum_t start_revision,
l2p_page_table_entry_t *table_entry,
apr_pool_t *result_pool)
{
@@ -1472,10 +1444,11 @@ get_l2p_page(l2p_page_t **page,
l2p_page_t *result = apr_pcalloc(result_pool, sizeof(*result));
apr_uint64_t container_count;
apr_off_t *container_offsets;
+ svn_fs_x__packed_number_stream_t *stream;
/* open index file and select page */
- SVN_ERR(auto_open_l2p_index(rev_file, fs, start_revision));
- packed_stream_seek(rev_file->l2p_stream, table_entry->offset);
+ SVN_ERR(svn_fs_x__rev_file_l2p_index(&stream, rev_file));
+ packed_stream_seek(stream, table_entry->offset);
/* initialize the page content */
result->entry_count = table_entry->entry_count;
@@ -1486,12 +1459,12 @@ get_l2p_page(l2p_page_t **page,
/* container offsets array */
- SVN_ERR(packed_stream_get(&container_count, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&container_count, stream));
container_offsets = apr_pcalloc(result_pool,
container_count * sizeof(*result));
for (i = 0; i < container_count; ++i)
{
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
last_value += value;
container_offsets[i] = (apr_off_t)last_value - 1;
/* '-1' is represented as '0' in the index file */
@@ -1500,7 +1473,7 @@ get_l2p_page(l2p_page_t **page,
/* read all page entries (offsets in rev file and container sub-items) */
for (i = 0; i < result->entry_count; ++i)
{
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
if (value == 0)
{
result->offsets[i] = -1;
@@ -1509,7 +1482,7 @@ get_l2p_page(l2p_page_t **page,
else if (value <= container_count)
{
result->offsets[i] = container_offsets[value - 1];
- SVN_ERR(packed_stream_get(&value, rev_file->l2p_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->sub_items[i] = (apr_uint32_t)value;
}
else
@@ -1521,7 +1494,7 @@ get_l2p_page(l2p_page_t **page,
/* After reading all page entries, the read cursor must have moved by
* TABLE_ENTRY->SIZE bytes. */
- if ( packed_stream_offset(rev_file->l2p_stream)
+ if ( packed_stream_offset(stream)
!= table_entry->offset + table_entry->size)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("L2P actual page size does not match page table value."));
@@ -1690,9 +1663,8 @@ get_l2p_page_table(apr_array_header_t *p
/* Utility function. Read the l2p index pages for REVISION in FS from
* STREAM and put them into the cache. Skip page number EXLCUDED_PAGE_NO
* (use -1 for 'skip none') and pages outside the MIN_OFFSET, MAX_OFFSET
- * range in the l2p index file. The index is being identified by
- * FIRST_REVISION. PAGES is a scratch container provided by the caller.
- * SCRATCH_POOL is used for temporary allocations.
+ * range in the l2p index file. PAGES is a scratch container provided by
+ * the caller. SCRATCH_POOL is used for temporary allocations.
*
* This function may be a no-op if the header cache lookup fails / misses.
*/
@@ -1700,7 +1672,6 @@ static svn_error_t *
prefetch_l2p_pages(svn_boolean_t *end,
svn_fs_t *fs,
svn_fs_x__revision_file_t *rev_file,
- svn_revnum_t first_revision,
svn_revnum_t revision,
apr_array_header_t *pages,
int exlcuded_page_no,
@@ -1769,8 +1740,7 @@ prefetch_l2p_pages(svn_boolean_t *end,
/* no in cache -> read from stream (data already buffered in APR)
* and cache the result */
l2p_page_t *page = NULL;
- SVN_ERR(get_l2p_page(&page, rev_file, fs, first_revision,
- entry, iterpool));
+ SVN_ERR(get_l2p_page(&page, rev_file, entry, iterpool));
SVN_ERR(svn_cache__set(ffd->l2p_page_cache, &key, page,
iterpool));
@@ -1841,8 +1811,7 @@ l2p_index_lookup(apr_off_t *offset,
apr_off_t min_offset = max_offset - ffd->block_size;
/* read the relevant page */
- SVN_ERR(get_l2p_page(&page, rev_file, fs, info_baton.first_revision,
- &info_baton.entry, scratch_pool));
+ SVN_ERR(get_l2p_page(&page, rev_file, &info_baton.entry, scratch_pool));
/* cache the page and extract the result we need */
SVN_ERR(svn_cache__set(ffd->l2p_page_cache, &key, page, scratch_pool));
@@ -1863,7 +1832,6 @@ l2p_index_lookup(apr_off_t *offset,
svn_pool_clear(iterpool);
SVN_ERR(prefetch_l2p_pages(&end, fs, rev_file,
- info_baton.first_revision,
prefetch_revision, pages,
excluded_page_no, min_offset,
max_offset, iterpool));
@@ -1877,7 +1845,6 @@ l2p_index_lookup(apr_off_t *offset,
svn_pool_clear(iterpool);
SVN_ERR(prefetch_l2p_pages(&end, fs, rev_file,
- info_baton.first_revision,
prefetch_revision, pages, -1,
min_offset, max_offset, iterpool));
}
@@ -1950,8 +1917,7 @@ svn_fs_x__l2p_get_max_ids(apr_array_head
apr_pool_t *header_pool = svn_pool_create(scratch_pool);
/* read index master data structure for the index covering START_REV */
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start_rev,
- header_pool, header_pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start_rev, header_pool));
SVN_ERR(get_l2p_header(&header, rev_file, fs, start_rev, header_pool,
header_pool));
SVN_ERR(svn_fs_x__close_revision_file(rev_file));
@@ -1972,8 +1938,8 @@ svn_fs_x__l2p_get_max_ids(apr_array_head
* the number of items in a revision, i.e. there is no consistency
* issue here. */
svn_pool_clear(header_pool);
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, revision,
- header_pool, header_pool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, revision,
+ header_pool));
SVN_ERR(get_l2p_header(&header, rev_file, fs, revision,
header_pool, header_pool));
SVN_ERR(svn_fs_x__close_revision_file(rev_file));
@@ -2315,7 +2281,8 @@ svn_fs_x__p2l_index_append(svn_checksum_
encode_uint(encoded, entry.size),
iterpool));
SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
- encode_uint(encoded, entry.type + entry.item_count * 16),
+ encode_uint(encoded, entry.type
+ + entry.item_count * 16),
iterpool));
SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
encode_uint(encoded, entry.fnv1_checksum),
@@ -2359,7 +2326,7 @@ svn_fs_x__p2l_index_append(svn_checksum_
result_pool);
/* write the start revision, file size and page size */
- SVN_ERR(svn_stream_puts(stream, P2L_STREAM_PREFIX));
+ SVN_ERR(svn_stream_puts(stream, SVN_FS_X__P2L_STREAM_PREFIX));
SVN_ERR(stream_write_encoded(stream, revision));
SVN_ERR(stream_write_encoded(stream, file_size));
SVN_ERR(stream_write_encoded(stream, page_size));
@@ -2382,32 +2349,6 @@ svn_fs_x__p2l_index_append(svn_checksum_
return SVN_NO_ERROR;
}
-/* If REV_FILE->P2L_STREAM is NULL, create a new stream for the phys-to-log
- * index for REVISION in FS using the rev / pack file provided by REV_FILE.
- */
-static svn_error_t *
-auto_open_p2l_index(svn_fs_x__revision_file_t *rev_file,
- svn_fs_t *fs,
- svn_revnum_t revision)
-{
- if (rev_file->p2l_stream == NULL)
- {
- svn_fs_x__data_t *ffd = fs->fsap_data;
-
- SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
- SVN_ERR(packed_stream_open(&rev_file->p2l_stream,
- rev_file->file,
- rev_file->p2l_offset,
- rev_file->footer_offset,
- P2L_STREAM_PREFIX,
- (apr_size_t)ffd->block_size,
- rev_file->pool,
- rev_file->pool));
- }
-
- return SVN_NO_ERROR;
-}
-
/* Data structure that describes which p2l page info shall be extracted
* from the cache and contains the fields that receive the result.
*/
@@ -2515,11 +2456,15 @@ get_p2l_header(p2l_header_t **header,
apr_off_t offset;
p2l_header_t *result;
svn_boolean_t is_cached = FALSE;
+ svn_fs_x__packed_number_stream_t *stream;
+ svn_fs_x__rev_file_info_t file_info;
+ svn_fs_x__index_info_t l2p_index_info;
/* look for the header data in our cache */
svn_fs_x__pair_cache_key_t key;
- key.revision = rev_file->start_revision;
- key.second = rev_file->is_packed;
+ SVN_ERR(svn_fs_x__rev_file_info(&file_info, rev_file));
+ key.revision = file_info.start_revision;
+ key.second = file_info.is_packed;
SVN_ERR(svn_cache__get((void**)header, &is_cached, ffd->p2l_header_cache,
&key, result_pool));
@@ -2528,32 +2473,33 @@ get_p2l_header(p2l_header_t **header,
/* not found -> must read it from disk.
* Open index file or position read pointer to the begin of the file */
- SVN_ERR(auto_open_p2l_index(rev_file, fs, key.revision));
- packed_stream_seek(rev_file->p2l_stream, 0);
+ SVN_ERR(svn_fs_x__rev_file_p2l_index(&stream, rev_file));
+ SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
+ packed_stream_seek(stream, 0);
/* allocate result data structure */
result = apr_pcalloc(result_pool, sizeof(*result));
/* Read table sizes, check them for plausibility and allocate page array. */
- SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->first_revision = (svn_revnum_t)value;
- if (result->first_revision != rev_file->start_revision)
+ if (result->first_revision != file_info.start_revision)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Index rev / pack file revision numbers do not match"));
- SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->file_size = value;
- if (result->file_size != (apr_uint64_t)rev_file->l2p_offset)
+ if (result->file_size != (apr_uint64_t)l2p_index_info.start)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Index offset and rev / pack file size do not match"));
- SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->page_size = value;
if (!result->page_size || (result->page_size & (result->page_size - 1)))
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("P2L index page size is not a power of two"));
- SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->page_count = (apr_size_t)value;
if (result->page_count != (result->file_size - 1) / result->page_size + 1)
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
@@ -2566,12 +2512,12 @@ get_p2l_header(p2l_header_t **header,
result->offsets[0] = 0;
for (i = 0; i < result->page_count; ++i)
{
- SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
result->offsets[i+1] = result->offsets[i] + (apr_off_t)value;
}
/* correct the offset values */
- offset = packed_stream_offset(rev_file->p2l_stream);
+ offset = packed_stream_offset(stream);
for (i = 0; i <= result->page_count; ++i)
result->offsets[i] += offset;
@@ -2732,14 +2678,15 @@ get_p2l_page(apr_array_header_t **entrie
= apr_array_make(result_pool, 16, sizeof(svn_fs_x__p2l_entry_t));
apr_off_t item_offset;
apr_off_t offset;
+ svn_fs_x__packed_number_stream_t *stream;
/* open index and navigate to page start */
- SVN_ERR(auto_open_p2l_index(rev_file, fs, start_revision));
- packed_stream_seek(rev_file->p2l_stream, start_offset);
+ SVN_ERR(svn_fs_x__rev_file_p2l_index(&stream, rev_file));
+ packed_stream_seek(stream, start_offset);
/* read rev file offset of the first page entry (all page entries will
* only store their sizes). */
- SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
item_offset = (apr_off_t)value;
/* Special case: empty pages. */
@@ -2747,17 +2694,15 @@ get_p2l_page(apr_array_header_t **entrie
{
/* Empty page. This only happens if the first entry of the next page
* also covers this page (and possibly more) completely. */
- SVN_ERR(read_entry(rev_file->p2l_stream, &item_offset, start_revision,
- result));
+ SVN_ERR(read_entry(stream, &item_offset, start_revision, result));
}
else
{
/* Read non-empty page. */
do
{
- SVN_ERR(read_entry(rev_file->p2l_stream, &item_offset,
- start_revision, result));
- offset = packed_stream_offset(rev_file->p2l_stream);
+ SVN_ERR(read_entry(stream, &item_offset, start_revision, result));
+ offset = packed_stream_offset(stream);
}
while (offset < next_offset);
@@ -2771,9 +2716,9 @@ get_p2l_page(apr_array_header_t **entrie
* entry of the next page */
if (item_offset < page_start + page_size)
{
- SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
+ SVN_ERR(packed_stream_get(&value, stream));
item_offset = (apr_off_t)value;
- SVN_ERR(read_entry(rev_file->p2l_stream, &item_offset,
+ SVN_ERR(read_entry(stream, &item_offset,
start_revision, result));
}
}
@@ -3203,7 +3148,8 @@ svn_fs_x__p2l_index_lookup(apr_array_hea
* RHS.
*/
static int
-compare_p2l_entry_offsets(const void *lhs, const void *rhs)
+compare_p2l_entry_offsets(const void *lhs,
+ const void *rhs)
{
const svn_fs_x__p2l_entry_t *entry = (const svn_fs_x__p2l_entry_t *)lhs;
apr_off_t offset = *(const apr_off_t *)rhs;
@@ -3503,15 +3449,13 @@ calc_fnv1(svn_fs_x__p2l_entry_t *entry,
}
/* Read the block and feed it to the checksum calculator. */
- SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &entry->offset,
- scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, entry->offset));
while (size > 0)
{
apr_size_t to_read = size > sizeof(buffer)
? sizeof(buffer)
: (apr_size_t)size;
- SVN_ERR(svn_io_file_read_full2(rev_file->file, buffer, to_read, NULL,
- NULL, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_read(rev_file, buffer, to_read));
SVN_ERR(svn_checksum_update(context, buffer, to_read));
size -= to_read;
}
@@ -3795,7 +3739,7 @@ svn_error_t *
svn_fs_x__deserialize_l2p_header(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
l2p_header_t *header = (l2p_header_t *)data;
@@ -3849,7 +3793,7 @@ svn_error_t *
svn_fs_x__deserialize_l2p_page(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
l2p_page_t *page = data;
@@ -3898,7 +3842,7 @@ svn_error_t *
svn_fs_x__deserialize_p2l_header(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
p2l_header_t *header = data;
@@ -3956,7 +3900,7 @@ svn_error_t *
svn_fs_x__deserialize_p2l_page(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
apr_array_header_t *page = (apr_array_header_t *)data;
svn_fs_x__p2l_entry_t *entries;
@@ -3971,7 +3915,7 @@ svn_fs_x__deserialize_p2l_page(void **ou
svn_temp_deserializer__resolve(entries, (void**)&entries[i].items);
/* patch up members */
- page->pool = pool;
+ page->pool = result_pool;
page->nalloc = page->nelts;
/* done */
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/index.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/index.h?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/index.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/index.h Wed Aug 19 02:35:12 2015
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__INDEX_H
-#define SVN_LIBSVN_FS__INDEX_H
+#ifndef SVN_LIBSVN_FS_X_INDEX_H
+#define SVN_LIBSVN_FS_X_INDEX_H
#include "fs.h"
#include "rev_file.h"
@@ -53,6 +53,28 @@
#define SVN_FS_X__ITEM_TYPE_REPS_CONT 10 /* item is a representations
container */
+/* We put this string in front of the L2P index header. */
+#define SVN_FS_X__L2P_STREAM_PREFIX "L2P-INDEX\n"
+
+/* We put this string in front of the P2L index header. */
+#define SVN_FS_X__P2L_STREAM_PREFIX "P2L-INDEX\n"
+
+
+/* Create and open a packed number stream reading from offsets START to
+ * END in FILE and return it in *STREAM. Access the file in chunks of
+ * BLOCK_SIZE bytes. Expect the stream to be prefixed by STREAM_PREFIX.
+ * Allocate *STREAM in RESULT_POOL and use SCRATCH_POOL for temporaries.
+ */
+svn_error_t *
+svn_fs_x__packed_stream_open(svn_fs_x__packed_number_stream_t **stream,
+ apr_file_t *file,
+ apr_off_t start,
+ apr_off_t end,
+ const char *stream_prefix,
+ apr_size_t block_size,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* (user visible) entry in the phys-to-log index. It describes a section
* of some packed / non-packed rev file as containing a specific item.
* There must be no overlapping / conflicting entries.
@@ -350,7 +372,7 @@ svn_error_t *
svn_fs_x__deserialize_l2p_header(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/*
* Implements svn_cache__serialize_func_t for l2p_page_t objects.
@@ -368,7 +390,7 @@ svn_error_t *
svn_fs_x__deserialize_l2p_page(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/*
* Implements svn_cache__serialize_func_t for p2l_header_t objects.
@@ -386,7 +408,7 @@ svn_error_t *
svn_fs_x__deserialize_p2l_header(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/*
* Implements svn_cache__serialize_func_t for apr_array_header_t objects
@@ -406,6 +428,6 @@ svn_error_t *
svn_fs_x__deserialize_p2l_page(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
#endif
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.c Wed Aug 19 02:35:12 2015
@@ -113,7 +113,8 @@ hash_fetch(apr_hash_t *hash,
/* SVN_ERR_FS_CORRUPT: the lockfile for PATH in FS is corrupt. */
static svn_error_t *
-err_corrupt_lockfile(const char *fs_path, const char *path)
+err_corrupt_lockfile(const char *fs_path,
+ const char *path)
{
return
svn_error_createf(
@@ -854,7 +855,8 @@ typedef struct lock_info_t {
type, and assumes that the write lock is held.
*/
static svn_error_t *
-lock_body(void *baton, apr_pool_t *pool)
+lock_body(void *baton,
+ apr_pool_t *pool)
{
lock_baton_t *lb = baton;
svn_fs_root_t *root;
@@ -1005,7 +1007,8 @@ typedef struct unlock_info_t {
type, and assumes that the write lock is held.
*/
static svn_error_t *
-unlock_body(void *baton, apr_pool_t *pool)
+unlock_body(void *baton,
+ apr_pool_t *pool)
{
unlock_baton_t *ub = baton;
svn_fs_root_t *root;
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.h?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/lock.h Wed Aug 19 02:35:12 2015
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS_LOCK_H
-#define SVN_LIBSVN_FS_LOCK_H
+#ifndef SVN_LIBSVN_FS_X_LOCK_H
+#define SVN_LIBSVN_FS_X_LOCK_H
#ifdef __cplusplus
extern "C" {
@@ -113,4 +113,4 @@ svn_fs_x__allow_locked_operation(const c
}
#endif /* __cplusplus */
-#endif /* SVN_LIBSVN_FS_LOCK_H */
+#endif /* SVN_LIBSVN_FS_X_LOCK_H */
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.c Wed Aug 19 02:35:12 2015
@@ -1,4 +1,4 @@
-/* low_level.c --- low level r/w access to fs_x file structures
+/* low_level.c --- low level r/w access to FSX file structures
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -56,7 +56,6 @@
#define ACTION_ADD "add"
#define ACTION_DELETE "delete"
#define ACTION_REPLACE "replace"
-#define ACTION_RESET "reset"
/* True and False flags. */
#define FLAG_TRUE "true"
@@ -845,10 +844,6 @@ read_change(svn_fs_x__change_t **change_
{
change->change_kind = svn_fs_path_change_replace;
}
- else if (strcmp(str, ACTION_RESET) == 0)
- {
- change->change_kind = svn_fs_path_change_reset;
- }
else
{
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1036,9 +1031,6 @@ write_change_entry(svn_stream_t *stream,
case svn_fs_path_change_replace:
change_string = ACTION_REPLACE;
break;
- case svn_fs_path_change_reset:
- change_string = ACTION_RESET;
- break;
default:
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
_("Invalid change type %d"),
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.h?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/low_level.h Wed Aug 19 02:35:12 2015
@@ -1,4 +1,4 @@
-/* low_level.c --- low level r/w access to fs_x file structures
+/* low_level.c --- low level r/w access to FSX file structures
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__LOW_LEVEL_H
-#define SVN_LIBSVN_FS__LOW_LEVEL_H
+#ifndef SVN_LIBSVN_FS_X_LOW_LEVEL_H
+#define SVN_LIBSVN_FS_X_LOW_LEVEL_H
#include "svn_fs.h"
@@ -211,4 +211,4 @@ svn_fs_x__write_changes(svn_stream_t *st
}
#endif /* __cplusplus */
-#endif /* SVN_LIBSVN_FS__LOW_LEVEL_H */
+#endif /* SVN_LIBSVN_FS_X_LOW_LEVEL_H */
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.c Wed Aug 19 02:35:12 2015
@@ -361,7 +361,7 @@ svn_error_t *
svn_fs_x__noderevs_get(svn_fs_x__noderev_t **noderev_p,
const svn_fs_x__noderevs_t *container,
apr_size_t idx,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
svn_fs_x__noderev_t *noderev;
binary_noderev_t *binary_noderev;
@@ -373,14 +373,14 @@ svn_fs_x__noderevs_get(svn_fs_x__noderev
/* validate index */
if (idx >= (apr_size_t)container->noderevs->nelts)
return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL,
- apr_psprintf(pool,
+ apr_psprintf(result_pool,
_("Node revision index %%%s"
" exceeds container size %%d"),
APR_SIZE_T_FMT),
idx, container->noderevs->nelts);
/* allocate result struct and fill it field by field */
- noderev = apr_pcalloc(pool, sizeof(*noderev));
+ noderev = apr_pcalloc(result_pool, sizeof(*noderev));
binary_noderev = &APR_ARRAY_IDX(container->noderevs, idx, binary_noderev_t);
noderev->kind = (svn_node_kind_t)(binary_noderev->flags & NODEREV_KIND_MASK);
@@ -398,7 +398,7 @@ svn_fs_x__noderevs_get(svn_fs_x__noderev
= svn_fs_x__string_table_get(container->paths,
binary_noderev->copyfrom_path,
NULL,
- pool);
+ result_pool);
noderev->copyfrom_rev = binary_noderev->copyfrom_rev;
}
else
@@ -413,7 +413,7 @@ svn_fs_x__noderevs_get(svn_fs_x__noderev
= svn_fs_x__string_table_get(container->paths,
binary_noderev->copyroot_path,
NULL,
- pool);
+ result_pool);
noderev->copyroot_rev = binary_noderev->copyroot_rev;
}
else
@@ -425,16 +425,16 @@ svn_fs_x__noderevs_get(svn_fs_x__noderev
noderev->predecessor_count = binary_noderev->predecessor_count;
SVN_ERR(get_representation(&noderev->prop_rep, container->reps,
- binary_noderev->prop_rep, pool));
+ binary_noderev->prop_rep, result_pool));
SVN_ERR(get_representation(&noderev->data_rep, container->reps,
- binary_noderev->data_rep, pool));
+ binary_noderev->data_rep, result_pool));
if (binary_noderev->flags & NODEREV_HAS_CPATH)
noderev->created_path
= svn_fs_x__string_table_get(container->paths,
binary_noderev->created_path,
NULL,
- pool);
+ result_pool);
noderev->mergeinfo_count = binary_noderev->mergeinfo_count;
@@ -578,15 +578,15 @@ svn_fs_x__write_noderevs_container(svn_s
return SVN_NO_ERROR;
}
-/* Allocate a svn_fs_x__representation_t array in POOL and return it in
- * REPS_P. Deserialize the data in REP_STREAM and DIGEST_STREAM and store
+/* Allocate a svn_fs_x__representation_t array in RESULT_POOL and return it
+ * in REPS_P. Deserialize the data in REP_STREAM and DIGEST_STREAM and store
* the resulting representations into the *REPS_P.
*/
static svn_error_t *
read_reps(apr_array_header_t **reps_p,
svn_packed__int_stream_t *rep_stream,
svn_packed__byte_stream_t *digest_stream,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
apr_size_t i;
apr_size_t len;
@@ -595,7 +595,8 @@ read_reps(apr_array_header_t **reps_p,
apr_size_t count
= svn_packed__int_count(svn_packed__first_int_substream(rep_stream));
apr_array_header_t *reps
- = apr_array_make(pool, (int)count, sizeof(svn_fs_x__representation_t));
+ = apr_array_make(result_pool, (int)count,
+ sizeof(svn_fs_x__representation_t));
for (i = 0; i < count; ++i)
{
@@ -613,7 +614,7 @@ read_reps(apr_array_header_t **reps_p,
bytes = svn_packed__get_bytes(digest_stream, &len);
if (len != sizeof(rep.md5_digest))
return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL,
- apr_psprintf(pool,
+ apr_psprintf(result_pool,
_("Unexpected MD5"
" digest size %%%s"),
APR_SIZE_T_FMT),
@@ -625,7 +626,7 @@ read_reps(apr_array_header_t **reps_p,
bytes = svn_packed__get_bytes(digest_stream, &len);
if (len != sizeof(rep.sha1_digest))
return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL,
- apr_psprintf(pool,
+ apr_psprintf(result_pool,
_("Unexpected SHA1"
" digest size %%%s"),
APR_SIZE_T_FMT),
@@ -766,15 +767,15 @@ svn_error_t *
svn_fs_x__deserialize_noderevs_container(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
svn_fs_x__noderevs_t *noderevs = (svn_fs_x__noderevs_t *)data;
/* de-serialize sub-structures */
svn_fs_x__deserialize_string_table(noderevs, &noderevs->paths);
- svn_fs_x__deserialize_apr_array(noderevs, &noderevs->ids, pool);
- svn_fs_x__deserialize_apr_array(noderevs, &noderevs->reps, pool);
- svn_fs_x__deserialize_apr_array(noderevs, &noderevs->noderevs, pool);
+ svn_fs_x__deserialize_apr_array(noderevs, &noderevs->ids, result_pool);
+ svn_fs_x__deserialize_apr_array(noderevs, &noderevs->reps, result_pool);
+ svn_fs_x__deserialize_apr_array(noderevs, &noderevs->noderevs, result_pool);
/* done */
*out = noderevs;
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.h?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/noderevs.h Wed Aug 19 02:35:12 2015
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__NODEREVS_H
-#define SVN_LIBSVN_FS__NODEREVS_H
+#ifndef SVN_LIBSVN_FS_X_NODEREVS_H
+#define SVN_LIBSVN_FS_X_NODEREVS_H
#include "svn_io.h"
#include "fs.h"
@@ -76,7 +76,7 @@ svn_error_t *
svn_fs_x__noderevs_get(svn_fs_x__noderev_t **noderev_p,
const svn_fs_x__noderevs_t *container,
apr_size_t idx,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/* I/O interface. */
@@ -114,7 +114,7 @@ svn_error_t *
svn_fs_x__deserialize_noderevs_container(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/* Implements svn_cache__partial_getter_func_t for svn_fs_x__noderevs_t,
* setting *OUT to the svn_fs_x__noderev_t selected by the apr_uint32_t index
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.c Wed Aug 19 02:35:12 2015
@@ -478,6 +478,7 @@ copy_item_to_temp(pack_context_t *contex
svn_fs_x__p2l_entry_t *entry,
apr_pool_t *scratch_pool)
{
+ apr_file_t *file;
svn_fs_x__p2l_entry_t *new_entry
= svn_fs_x__p2l_entry_dup(entry, context->info_pool);
@@ -485,7 +486,8 @@ copy_item_to_temp(pack_context_t *contex
scratch_pool));
APR_ARRAY_PUSH(entries, svn_fs_x__p2l_entry_t *) = new_entry;
- SVN_ERR(copy_file_data(context, temp_file, rev_file->file, entry->size,
+ SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
+ SVN_ERR(copy_file_data(context, temp_file, file, entry->size,
scratch_pool));
return SVN_NO_ERROR;
@@ -567,6 +569,8 @@ copy_rep_to_temp(pack_context_t *context
apr_pool_t *scratch_pool)
{
svn_fs_x__rep_header_t *rep_header;
+ svn_stream_t *stream;
+ apr_file_t *file;
apr_off_t source_offset = entry->offset;
/* create a copy of ENTRY, make it point to the copy destination and
@@ -577,7 +581,8 @@ copy_rep_to_temp(pack_context_t *context
add_item_rep_mapping(context, entry);
/* read & parse the representation header */
- SVN_ERR(svn_fs_x__read_rep_header(&rep_header, rev_file->stream,
+ SVN_ERR(svn_fs_x__rev_file_stream(&stream, rev_file));
+ SVN_ERR(svn_fs_x__read_rep_header(&rep_header, stream,
scratch_pool, scratch_pool));
/* if the representation is a delta against some other rep, link the two */
@@ -594,10 +599,10 @@ copy_rep_to_temp(pack_context_t *context
}
/* copy the whole rep (including header!) to our temp file */
- SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &source_offset,
- scratch_pool));
- SVN_ERR(copy_file_data(context, context->reps_file, rev_file->file,
- entry->size, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, source_offset));
+ SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
+ SVN_ERR(copy_file_data(context, context->reps_file, file, entry->size,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -687,25 +692,28 @@ copy_node_to_temp(pack_context_t *contex
path_order_t *path_order = apr_pcalloc(context->info_pool,
sizeof(*path_order));
svn_fs_x__noderev_t *noderev;
+ svn_stream_t *stream;
+ apr_file_t *file;
const char *sort_path;
apr_off_t source_offset = entry->offset;
/* read & parse noderev */
- SVN_ERR(svn_fs_x__read_noderev(&noderev, rev_file->stream, scratch_pool,
+ SVN_ERR(svn_fs_x__rev_file_stream(&stream, rev_file));
+ SVN_ERR(svn_fs_x__read_noderev(&noderev, stream, scratch_pool,
scratch_pool));
/* create a copy of ENTRY, make it point to the copy destination and
* store it in CONTEXT */
entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool);
SVN_ERR(svn_fs_x__get_file_offset(&entry->offset, context->reps_file,
- scratch_pool));
+ scratch_pool));
add_item_rep_mapping(context, entry);
/* copy the noderev to our temp file */
- SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &source_offset,
- scratch_pool));
- SVN_ERR(copy_file_data(context, context->reps_file, rev_file->file,
- entry->size, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, source_offset));
+ SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
+ SVN_ERR(copy_file_data(context, context->reps_file, file, entry->size,
+ scratch_pool));
/* if the node has a data representation, make that the node's "base".
* This will (often) cause the noderev to be placed right in front of
@@ -1234,7 +1242,7 @@ write_reps_containers(pack_context_t *co
= apr_array_make(scratch_pool, 64, sizeof(svn_fs_x__id_t));
svn_fs_x__revision_file_t *file;
- SVN_ERR(svn_fs_x__wrap_temp_rev_file(&file, context->fs, temp_file,
+ SVN_ERR(svn_fs_x__rev_file_wrap_temp(&file, context->fs, temp_file,
scratch_pool));
/* copy all items in strict order */
@@ -1723,18 +1731,19 @@ pack_range(pack_context_t *context,
{
apr_off_t offset = 0;
svn_fs_x__revision_file_t *rev_file;
+ svn_fs_x__index_info_t l2p_index_info;
/* Get the rev file dimensions (mainly index locations). */
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, context->fs,
- revision, revpool, iterpool));
- SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, context->fs, revision,
+ revpool));
+ SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
/* store the indirect array index */
APR_ARRAY_PUSH(context->rev_offsets, int) = context->reps->nelts;
/* read the phys-to-log index file until we covered the whole rev file.
* That index contains enough info to build both target indexes from it. */
- while (offset < rev_file->l2p_offset)
+ while (offset < l2p_index_info.start)
{
/* read one cluster */
int i;
@@ -1758,10 +1767,9 @@ pack_range(pack_context_t *context,
/* process entry while inside the rev file */
offset = entry->offset;
- if (offset < rev_file->l2p_offset)
+ if (offset < l2p_index_info.start)
{
- SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &offset,
- iterpool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, offset));
if (entry->type == SVN_FS_X__ITEM_TYPE_CHANGES)
SVN_ERR(copy_item_to_temp(context,
@@ -1843,6 +1851,7 @@ append_revision(pack_context_t *context,
apr_off_t offset = 0;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
svn_fs_x__revision_file_t *rev_file;
+ apr_file_t *file;
apr_finfo_t finfo;
/* Get the size of the file. */
@@ -1853,11 +1862,11 @@ append_revision(pack_context_t *context,
SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, scratch_pool));
/* Copy all the bits from the rev file to the end of the pack file. */
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, context->fs,
- context->start_rev, scratch_pool,
- iterpool));
- SVN_ERR(copy_file_data(context, context->pack_file, rev_file->file,
- finfo.size, iterpool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, context->fs, context->start_rev,
+ scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_get(&file, rev_file));
+ SVN_ERR(copy_file_data(context, context->pack_file, file, finfo.size,
+ iterpool));
/* mark the start of a new revision */
SVN_ERR(svn_fs_x__l2p_proto_index_add_revision(context->proto_l2p_index,
@@ -2003,72 +2012,6 @@ pack_log_addressed(svn_fs_t *fs,
return SVN_NO_ERROR;
}
-/* Given REV in FS, set *REV_OFFSET to REV's offset in the packed file.
- Use SCRATCH_POOL for temporary allocations. */
-svn_error_t *
-svn_fs_x__get_packed_offset(apr_off_t *rev_offset,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *scratch_pool)
-{
- svn_fs_x__data_t *ffd = fs->fsap_data;
- svn_stream_t *manifest_stream;
- svn_boolean_t is_cached;
- svn_revnum_t shard;
- apr_int64_t shard_pos;
- apr_array_header_t *manifest;
- apr_pool_t *iterpool;
-
- shard = rev / ffd->max_files_per_dir;
-
- /* position of the shard within the manifest */
- shard_pos = rev % ffd->max_files_per_dir;
-
- /* fetch exactly that element into *rev_offset, if the manifest is found
- in the cache */
- SVN_ERR(svn_cache__get_partial((void **) rev_offset, &is_cached,
- ffd->packed_offset_cache, &shard,
- svn_fs_x__get_sharded_offset, &shard_pos,
- scratch_pool));
-
- if (is_cached)
- return SVN_NO_ERROR;
-
- /* Open the manifest file. */
- SVN_ERR(svn_stream_open_readonly(&manifest_stream,
- svn_fs_x__path_rev_packed(fs, rev, PATH_MANIFEST,
- scratch_pool),
- scratch_pool, scratch_pool));
-
- /* While we're here, let's just read the entire manifest file into an array,
- so we can cache the entire thing. */
- iterpool = svn_pool_create(scratch_pool);
- manifest = apr_array_make(scratch_pool, ffd->max_files_per_dir,
- sizeof(apr_off_t));
- while (1)
- {
- svn_boolean_t eof;
- apr_int64_t val;
-
- svn_pool_clear(iterpool);
- SVN_ERR(svn_fs_x__read_number_from_stream(&val, &eof, manifest_stream,
- iterpool));
- if (eof)
- break;
-
- APR_ARRAY_PUSH(manifest, apr_off_t) = (apr_off_t)val;
- }
- svn_pool_destroy(iterpool);
-
- *rev_offset = APR_ARRAY_IDX(manifest, rev % ffd->max_files_per_dir,
- apr_off_t);
-
- /* Close up shop and cache the array. */
- SVN_ERR(svn_stream_close(manifest_stream));
- return svn_cache__set(ffd->packed_offset_cache, &shard, manifest,
- scratch_pool);
-}
-
/* In filesystem FS, pack the revision SHARD containing exactly
* MAX_FILES_PER_DIR revisions from SHARD_PATH into the PACK_FILE_DIR,
* using SCRATCH_POOL for temporary allocations. Try to limit the amount of
@@ -2115,11 +2058,9 @@ pack_rev_shard(svn_fs_t *fs,
return SVN_NO_ERROR;
}
-/* In the file system at FS_PATH, pack the SHARD in REVS_DIR and
- * REVPROPS_DIR containing exactly MAX_FILES_PER_DIR revisions, using
- * SCRATCH_POOL temporary for allocations. REVPROPS_DIR will be NULL if
- * revprop packing is not supported. COMPRESSION_LEVEL and MAX_PACK_SIZE
- * will be ignored in that case.
+/* In the file system at FS_PATH, pack the SHARD in DIR containing exactly
+ * MAX_FILES_PER_DIR revisions, using SCRATCH_POOL temporary for allocations.
+ * COMPRESSION_LEVEL and MAX_PACK_SIZE will be ignored in that case.
*
* CANCEL_FUNC and CANCEL_BATON are what you think they are; similarly
* NOTIFY_FUNC and NOTIFY_BATON.
@@ -2128,8 +2069,7 @@ pack_rev_shard(svn_fs_t *fs,
* remove the pack file and start again.
*/
static svn_error_t *
-pack_shard(const char *revs_dir,
- const char *revsprops_dir,
+pack_shard(const char *dir,
svn_fs_t *fs,
apr_int64_t shard,
int max_files_per_dir,
@@ -2151,12 +2091,12 @@ pack_shard(const char *revs_dir,
scratch_pool));
/* Some useful paths. */
- rev_pack_file_dir = svn_dirent_join(revs_dir,
+ rev_pack_file_dir = svn_dirent_join(dir,
apr_psprintf(scratch_pool,
"%" APR_INT64_T_FMT PATH_EXT_PACKED_SHARD,
shard),
scratch_pool);
- rev_shard_path = svn_dirent_join(revs_dir,
+ rev_shard_path = svn_dirent_join(dir,
apr_psprintf(scratch_pool, "%" APR_INT64_T_FMT, shard),
scratch_pool);
@@ -2165,26 +2105,24 @@ pack_shard(const char *revs_dir,
shard, max_files_per_dir, DEFAULT_MAX_MEM,
cancel_func, cancel_baton, scratch_pool));
- /* if enabled, pack the revprops in an equivalent way */
- if (revsprops_dir)
- {
- revprops_pack_file_dir = svn_dirent_join(revsprops_dir,
- apr_psprintf(scratch_pool,
- "%" APR_INT64_T_FMT PATH_EXT_PACKED_SHARD,
- shard),
- scratch_pool);
- revprops_shard_path = svn_dirent_join(revsprops_dir,
- apr_psprintf(scratch_pool, "%" APR_INT64_T_FMT, shard),
- scratch_pool);
-
- SVN_ERR(svn_fs_x__pack_revprops_shard(revprops_pack_file_dir,
- revprops_shard_path,
- shard, max_files_per_dir,
- (int)(0.9 * max_pack_size),
- compression_level,
- cancel_func, cancel_baton,
- scratch_pool));
- }
+ /* pack the revprops in an equivalent way */
+ revprops_pack_file_dir = svn_dirent_join(dir,
+ apr_psprintf(scratch_pool,
+ "%" APR_INT64_T_FMT PATH_EXT_PACKED_SHARD,
+ shard),
+ scratch_pool);
+ revprops_shard_path = svn_dirent_join(dir,
+ apr_psprintf(scratch_pool, "%" APR_INT64_T_FMT, shard),
+ scratch_pool);
+
+ SVN_ERR(svn_fs_x__pack_revprops_shard(fs,
+ revprops_pack_file_dir,
+ revprops_shard_path,
+ shard, max_files_per_dir,
+ (int)(0.9 * max_pack_size),
+ compression_level,
+ cancel_func, cancel_baton,
+ scratch_pool));
/* Update the min-unpacked-rev file to reflect our newly packed shard. */
SVN_ERR(svn_fs_x__write_min_unpacked_rev(fs,
@@ -2192,35 +2130,9 @@ pack_shard(const char *revs_dir,
scratch_pool));
ffd->min_unpacked_rev = (svn_revnum_t)((shard + 1) * max_files_per_dir);
- /* Finally, remove the existing shard directories.
- * For revprops, clean up older obsolete shards as well as they might
- * have been left over from an interrupted FS upgrade. */
+ /* Finally, remove the existing shard directories. */
SVN_ERR(svn_io_remove_dir2(rev_shard_path, TRUE,
cancel_func, cancel_baton, scratch_pool));
- if (revsprops_dir)
- {
- svn_node_kind_t kind = svn_node_dir;
- apr_int64_t to_cleanup = shard;
- do
- {
- SVN_ERR(svn_fs_x__delete_revprops_shard(revprops_shard_path,
- to_cleanup,
- max_files_per_dir,
- cancel_func, cancel_baton,
- scratch_pool));
-
- /* If the previous shard exists, clean it up as well.
- Don't try to clean up shard 0 as it we can't tell quickly
- whether it actually needs cleaning up. */
- revprops_shard_path = svn_dirent_join(revsprops_dir,
- apr_psprintf(scratch_pool,
- "%" APR_INT64_T_FMT,
- --to_cleanup),
- scratch_pool);
- SVN_ERR(svn_io_check_path(revprops_shard_path, &kind, scratch_pool));
- }
- while (kind == svn_node_dir && to_cleanup > 0);
- }
/* Notify caller we're starting to pack this shard. */
if (notify_func)
@@ -2264,8 +2176,7 @@ pack_body(void *baton,
apr_int64_t i;
svn_revnum_t youngest;
apr_pool_t *iterpool;
- const char *rev_data_path;
- const char *revprops_data_path = NULL;
+ const char *data_path;
/* If we aren't using sharding, we can't do any packing, so quit. */
SVN_ERR(svn_fs_x__read_min_unpacked_rev(&ffd->min_unpacked_rev, pb->fs,
@@ -2278,9 +2189,7 @@ pack_body(void *baton,
if (ffd->min_unpacked_rev == (completed_shards * ffd->max_files_per_dir))
return SVN_NO_ERROR;
- rev_data_path = svn_dirent_join(pb->fs->path, PATH_REVS_DIR, scratch_pool);
- revprops_data_path = svn_dirent_join(pb->fs->path, PATH_REVPROPS_DIR,
- scratch_pool);
+ data_path = svn_dirent_join(pb->fs->path, PATH_REVS_DIR, scratch_pool);
iterpool = svn_pool_create(scratch_pool);
for (i = ffd->min_unpacked_rev / ffd->max_files_per_dir;
@@ -2292,7 +2201,7 @@ pack_body(void *baton,
if (pb->cancel_func)
SVN_ERR(pb->cancel_func(pb->cancel_baton));
- SVN_ERR(pack_shard(rev_data_path, revprops_data_path,
+ SVN_ERR(pack_shard(data_path,
pb->fs, i, ffd->max_files_per_dir,
ffd->revprop_pack_size,
ffd->compress_packed_revprops
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.h?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/pack.h Wed Aug 19 02:35:12 2015
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__PACK_H
-#define SVN_LIBSVN_FS__PACK_H
+#ifndef SVN_LIBSVN_FS_X_PACK_H
+#define SVN_LIBSVN_FS_X_PACK_H
#include "fs.h"
@@ -39,17 +39,6 @@ svn_fs_x__pack(svn_fs_t *fs,
void *cancel_baton,
apr_pool_t *scratch_pool);
-/**
- * For the packed revision REV in FS, determine the offset within the
- * revision pack file and return it in REV_OFFSET.
- * Use SCRATCH_POOL for temporary allocations.
- */
-svn_error_t *
-svn_fs_x__get_packed_offset(apr_off_t *rev_offset,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *scratch_pool);
-
/* Return the svn_dir_entry_t* objects of DIRECTORY in an APR array
* allocated in RESULT_POOL with entries added in storage (on-disk) order.
* FS' format will be used to pick the optimal ordering strategy. Use
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.c Wed Aug 19 02:35:12 2015
@@ -38,6 +38,22 @@
#include "svn_private_config.h"
+/* Set *EXISTS to TRUE, if the revision / pack file for REV exists in FS.
+ Use SCRATCH_POOL for temporary allocations. */
+static svn_error_t *
+revision_file_exists(svn_boolean_t *exists,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *scratch_pool)
+{
+ svn_node_kind_t kind;
+ const char *path = svn_fs_x__path_rev_absolute(fs, rev, scratch_pool);
+ SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
+
+ *exists = kind == svn_node_file;
+ return SVN_NO_ERROR;
+}
+
/* Part of the recovery procedure. Return the largest revision *REV in
filesystem FS. Use SCRATCH_POOL for temporary allocation. */
static svn_error_t *
@@ -56,19 +72,12 @@ recover_get_largest_revision(svn_fs_t *f
/* Keep doubling right, until we find a revision that doesn't exist. */
while (1)
{
- svn_error_t *err;
- svn_fs_x__revision_file_t *file;
+ svn_boolean_t exists;
svn_pool_clear(iterpool);
- err = svn_fs_x__open_pack_or_rev_file(&file, fs, right, iterpool,
- iterpool);
- if (err && err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
- {
- svn_error_clear(err);
- break;
- }
- else
- SVN_ERR(err);
+ SVN_ERR(revision_file_exists(&exists, fs, right, iterpool));
+ if (!exists)
+ break;
right <<= 1;
}
@@ -80,22 +89,14 @@ recover_get_largest_revision(svn_fs_t *f
while (left + 1 < right)
{
svn_revnum_t probe = left + ((right - left) / 2);
- svn_error_t *err;
- svn_fs_x__revision_file_t *file;
+ svn_boolean_t exists;
svn_pool_clear(iterpool);
- err = svn_fs_x__open_pack_or_rev_file(&file, fs, probe, iterpool,
- iterpool);
- if (err && err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
- {
- svn_error_clear(err);
- right = probe;
- }
+ SVN_ERR(revision_file_exists(&exists, fs, probe, iterpool));
+ if (exists)
+ left = probe;
else
- {
- SVN_ERR(err);
- left = probe;
- }
+ right = probe;
}
svn_pool_destroy(iterpool);
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.h?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/recovery.h Wed Aug 19 02:35:12 2015
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__RECOVERY_H
-#define SVN_LIBSVN_FS__RECOVERY_H
+#ifndef SVN_LIBSVN_FS_X_RECOVERY_H
+#define SVN_LIBSVN_FS_X_RECOVERY_H
#include "fs.h"
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.c Wed Aug 19 02:35:12 2015
@@ -641,16 +641,17 @@ svn_fs_x__reps_get(svn_fs_x__rep_extract
svn_fs_t *fs,
const svn_fs_x__reps_t *container,
apr_size_t idx,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
apr_uint32_t first = container->first_instructions[idx];
apr_uint32_t last = container->first_instructions[idx + 1];
/* create the extractor object */
- svn_fs_x__rep_extractor_t *result = apr_pcalloc(pool, sizeof(*result));
+ svn_fs_x__rep_extractor_t *result = apr_pcalloc(result_pool,
+ sizeof(*result));
result->fs = fs;
- result->result = svn_stringbuf_create_empty(pool);
- result->pool = pool;
+ result->result = svn_stringbuf_create_empty(result_pool);
+ result->pool = result_pool;
/* fill all the bits of the result that we can, i.e. all but bits coming
* from base representations */
@@ -900,7 +901,7 @@ svn_error_t *
svn_fs_x__deserialize_reps_container(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
svn_fs_x__reps_t *reps = (svn_fs_x__reps_t *)data;
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.h?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/reps.h Wed Aug 19 02:35:12 2015
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__REPS_H
-#define SVN_LIBSVN_FS__REPS_H
+#ifndef SVN_LIBSVN_FS_X_REPS_H
+#define SVN_LIBSVN_FS_X_REPS_H
#include "svn_io.h"
#include "fs.h"
@@ -112,14 +112,14 @@ svn_fs_x__reps_estimate_size(const svn_f
/* Read from representation containers. */
/* For fulltext IDX in CONTAINER in filesystem FS, create an extract object
- * allocated in POOL and return it in *EXTRACTOR.
+ * allocated in RESULT_POOL and return it in *EXTRACTOR.
*/
svn_error_t *
svn_fs_x__reps_get(svn_fs_x__rep_extractor_t **extractor,
svn_fs_t *fs,
const svn_fs_x__reps_t *container,
apr_size_t idx,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/* Let the EXTRACTOR object fetch all parts of the desired fulltext and
* return the latter in *CONTENTS. If SIZE is not 0, return SIZE bytes
@@ -172,7 +172,7 @@ svn_error_t *
svn_fs_x__deserialize_reps_container(void **out,
void *data,
apr_size_t data_len,
- apr_pool_t *pool);
+ apr_pool_t *result_pool);
/* Implements svn_cache__partial_getter_func_t for svn_fs_x__reps_t,
* setting *OUT to an svn_fs_x__rep_extractor_t object defined by the
Modified: subversion/branches/patch-exec/subversion/libsvn_fs_x/rev_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_fs_x/rev_file.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_fs_x/rev_file.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_fs_x/rev_file.c Wed Aug 19 02:35:12 2015
@@ -20,6 +20,8 @@
* ====================================================================
*/
+#include "svn_pools.h"
+
#include "rev_file.h"
#include "fs_x.h"
#include "index.h"
@@ -31,6 +33,46 @@
#include "private/svn_io_private.h"
#include "svn_private_config.h"
+struct svn_fs_x__revision_file_t
+{
+ /* the filesystem that this revision file belongs to */
+ svn_fs_t *fs;
+
+ /* Meta-data to FILE. */
+ svn_fs_x__rev_file_info_t file_info;
+
+ /* rev / pack file */
+ apr_file_t *file;
+
+ /* stream based on FILE and not NULL exactly when FILE is not NULL */
+ svn_stream_t *stream;
+
+ /* the opened P2L index stream or NULL. Always NULL for txns. */
+ svn_fs_x__packed_number_stream_t *p2l_stream;
+
+ /* the opened L2P index stream or NULL. Always NULL for txns. */
+ svn_fs_x__packed_number_stream_t *l2p_stream;
+
+ /* Copied from FS->FFD->BLOCK_SIZE upon creation. It allows us to
+ * use aligned seek() without having the FS handy. */
+ apr_off_t block_size;
+
+ /* Info on the L2P index within FILE.
+ * Elements are -1 / NULL until svn_fs_x__auto_read_footer gets called. */
+ svn_fs_x__index_info_t l2p_info;
+
+ /* Info on the P2L index within FILE.
+ * Elements are -1 / NULL until svn_fs_x__auto_read_footer gets called. */
+ svn_fs_x__index_info_t p2l_info;
+
+ /* Pool used for all sub-structure allocations (file, streams etc.).
+ A sub-pool of OWNER. NULL until the lazily initilized. */
+ apr_pool_t *pool;
+
+ /* Pool that this structure got allocated in. */
+ apr_pool_t *owner;
+};
+
/* Return a new revision file instance, allocated in RESULT_POOL, for
* filesystem FS. Set its pool member to the provided RESULT_POOL. */
static svn_fs_x__revision_file_t *
@@ -38,22 +80,24 @@ create_revision_file(svn_fs_t *fs,
apr_pool_t *result_pool)
{
svn_fs_x__data_t *ffd = fs->fsap_data;
- svn_fs_x__revision_file_t *file = apr_palloc(result_pool, sizeof(*file));
-
- file->is_packed = FALSE;
- file->start_revision = SVN_INVALID_REVNUM;
+ svn_fs_x__revision_file_t *file = apr_palloc(result_pool, sizeof(*file));
+ file->fs = fs;
+ file->file_info.is_packed = FALSE;
+ file->file_info.start_revision = SVN_INVALID_REVNUM;
file->file = NULL;
file->stream = NULL;
file->p2l_stream = NULL;
file->l2p_stream = NULL;
file->block_size = ffd->block_size;
- file->l2p_offset = -1;
- file->l2p_checksum = NULL;
- file->p2l_offset = -1;
- file->p2l_checksum = NULL;
- file->footer_offset = -1;
- file->pool = result_pool;
+ file->l2p_info.start = -1;
+ file->l2p_info.end = -1;
+ file->l2p_info.checksum = NULL;
+ file->p2l_info.start = -1;
+ file->p2l_info.end = -1;
+ file->p2l_info.checksum = NULL;
+ file->pool = NULL;
+ file->owner = result_pool;
return file;
}
@@ -68,8 +112,8 @@ init_revision_file(svn_fs_t *fs,
{
svn_fs_x__revision_file_t *file = create_revision_file(fs, result_pool);
- file->is_packed = svn_fs_x__is_packed_rev(fs, revision);
- file->start_revision = svn_fs_x__packed_base_rev(fs, revision);
+ file->file_info.is_packed = svn_fs_x__is_packed_rev(fs, revision);
+ file->file_info.start_revision = svn_fs_x__packed_base_rev(fs, revision);
return file;
}
@@ -137,20 +181,31 @@ auto_make_writable(const char *path,
return SVN_NO_ERROR;
}
+/* Return the pool to be used for allocations with FILE.
+ Lazily created that pool upon the first call. */
+static apr_pool_t *
+get_file_pool(svn_fs_x__revision_file_t *file)
+{
+ if (file->pool == NULL)
+ file->pool = svn_pool_create(file->owner);
+
+ return file->pool;
+}
+
/* Core implementation of svn_fs_fs__open_pack_or_rev_file working on an
* existing, initialized FILE structure. If WRITABLE is TRUE, give write
* access to the file - temporarily resetting the r/o state if necessary.
*/
static svn_error_t *
open_pack_or_rev_file(svn_fs_x__revision_file_t *file,
- svn_fs_t *fs,
- svn_revnum_t rev,
svn_boolean_t writable,
- apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_error_t *err;
svn_boolean_t retry = FALSE;
+ svn_fs_t *fs = file->fs;
+ svn_revnum_t rev = file->file_info.start_revision;
+ apr_pool_t *file_pool = get_file_pool(file);
do
{
@@ -161,19 +216,19 @@ open_pack_or_rev_file(svn_fs_x__revision
: APR_READ | APR_BUFFERED;
/* We may have to *temporarily* enable write access. */
- err = writable ? auto_make_writable(path, result_pool, scratch_pool)
+ err = writable ? auto_make_writable(path, file_pool, scratch_pool)
: SVN_NO_ERROR;
/* open the revision file in buffered r/o or r/w mode */
if (!err)
err = svn_io_file_open(&apr_file, path, flags, APR_OS_DEFAULT,
- result_pool);
+ file_pool);
if (!err)
{
file->file = apr_file;
file->stream = svn_stream_from_aprfile2(apr_file, TRUE,
- result_pool);
+ file_pool);
return SVN_NO_ERROR;
}
@@ -191,7 +246,7 @@ open_pack_or_rev_file(svn_fs_x__revision
/* We failed for the first time. Refresh cache & retry. */
SVN_ERR(svn_fs_x__update_min_unpacked_rev(fs, scratch_pool));
- file->start_revision = svn_fs_x__packed_base_rev(fs, rev);
+ file->file_info.start_revision = svn_fs_x__packed_base_rev(fs, rev);
retry = TRUE;
}
@@ -206,39 +261,52 @@ open_pack_or_rev_file(svn_fs_x__revision
}
svn_error_t *
-svn_fs_x__open_pack_or_rev_file(svn_fs_x__revision_file_t **file,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_fs_x__rev_file_init(svn_fs_x__revision_file_t **file,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *result_pool)
{
*file = init_revision_file(fs, rev, result_pool);
- return svn_error_trace(open_pack_or_rev_file(*file, fs, rev, FALSE,
- result_pool, scratch_pool));
+ return SVN_NO_ERROR;
}
svn_error_t *
-svn_fs_x__open_pack_or_rev_file_writable(svn_fs_x__revision_file_t** file,
- svn_fs_t* fs,
- svn_revnum_t rev,
- apr_pool_t* result_pool,
- apr_pool_t *scratch_pool)
+svn_fs_x__rev_file_open_writable(svn_fs_x__revision_file_t** file,
+ svn_fs_t* fs,
+ svn_revnum_t rev,
+ apr_pool_t* result_pool,
+ apr_pool_t *scratch_pool)
{
*file = init_revision_file(fs, rev, result_pool);
- return svn_error_trace(open_pack_or_rev_file(*file, fs, rev, TRUE,
- result_pool, scratch_pool));
+ return svn_error_trace(open_pack_or_rev_file(*file, TRUE, scratch_pool));
}
-svn_error_t *
-svn_fs_x__auto_read_footer(svn_fs_x__revision_file_t *file)
+/* If the revision file in FILE has not been opened, yet, do it now. */
+static svn_error_t *
+auto_open(svn_fs_x__revision_file_t *file)
+{
+ if (file->file == NULL)
+ SVN_ERR(open_pack_or_rev_file(file, FALSE, get_file_pool(file)));
+
+ return SVN_NO_ERROR;
+}
+
+/* If the footer data in FILE has not been read, yet, do so now.
+ * Index locations will only be read upon request as we assume they get
+ * cached and the FILE is usually used for REP data access only.
+ * Hence, the separate step.
+ */
+static svn_error_t *
+auto_read_footer(svn_fs_x__revision_file_t *file)
{
- if (file->l2p_offset == -1)
+ if (file->l2p_info.start == -1)
{
apr_off_t filesize = 0;
unsigned char footer_length;
svn_stringbuf_t *footer;
/* Determine file size. */
+ SVN_ERR(auto_open(file));
SVN_ERR(svn_io_file_seek(file->file, APR_END, &filesize, file->pool));
/* Read last byte (containing the length of the footer). */
@@ -258,22 +326,25 @@ svn_fs_x__auto_read_footer(svn_fs_x__rev
footer->data[footer->len] = '\0';
/* Extract index locations. */
- SVN_ERR(svn_fs_x__parse_footer(&file->l2p_offset, &file->l2p_checksum,
- &file->p2l_offset, &file->p2l_checksum,
- footer, file->start_revision,
+ SVN_ERR(svn_fs_x__parse_footer(&file->l2p_info.start,
+ &file->l2p_info.checksum,
+ &file->p2l_info.start,
+ &file->p2l_info.checksum,
+ footer, file->file_info.start_revision,
file->pool));
- file->footer_offset = filesize - footer_length - 1;
+ file->l2p_info.end = file->p2l_info.start;
+ file->p2l_info.end = filesize - footer_length - 1;
}
return SVN_NO_ERROR;
}
svn_error_t *
-svn_fs_x__open_proto_rev_file(svn_fs_x__revision_file_t **file,
- svn_fs_t *fs,
- svn_fs_x__txn_id_t txn_id,
- apr_pool_t* result_pool,
- apr_pool_t *scratch_pool)
+svn_fs_x__rev_file_open_proto_rev(svn_fs_x__revision_file_t **file,
+ svn_fs_t *fs,
+ svn_fs_x__txn_id_t txn_id,
+ apr_pool_t* result_pool,
+ apr_pool_t *scratch_pool)
{
apr_file_t *apr_file;
SVN_ERR(svn_io_file_open(&apr_file,
@@ -282,12 +353,12 @@ svn_fs_x__open_proto_rev_file(svn_fs_x__
APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
result_pool));
- return svn_error_trace(svn_fs_x__wrap_temp_rev_file(file, fs, apr_file,
+ return svn_error_trace(svn_fs_x__rev_file_wrap_temp(file, fs, apr_file,
result_pool));
}
svn_error_t *
-svn_fs_x__wrap_temp_rev_file(svn_fs_x__revision_file_t **file,
+svn_fs_x__rev_file_wrap_temp(svn_fs_x__revision_file_t **file,
svn_fs_t *fs,
apr_file_t *temp_file,
apr_pool_t *result_pool)
@@ -300,17 +371,159 @@ svn_fs_x__wrap_temp_rev_file(svn_fs_x__r
}
svn_error_t *
+svn_fs_x__rev_file_info(svn_fs_x__rev_file_info_t *info,
+ svn_fs_x__revision_file_t *file)
+{
+ SVN_ERR(auto_open(file));
+
+ *info = file->file_info;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__rev_file_name(const char **filename,
+ svn_fs_x__revision_file_t *file,
+ apr_pool_t *result_pool)
+{
+ SVN_ERR(auto_open(file));
+
+ return svn_error_trace(svn_io_file_name_get(filename, file->file,
+ result_pool));
+}
+
+svn_error_t *
+svn_fs_x__rev_file_stream(svn_stream_t **stream,
+ svn_fs_x__revision_file_t *file)
+{
+ SVN_ERR(auto_open(file));
+
+ *stream = file->stream;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__rev_file_get(apr_file_t **apr_file,
+ svn_fs_x__revision_file_t *file)
+{
+ SVN_ERR(auto_open(file));
+
+ *apr_file = file->file;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__rev_file_l2p_index(svn_fs_x__packed_number_stream_t **stream,
+ svn_fs_x__revision_file_t *file)
+{
+ if (file->l2p_stream == NULL)
+ {
+ SVN_ERR(auto_read_footer(file));
+ SVN_ERR(svn_fs_x__packed_stream_open(&file->l2p_stream,
+ file->file,
+ file->l2p_info.start,
+ file->l2p_info.end,
+ SVN_FS_X__L2P_STREAM_PREFIX,
+ (apr_size_t)file->block_size,
+ file->pool,
+ file->pool));
+ }
+
+ *stream = file->l2p_stream;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__rev_file_p2l_index(svn_fs_x__packed_number_stream_t **stream,
+ svn_fs_x__revision_file_t *file)
+{
+ if (file->p2l_stream== NULL)
+ {
+ SVN_ERR(auto_read_footer(file));
+ SVN_ERR(svn_fs_x__packed_stream_open(&file->p2l_stream,
+ file->file,
+ file->p2l_info.start,
+ file->p2l_info.end,
+ SVN_FS_X__P2L_STREAM_PREFIX,
+ (apr_size_t)file->block_size,
+ file->pool,
+ file->pool));
+ }
+
+ *stream = file->p2l_stream;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__rev_file_l2p_info(svn_fs_x__index_info_t *info,
+ svn_fs_x__revision_file_t *file)
+{
+ SVN_ERR(auto_read_footer(file));
+ *info = file->l2p_info;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__rev_file_p2l_info(svn_fs_x__index_info_t *info,
+ svn_fs_x__revision_file_t *file)
+{
+ SVN_ERR(auto_read_footer(file));
+ *info = file->p2l_info;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_x__rev_file_seek(svn_fs_x__revision_file_t *file,
+ apr_off_t *buffer_start,
+ apr_off_t offset)
+{
+ SVN_ERR(auto_open(file));
+ return svn_error_trace(svn_io_file_aligned_seek(file->file,
+ file->block_size,
+ buffer_start, offset,
+ file->pool));
+}
+
+svn_error_t *
+svn_fs_x__rev_file_offset(apr_off_t *offset,
+ svn_fs_x__revision_file_t *file)
+{
+ SVN_ERR(auto_open(file));
+ return svn_error_trace(svn_fs_x__get_file_offset(offset, file->file,
+ file->pool));
+}
+
+svn_error_t *
+svn_fs_x__rev_file_read(svn_fs_x__revision_file_t *file,
+ void *buf,
+ apr_size_t nbytes)
+{
+ SVN_ERR(auto_open(file));
+ return svn_error_trace(svn_io_file_read_full2(file->file, buf, nbytes,
+ NULL, NULL, file->pool));
+}
+
+svn_error_t *
svn_fs_x__close_revision_file(svn_fs_x__revision_file_t *file)
{
+ /* Close sub-objects properly */
if (file->stream)
SVN_ERR(svn_stream_close(file->stream));
if (file->file)
SVN_ERR(svn_io_file_close(file->file, file->pool));
+ /* Release the memory. */
+ if (file->pool)
+ svn_pool_clear(file->pool);
+
+ /* Reset pointers to objects previously allocated from FILE->POOL. */
file->file = NULL;
file->stream = NULL;
file->l2p_stream = NULL;
file->p2l_stream = NULL;
+ /* Cause any index data getters to re-read the footer. */
+ file->l2p_info.start = -1;
return SVN_NO_ERROR;
}