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 2013/10/14 19:11:01 UTC
svn commit: r1531982 - in
/subversion/branches/log-addressing/subversion/libsvn_fs_fs: cached_data.c
index.c index.h recovery.c rev_file.c rev_file.h util.c util.h verify.c
Author: stefan2
Date: Mon Oct 14 17:11:01 2013
New Revision: 1531982
URL: http://svn.apache.org/r1531982
Log:
On the log-addressing branch:
Introduce a new abstraction, the "revsion file" which ensures that all
files pertaining to a revision / pack file are read consistently wrt.
being packed. This is needed to read file offsets from index that
match the actual rev / pack file.
In this commit, we introduce the new API and use it when reading data
from the rev / pack file. We don't read index files consistently, yet.
* subversion/libsvn_fs_fs/rev_file.h
(): new file
(svn_fs_fs__packed_number_stream_t): publish previously private type
(svn_fs_fs__revision_file_t): declare new object type
(svn_fs_fs__init_revision_file,
svn_fs_fs__open_pack_or_rev_file,
svn_fs_fs__reopen_revision_file,
svn_fs_fs__open_proto_rev_file,
svn_fs_fs__close_revision_file): declare operations on that object
* subversion/libsvn_fs_fs/rev_file.c
(): new file
(open_pack_or_rev_file): logic taken from svn_fs_fs__open_pack_or_rev_file
in utils.c
(svn_fs_fs__init_revision_file,
svn_fs_fs__open_pack_or_rev_file,
svn_fs_fs__reopen_revision_file,
svn_fs_fs__open_proto_rev_file,
svn_fs_fs__close_revision_file): implement new API
* subversion/libsvn_fs_fs/util.h
(svn_fs_fs__open_pack_or_rev_file): remove here
* subversion/libsvn_fs_fs/util.c
(svn_fs_fs__open_pack_or_rev_file): remove here
* subversion/libsvn_fs_fs/cached_data.c
(block_read,
open_and_seek_revision,
open_and_seek_representation): replace plain APR file with new struct
(open_and_seek_transaction): ditto; use new API
(get_node_revision_body): use new type and API for committed data;
keep old code for txn data with file varible
being renamed for clarity
(get_fs_id_at_offset,
svn_fs_fs__rev_get_root): use new type and API
(shared_file_t): replace plain file member with new struct;
drop stream member because it is already provided by
the new revision file struct
(get_file_offset,
rs_aligned_seek): adapt to struct change
(auto_open_shared_file): use new API
(auto_read_diff_version,
create_rep_state_body
read_delta_window,
read_plain_window,
get_contents): adapt to struct change
(svn_fs_fs__get_file_delta_stream,
svn_fs_fs__get_changes): ditto; use new API
(init_rep_state,
cache_windows,
block_read_windows,
block_read_contents,
auto_select_stream,
block_read_changes,
block_read_noderev,
block_read): adapt to struct change; replace file+stream with new struct
* subversion/libsvn_fs_fs/index.h
(svn_fs_fs__packed_stream_close): publish previously private function
* subversion/libsvn_fs_fs/index.c
(packed_stream_close): rename to ...
(svn_fs_fs__packed_stream_close): ... this
(svn_fs_fs__packed_number_stream_t,
stream_error_create,
packed_stream_open,
packed_stream_get,
get_l2p_header_body,
get_l2p_page_info,
get_l2p_page,
prefetch_l2p_pages,
l2p_index_lookup,
get_l2p_header,
svn_fs_fs__l2p_get_max_ids,
get_p2l_header,
get_p2l_page_info,
get_p2l_page,
prefetch_p2l_page,
get_p2l_keys,
p2l_index_lookup,
svn_fs_fs__p2l_index_lookup,
p2l_entry_lookup,
svn_fs_fs__p2l_entry_lookup,
svn_fs_fs__p2l_get_max_offset): adapt to renamed stream type and
close function
* subversion/libsvn_fs_fs/recovery.c
(recover_get_largest_revision,
recover_find_max_ids): replace plain APR file with new struct
(svn_fs_fs__find_max_ids): ditto; use new API
* subversion/libsvn_fs_fs/verify.c
(compare_p2l_to_rev): replace plain APR file with new struct
Added:
subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.c
subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.h
Modified:
subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c
subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c
subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h
subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c
subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c
subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h
subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c?rev=1531982&r1=1531981&r2=1531982&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c Mon Oct 14 17:11:01 2013
@@ -46,7 +46,7 @@ block_read(void **result,
svn_fs_t *fs,
svn_revnum_t revision,
apr_uint64_t item_index,
- apr_file_t *revision_file,
+ svn_fs_fs__revision_file_t *revision_file,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -197,20 +197,20 @@ aligned_seek(svn_fs_t *fs,
the newly opened file in FILE. Seek to location OFFSET before
returning. Perform temporary allocations in POOL. */
static svn_error_t *
-open_and_seek_revision(apr_file_t **file,
+open_and_seek_revision(svn_fs_fs__revision_file_t **file,
svn_fs_t *fs,
svn_revnum_t rev,
apr_uint64_t item,
apr_pool_t *pool)
{
- apr_file_t *rev_file;
+ svn_fs_fs__revision_file_t *rev_file;
apr_off_t offset = -1;
SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, rev, pool));
SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev, NULL, item, pool));
- SVN_ERR(aligned_seek(fs, rev_file, NULL, offset, pool));
+ SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, pool));
*file = rev_file;
@@ -221,24 +221,18 @@ open_and_seek_revision(apr_file_t **file
to its position and store the newly opened file in FILE. Perform
temporary allocations in POOL. */
static svn_error_t *
-open_and_seek_transaction(apr_file_t **file,
+open_and_seek_transaction(svn_fs_fs__revision_file_t **file,
svn_fs_t *fs,
representation_t *rep,
apr_pool_t *pool)
{
- apr_file_t *rev_file;
apr_off_t offset;
- SVN_ERR(svn_io_file_open(&rev_file,
- svn_fs_fs__path_txn_proto_rev(fs, &rep->txn_id,
- pool),
- APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));
+ SVN_ERR(svn_fs_fs__open_proto_rev_file(file, fs, &rep->txn_id, pool));
SVN_ERR(svn_fs_fs__item_offset(&offset, fs, SVN_INVALID_REVNUM,
&rep->txn_id, rep->item_index, pool));
- SVN_ERR(aligned_seek(fs, rev_file, NULL, offset, pool));
-
- *file = rev_file;
+ SVN_ERR(aligned_seek(fs, (*file)->file, NULL, offset, pool));
return SVN_NO_ERROR;
}
@@ -247,7 +241,7 @@ open_and_seek_transaction(apr_file_t **f
the correct file and seek to the correction location. Store this
file in *FILE_P. Perform any allocations in POOL. */
static svn_error_t *
-open_and_seek_representation(apr_file_t **file_p,
+open_and_seek_representation(svn_fs_fs__revision_file_t **file_p,
svn_fs_t *fs,
representation_t *rep,
apr_pool_t *pool)
@@ -281,16 +275,17 @@ get_node_revision_body(node_revision_t *
const svn_fs_id_t *id,
apr_pool_t *pool)
{
- apr_file_t *revision_file;
svn_error_t *err;
svn_boolean_t is_cached = FALSE;
fs_fs_data_t *ffd = fs->fsap_data;
if (svn_fs_fs__id_is_txn(id))
{
+ apr_file_t *file;
+
/* This is a transaction node-rev. Its storage logic is very
different from that of rev / pack files. */
- err = svn_io_file_open(&revision_file,
+ err = svn_io_file_open(&file,
svn_fs_fs__path_txn_node_rev(fs, id, pool),
APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
if (err)
@@ -305,13 +300,15 @@ get_node_revision_body(node_revision_t *
}
SVN_ERR(svn_fs_fs__read_noderev(noderev_p,
- svn_stream_from_aprfile2(revision_file,
+ svn_stream_from_aprfile2(file,
FALSE,
pool),
pool));
}
else
{
+ svn_fs_fs__revision_file_t *revision_file;
+
/* noderevs in rev / pack files can be cached */
const svn_fs_fs__id_part_t *rev_item = svn_fs_fs__id_rev_item(id);
pair_cache_key_t key;
@@ -347,15 +344,13 @@ get_node_revision_body(node_revision_t *
revision_file,
pool,
pool));
- SVN_ERR(svn_io_file_close(revision_file, pool));
+ SVN_ERR(svn_fs_fs__close_revision_file(revision_file));
}
else
{
/* physical addressing mode reading, parsing and caching */
SVN_ERR(svn_fs_fs__read_noderev(noderev_p,
- svn_stream_from_aprfile2(revision_file,
- FALSE,
- pool),
+ revision_file->stream,
pool));
/* Workaround issue #4031: is-fresh-txn-root in revision files. */
@@ -406,7 +401,7 @@ svn_fs_fs__get_node_revision(node_revisi
temporary variables from POOL. */
static svn_error_t *
get_fs_id_at_offset(svn_fs_id_t **id_p,
- apr_file_t *rev_file,
+ svn_fs_fs__revision_file_t *rev_file,
svn_fs_t *fs,
svn_revnum_t rev,
apr_off_t offset,
@@ -414,10 +409,9 @@ get_fs_id_at_offset(svn_fs_id_t **id_p,
{
node_revision_t *noderev;
- SVN_ERR(aligned_seek(fs, rev_file, NULL, offset, pool));
+ SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, pool));
SVN_ERR(svn_fs_fs__read_noderev(&noderev,
- svn_stream_from_aprfile2(rev_file, TRUE,
- pool),
+ rev_file->stream,
pool));
/* noderev->id is const, get rid of that */
@@ -530,7 +524,7 @@ svn_fs_fs__rev_get_root(svn_fs_id_t **ro
}
else
{
- apr_file_t *revision_file;
+ svn_fs_fs__revision_file_t *revision_file;
apr_off_t root_offset;
svn_fs_id_t *root_id = NULL;
svn_boolean_t is_cached;
@@ -541,13 +535,13 @@ svn_fs_fs__rev_get_root(svn_fs_id_t **ro
return SVN_NO_ERROR;
SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&revision_file, fs, rev, pool));
- SVN_ERR(get_root_changes_offset(&root_offset, NULL, revision_file,
- fs, rev, pool));
+ SVN_ERR(get_root_changes_offset(&root_offset, NULL,
+ revision_file->file, fs, rev, pool));
SVN_ERR(get_fs_id_at_offset(&root_id, revision_file, fs, rev,
root_offset, pool));
- SVN_ERR(svn_io_file_close(revision_file, pool));
+ SVN_ERR(svn_fs_fs__close_revision_file(revision_file));
SVN_ERR(svn_cache__set(ffd->rev_root_id_cache, &rev, root_id, pool));
@@ -562,10 +556,7 @@ svn_fs_fs__rev_get_root(svn_fs_id_t **ro
typedef struct shared_file_t
{
/* The opened file. NULL while file is not open, yet. */
- apr_file_t *file;
-
- /* Stream wrapper around FILE. NULL while file is not open, yet. */
- svn_stream_t *stream;
+ svn_fs_fs__revision_file_t *rfile;
/* file system to open the file in */
svn_fs_t *fs;
@@ -615,7 +606,7 @@ get_file_offset(apr_off_t *offset,
apr_pool_t *pool)
{
return svn_error_trace(svn_fs_fs__get_file_offset(offset,
- rs->sfile->file,
+ rs->sfile->rfile->file,
pool));
}
@@ -627,7 +618,7 @@ rs_aligned_seek(rep_state_t *rs,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = rs->sfile->fs->fsap_data;
- return svn_error_trace(svn_io_file_aligned_seek(rs->sfile->file,
+ return svn_error_trace(svn_io_file_aligned_seek(rs->sfile->rfile->file,
ffd->block_size,
buffer_start, offset,
pool));
@@ -637,12 +628,9 @@ rs_aligned_seek(rep_state_t *rs,
static svn_error_t*
auto_open_shared_file(shared_file_t *file)
{
- if (file->file == NULL)
- {
- SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&file->file, file->fs,
- file->revision, file->pool));
- file->stream = svn_stream_from_aprfile2(file->file, TRUE, file->pool);
- }
+ if (file->rfile == NULL)
+ SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&file->rfile, file->fs,
+ file->revision, file->pool));
return SVN_NO_ERROR;
}
@@ -673,7 +661,7 @@ auto_read_diff_version(rep_state_t *rs,
{
char buf[4];
SVN_ERR(rs_aligned_seek(rs, NULL, rs->start, pool));
- SVN_ERR(svn_io_file_read_full2(rs->sfile->file, buf,
+ SVN_ERR(svn_io_file_read_full2(rs->sfile->rfile->file, buf,
sizeof(buf), NULL, NULL, pool));
/* ### Layering violation */
@@ -713,7 +701,7 @@ create_rep_state_body(rep_state_t **rep_
* we can re-use the same, already open file object
*/
svn_boolean_t reuse_shared_file
- = shared_file && *shared_file && (*shared_file)->file
+ = shared_file && *shared_file && (*shared_file)->rfile
&& SVN_IS_VALID_REVNUM((*shared_file)->revision)
&& (*shared_file)->revision < ffd->min_unpacked_rev
&& rep->revision < ffd->min_unpacked_rev
@@ -780,13 +768,11 @@ create_rep_state_body(rep_state_t **rep_
/* otherwise, create a new file object. May or may not be
* an in-txn file.
*/
- SVN_ERR(open_and_seek_representation(&rs->sfile->file, fs, rep,
+ SVN_ERR(open_and_seek_representation(&rs->sfile->rfile, fs, rep,
pool));
- rs->sfile->stream = svn_stream_from_aprfile2(rs->sfile->file, TRUE,
- rs->sfile->pool);
}
- SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->sfile->stream, pool));
+ SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->sfile->rfile->stream, pool));
SVN_ERR(get_file_offset(&rs->start, rs, pool));
/* populate the cache if appropriate */
@@ -794,7 +780,7 @@ create_rep_state_body(rep_state_t **rep_
{
if (svn_fs_fs__use_log_addressing(fs, rep->revision))
SVN_ERR(block_read(NULL, fs, rep->revision, rep->item_index,
- rs->sfile->file, pool, pool));
+ rs->sfile->rfile, pool, pool));
else
if (ffd->rep_header_cache)
SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh, pool));
@@ -1318,7 +1304,7 @@ read_delta_window(svn_txdelta_window_t *
&& svn_fs_fs__use_log_addressing(rs->sfile->fs, rs->revision))
{
SVN_ERR(block_read(NULL, rs->sfile->fs, rs->revision, rs->item_index,
- rs->sfile->file, pool, pool));
+ rs->sfile->rfile, pool, pool));
/* reading the whole block probably also provided us with the
desired txdelta window */
@@ -1340,7 +1326,7 @@ read_delta_window(svn_txdelta_window_t *
/* Skip windows to reach the current chunk if we aren't there yet. */
while (rs->chunk_index < this_chunk)
{
- SVN_ERR(svn_txdelta_skip_svndiff_window(rs->sfile->file,
+ SVN_ERR(svn_txdelta_skip_svndiff_window(rs->sfile->rfile->file,
rs->ver, pool));
rs->chunk_index++;
SVN_ERR(get_file_offset(&start_offset, rs, pool));
@@ -1353,7 +1339,7 @@ read_delta_window(svn_txdelta_window_t *
}
/* Actually read the next window. */
- SVN_ERR(svn_txdelta_read_svndiff_window(nwin, rs->sfile->stream,
+ SVN_ERR(svn_txdelta_read_svndiff_window(nwin, rs->sfile->rfile->stream,
rs->ver, pool));
SVN_ERR(get_file_offset(&end_offset, rs, pool));
rs->current = end_offset - rs->start;
@@ -1387,7 +1373,7 @@ read_plain_window(svn_stringbuf_t **nwin
/* Read the plain data. */
*nwin = svn_stringbuf_create_ensure(size, pool);
- SVN_ERR(svn_io_file_read_full2(rs->sfile->file, (*nwin)->data, size,
+ SVN_ERR(svn_io_file_read_full2(rs->sfile->rfile->file, (*nwin)->data, size,
NULL, NULL, pool));
(*nwin)->data[size] = 0;
@@ -1545,7 +1531,7 @@ get_contents(struct rep_read_baton *rb,
offset = rs->start + rs->current;
SVN_ERR(rs_aligned_seek(rs, NULL, offset, rb->pool));
- SVN_ERR(svn_io_file_read_full2(rs->sfile->file, cur,
+ SVN_ERR(svn_io_file_read_full2(rs->sfile->rfile->file, cur,
copy_len, NULL, NULL, rb->pool));
}
@@ -1837,9 +1823,10 @@ svn_fs_fs__get_file_delta_stream(svn_txd
delta_read_md5_digest, pool);
return SVN_NO_ERROR;
}
- else if (rep_state->sfile->file)
+ else if (rep_state->sfile->rfile)
{
- SVN_ERR(svn_io_file_close(rep_state->sfile->file, pool));
+ SVN_ERR(svn_fs_fs__close_revision_file(rep_state->sfile->rfile));
+ rep_state->sfile->rfile = NULL;
}
}
@@ -2166,7 +2153,7 @@ svn_fs_fs__get_changes(apr_array_header_
apr_pool_t *pool)
{
apr_off_t changes_offset;
- apr_file_t *revision_file;
+ svn_fs_fs__revision_file_t *revision_file;
svn_boolean_t found;
fs_fs_data_t *ffd = fs->fsap_data;
@@ -2195,13 +2182,13 @@ svn_fs_fs__get_changes(apr_array_header_
{
/* physical addressing mode code path */
SVN_ERR(get_root_changes_offset(NULL, &changes_offset,
- revision_file, fs, rev, pool));
+ revision_file->file, fs, rev,
+ pool));
- SVN_ERR(aligned_seek(fs, revision_file, NULL, changes_offset,
+ SVN_ERR(aligned_seek(fs, revision_file->file, NULL, changes_offset,
pool));
- SVN_ERR(svn_fs_fs__read_changes(changes,
- svn_stream_from_aprfile2(revision_file, TRUE, pool),
- pool));
+ SVN_ERR(svn_fs_fs__read_changes(changes, revision_file->stream,
+ pool));
/* cache for future reference */
@@ -2209,7 +2196,7 @@ svn_fs_fs__get_changes(apr_array_header_
SVN_ERR(svn_cache__set(ffd->changes_cache, &rev, *changes, pool));
}
- SVN_ERR(svn_io_file_close(revision_file, pool));
+ SVN_ERR(svn_fs_fs__close_revision_file(revision_file));
}
SVN_ERR(dbg_log_access(fs, rev, changes_offset, *changes,
@@ -2226,8 +2213,7 @@ static svn_error_t *
init_rep_state(rep_state_t *rs,
svn_fs_fs__rep_header_t *rep_header,
svn_fs_t *fs,
- apr_file_t *file,
- svn_stream_t *stream,
+ svn_fs_fs__revision_file_t *file,
svn_fs_fs__p2l_entry_t* entry,
apr_pool_t *pool)
{
@@ -2238,8 +2224,7 @@ init_rep_state(rep_state_t *rs,
SVN_ERR_ASSERT(entry->type >= SVN_FS_FS__ITEM_TYPE_FILE_REP
&& entry->type <= SVN_FS_FS__ITEM_TYPE_DIR_PROPS);
- shared_file->file = file;
- shared_file->stream = stream;
+ shared_file->rfile = file;
shared_file->fs = fs;
shared_file->revision = entry->item.revision;
shared_file->pool = pool;
@@ -2281,7 +2266,7 @@ cache_windows(svn_filesize_t *fulltext_l
/* navigate to & read the current window */
SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, pool));
SVN_ERR(svn_txdelta_read_svndiff_window(&window,
- rs->sfile->stream,
+ rs->sfile->rfile->stream,
rs->ver, pool));
/* aggregate expanded window size */
@@ -2312,8 +2297,7 @@ cache_windows(svn_filesize_t *fulltext_l
static svn_error_t *
block_read_windows(svn_fs_fs__rep_header_t *rep_header,
svn_fs_t *fs,
- apr_file_t *file,
- svn_stream_t *stream,
+ svn_fs_fs__revision_file_t *rev_file,
svn_fs_fs__p2l_entry_t* entry,
apr_pool_t *pool)
{
@@ -2329,7 +2313,7 @@ block_read_windows(svn_fs_fs__rep_header
&& !ffd->combined_window_cache))
return SVN_NO_ERROR;
- SVN_ERR(init_rep_state(&rs, rep_header, fs, file, stream, entry, pool));
+ SVN_ERR(init_rep_state(&rs, rep_header, fs, rev_file, entry, pool));
/* RS->FILE may be shared between RS instances -> make sure we point
* to the right data. */
@@ -2347,10 +2331,10 @@ block_read_windows(svn_fs_fs__rep_header
/* for larger reps, the header may have crossed a block boundary.
* make sure we still read blocks properly aligned, i.e. don't use
* plain seek here. */
- SVN_ERR(aligned_seek(fs, file, NULL, offset, pool));
+ SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, pool));
plaintext = svn_stringbuf_create_ensure(rs.size, pool);
- SVN_ERR(svn_io_file_read_full2(file, plaintext->data,
+ SVN_ERR(svn_io_file_read_full2(rev_file->file, plaintext->data,
rs.size, &plaintext->len, NULL, pool));
plaintext->data[plaintext->len] = 0;
rs.current += rs.size;
@@ -2404,8 +2388,7 @@ read_rep_header(svn_fs_fs__rep_header_t
*/
static svn_error_t *
block_read_contents(svn_fs_t *fs,
- apr_file_t *file,
- svn_stream_t *stream,
+ svn_fs_fs__revision_file_t *rev_file,
svn_fs_fs__p2l_entry_t* entry,
apr_pool_t *pool)
{
@@ -2416,8 +2399,9 @@ block_read_contents(svn_fs_t *fs,
header_key.is_packed = svn_fs_fs__is_packed_rev(fs, header_key.revision);
header_key.item_index = entry->item.number;
- SVN_ERR(read_rep_header(&rep_header, fs, stream, &header_key, pool));
- SVN_ERR(block_read_windows(rep_header, fs, file, stream, entry, pool));
+ SVN_ERR(read_rep_header(&rep_header, fs, rev_file->stream, &header_key,
+ pool));
+ SVN_ERR(block_read_windows(rep_header, fs, rev_file, entry, pool));
return SVN_NO_ERROR;
}
@@ -2429,8 +2413,7 @@ block_read_contents(svn_fs_t *fs,
static svn_error_t *
auto_select_stream(svn_stream_t **stream,
svn_fs_t *fs,
- apr_file_t *file,
- svn_stream_t *file_stream,
+ svn_fs_fs__revision_file_t *rev_file,
svn_fs_fs__p2l_entry_t* entry,
apr_pool_t *pool)
{
@@ -2447,13 +2430,13 @@ auto_select_stream(svn_stream_t **stream
svn_stringbuf_t *text = svn_stringbuf_create_ensure(entry->size, pool);
text->len = entry->size;
text->data[text->len] = 0;
- SVN_ERR(svn_io_file_read_full2(file, text->data, text->len,
+ SVN_ERR(svn_io_file_read_full2(rev_file->file, text->data, text->len,
NULL, NULL, pool));
*stream = svn_stream_from_stringbuf(text, pool);
}
else
{
- *stream = file_stream;
+ *stream = rev_file->stream;
}
return SVN_NO_ERROR;
@@ -2467,8 +2450,7 @@ auto_select_stream(svn_stream_t **stream
static svn_error_t *
block_read_changes(apr_array_header_t **changes,
svn_fs_t *fs,
- apr_file_t *file,
- svn_stream_t *file_stream,
+ svn_fs_fs__revision_file_t *rev_file,
svn_fs_fs__p2l_entry_t* entry,
svn_boolean_t must_read,
apr_pool_t *pool)
@@ -2488,7 +2470,7 @@ block_read_changes(apr_array_header_t **
return SVN_NO_ERROR;
}
- SVN_ERR(auto_select_stream(&stream, fs, file, file_stream, entry, pool));
+ SVN_ERR(auto_select_stream(&stream, fs, rev_file, entry, pool));
/* read changes from revision file */
@@ -2511,8 +2493,7 @@ block_read_changes(apr_array_header_t **
static svn_error_t *
block_read_noderev(node_revision_t **noderev_p,
svn_fs_t *fs,
- apr_file_t *file,
- svn_stream_t *file_stream,
+ svn_fs_fs__revision_file_t *rev_file,
svn_fs_fs__p2l_entry_t* entry,
svn_boolean_t must_read,
apr_pool_t *pool)
@@ -2537,7 +2518,7 @@ block_read_noderev(node_revision_t **nod
return SVN_NO_ERROR;
}
- SVN_ERR(auto_select_stream(&stream, fs, file, file_stream, entry, pool));
+ SVN_ERR(auto_select_stream(&stream, fs, rev_file, entry, pool));
/* read node rev from revision file */
@@ -2567,7 +2548,7 @@ block_read(void **result,
svn_fs_t *fs,
svn_revnum_t revision,
apr_uint64_t item_index,
- apr_file_t *revision_file,
+ svn_fs_fs__revision_file_t *revision_file,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -2578,8 +2559,6 @@ block_read(void **result,
int run_count = 0;
int i;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- svn_stream_t *stream = svn_stream_from_aprfile2(revision_file, TRUE,
- scratch_pool);
/* don't try this on transaction protorev files */
SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision));
@@ -2603,7 +2582,8 @@ block_read(void **result,
{
SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, revision, offset,
scratch_pool));
- SVN_ERR(aligned_seek(fs, revision_file, &block_start, offset, iterpool));
+ SVN_ERR(aligned_seek(fs, revision_file->file, &block_start, offset,
+ iterpool));
/* read all items from the block */
for (i = 0; i < entries->nelts; ++i)
@@ -2634,7 +2614,7 @@ block_read(void **result,
&& entry->size < ffd->block_size))
{
void *item = NULL;
- SVN_ERR(svn_io_file_seek(revision_file, SEEK_SET,
+ SVN_ERR(svn_io_file_seek(revision_file->file, SEEK_SET,
&entry->offset, iterpool));
switch (entry->type)
{
@@ -2642,20 +2622,20 @@ block_read(void **result,
case SVN_FS_FS__ITEM_TYPE_DIR_REP:
case SVN_FS_FS__ITEM_TYPE_FILE_PROPS:
case SVN_FS_FS__ITEM_TYPE_DIR_PROPS:
- SVN_ERR(block_read_contents(fs, revision_file, stream,
- entry, pool));
+ SVN_ERR(block_read_contents(fs, revision_file, entry,
+ pool));
break;
case SVN_FS_FS__ITEM_TYPE_NODEREV:
if (ffd->node_revision_cache || is_result)
SVN_ERR(block_read_noderev((node_revision_t **)&item,
- fs, revision_file, stream,
+ fs, revision_file,
entry, is_result, pool));
break;
case SVN_FS_FS__ITEM_TYPE_CHANGES:
SVN_ERR(block_read_changes((apr_array_header_t **)&item,
- fs, revision_file, stream,
+ fs, revision_file,
entry, is_result, pool));
break;
@@ -2682,7 +2662,6 @@ block_read(void **result,
/* if the caller requested a result, we must have provided one by now */
assert(!result || *result);
- SVN_ERR(svn_stream_close(stream));
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c?rev=1531982&r1=1531981&r2=1531982&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c Mon Oct 14 17:11:01 2013
@@ -35,6 +35,7 @@
#include "pack.h"
#include "temp_serializer.h"
#include "util.h"
+#include "fs_fs.h"
#include "../libsvn_fs/fs-loader.h"
@@ -152,7 +153,7 @@ typedef struct value_position_pair_t
/* State of a prefetching packed number stream. It will read compressed
* index data efficiently and present it as a series of non-packed uint64.
*/
-typedef struct packed_number_stream_t
+struct svn_fs_fs__packed_number_stream_t
{
/* underlying data file containing the packed values */
apr_file_t *file;
@@ -178,14 +179,14 @@ typedef struct packed_number_stream_t
/* buffer for prefetched values */
value_position_pair_t buffer[MAX_NUMBER_PREFETCH];
-} packed_number_stream_t;
+};
/* Return an svn_error_t * object for error ERR on STREAM with the given
* MESSAGE string. The latter must have a placeholder for the index file
* name ("%s") and the current read offset (e.g. "0x%lx").
*/
static svn_error_t *
-stream_error_create(packed_number_stream_t *stream,
+stream_error_create(svn_fs_fs__packed_number_stream_t *stream,
apr_status_t err,
const char *message)
{
@@ -207,7 +208,7 @@ stream_error_create(packed_number_stream
*/
SVN__PREVENT_INLINE
static svn_error_t *
-packed_stream_read(packed_number_stream_t *stream)
+packed_stream_read(svn_fs_fs__packed_number_stream_t *stream)
{
unsigned char buffer[MAX_NUMBER_PREFETCH];
apr_size_t read = 0;
@@ -302,18 +303,19 @@ packed_stream_read(packed_number_stream_
* Use POOL for allocations.
*/
static svn_error_t *
-packed_stream_open(packed_number_stream_t **stream,
+packed_stream_open(svn_fs_fs__packed_number_stream_t **stream,
const char *file_name,
apr_size_t block_size,
apr_pool_t *pool)
{
- packed_number_stream_t *result = apr_palloc(pool, sizeof(*result));
+ svn_fs_fs__packed_number_stream_t *result
+ = apr_palloc(pool, sizeof(*result));
result->pool = svn_pool_create(pool);
SVN_ERR(svn_io_file_open(&result->file, file_name,
APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
result->pool));
-
+
result->used = 0;
result->current = 0;
result->start_offset = 0;
@@ -327,9 +329,8 @@ packed_stream_open(packed_number_stream_
/* Close STREAM which may be NULL.
*/
-SVN__FORCE_INLINE
-static svn_error_t *
-packed_stream_close(packed_number_stream_t *stream)
+svn_error_t *
+svn_fs_fs__packed_stream_close(svn_fs_fs__packed_number_stream_t *stream)
{
if (stream)
{
@@ -347,7 +348,7 @@ packed_stream_close(packed_number_stream
SVN__FORCE_INLINE
static svn_error_t*
packed_stream_get(apr_uint64_t *value,
- packed_number_stream_t *stream)
+ svn_fs_fs__packed_number_stream_t *stream)
{
if (stream->current == stream->used)
SVN_ERR(packed_stream_read(stream));
@@ -362,7 +363,7 @@ packed_stream_get(apr_uint64_t *value,
* whether the given OFFSET is valid.
*/
static void
-packed_stream_seek(packed_number_stream_t *stream,
+packed_stream_seek(svn_fs_fs__packed_number_stream_t *stream,
apr_off_t offset)
{
if ( stream->used == 0
@@ -393,7 +394,7 @@ packed_stream_seek(packed_number_stream_
* can be found.
*/
static apr_off_t
-packed_stream_offset(packed_number_stream_t *stream)
+packed_stream_offset(svn_fs_fs__packed_number_stream_t *stream)
{
return stream->current == 0
? stream->start_offset
@@ -703,7 +704,7 @@ svn_fs_fs__l2p_index_create(svn_fs_t *fs
* REVISION in FS and return it in *STREAM. Use POOL for allocations.
*/
static svn_error_t *
-auto_open_l2p_index(packed_number_stream_t **stream,
+auto_open_l2p_index(svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t revision,
apr_pool_t *pool)
@@ -727,7 +728,7 @@ auto_open_l2p_index(packed_number_stream
*/
static svn_error_t *
get_l2p_header_body(l2p_header_t **header,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t revision,
apr_pool_t *pool)
@@ -911,7 +912,7 @@ l2p_page_info_access_func(void **out,
*/
static svn_error_t *
get_l2p_page_info(l2p_page_info_baton_t *baton,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
apr_pool_t *pool)
{
@@ -1029,7 +1030,7 @@ get_l2p_page_table(apr_array_header_t *p
*/
static svn_error_t *
get_l2p_page(l2p_page_t **page,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t start_revision,
l2p_page_table_entry_t *table_entry,
@@ -1074,7 +1075,7 @@ get_l2p_page(l2p_page_t **page,
static svn_error_t *
prefetch_l2p_pages(svn_boolean_t *end,
svn_fs_t *fs,
- packed_number_stream_t *stream,
+ svn_fs_fs__packed_number_stream_t *stream,
svn_revnum_t first_revision,
svn_revnum_t revision,
apr_array_header_t *pages,
@@ -1219,7 +1220,7 @@ l2p_index_lookup(apr_off_t *offset,
l2p_page_info_baton_t info_baton;
l2p_entry_baton_t page_baton;
l2p_page_t *page = NULL;
- packed_number_stream_t *stream = NULL;
+ svn_fs_fs__packed_number_stream_t *stream = NULL;
svn_fs_fs__page_cache_key_t key = { 0 };
svn_boolean_t is_cached = FALSE;
void *dummy = NULL;
@@ -1301,7 +1302,7 @@ l2p_index_lookup(apr_off_t *offset,
svn_pool_destroy(iterpool);
}
- SVN_ERR(packed_stream_close(stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(stream));
*offset = page_baton.offset;
@@ -1356,7 +1357,7 @@ l2p_proto_index_lookup(apr_off_t *offset
*/
static svn_error_t *
get_l2p_header(l2p_header_t **header,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t revision,
apr_pool_t *pool)
@@ -1389,12 +1390,12 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
l2p_header_t *header = NULL;
svn_revnum_t revision;
svn_revnum_t last_rev = (svn_revnum_t)(start_rev + count);
- packed_number_stream_t *stream = NULL;
+ svn_fs_fs__packed_number_stream_t *stream = NULL;
apr_pool_t *header_pool = svn_pool_create(pool);
/* read index master data structure for the index covering START_REV */
SVN_ERR(get_l2p_header(&header, &stream, fs, start_rev, header_pool));
- SVN_ERR(packed_stream_close(stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(stream));
stream = NULL;
/* Determine the length of the item index list for each rev.
@@ -1413,7 +1414,7 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
svn_pool_clear(header_pool);
SVN_ERR(get_l2p_header(&header, &stream, fs, revision,
header_pool));
- SVN_ERR(packed_stream_close(stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(stream));
stream = NULL;
}
@@ -1693,7 +1694,7 @@ svn_fs_fs__p2l_index_create(svn_fs_t *fs
*/
static svn_error_t *
get_p2l_header(p2l_header_t **header,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t revision,
apr_pool_t *stream_pool,
@@ -1860,7 +1861,7 @@ p2l_page_info_func(void **out,
*/
static svn_error_t *
get_p2l_page_info(p2l_page_info_baton_t *baton,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
apr_pool_t *stream_pool,
apr_pool_t *pool)
@@ -1894,7 +1895,7 @@ get_p2l_page_info(p2l_page_info_baton_t
* be moved forward by the size of entry. Use POOL for allocations.
*/
static svn_error_t *
-read_entry(packed_number_stream_t *stream,
+read_entry(svn_fs_fs__packed_number_stream_t *stream,
apr_off_t *item_offset,
svn_revnum_t *last_revision,
apr_uint64_t *last_compound,
@@ -1938,7 +1939,7 @@ read_entry(packed_number_stream_t *strea
*/
static svn_error_t *
get_p2l_page(apr_array_header_t **entries,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t start_revision,
apr_off_t start_offset,
@@ -2013,7 +2014,7 @@ static svn_error_t *
prefetch_p2l_page(svn_boolean_t *end,
int *leaking_bucket,
svn_fs_t *fs,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
p2l_page_info_baton_t *baton,
apr_off_t min_offset,
apr_pool_t *stream_pool,
@@ -2080,7 +2081,7 @@ prefetch_p2l_page(svn_boolean_t *end,
static svn_error_t *
get_p2l_keys(p2l_page_info_baton_t *page_info_p,
svn_fs_fs__page_cache_key_t *key_p,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t revision,
apr_off_t offset,
@@ -2097,7 +2098,7 @@ get_p2l_keys(p2l_page_info_baton_t *page
/* if the offset refers to a non-existent page, bail out */
if (page_info.page_count <= page_info.page_no)
{
- SVN_ERR(packed_stream_close(*stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(*stream));
return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL,
_("Offset %s too large in revision %ld"),
apr_off_t_toa(pool, offset), revision);
@@ -2127,7 +2128,7 @@ get_p2l_keys(p2l_page_info_baton_t *page
*/
static svn_error_t *
p2l_index_lookup(apr_array_header_t **entries,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t revision,
apr_off_t offset,
@@ -2212,13 +2213,13 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
apr_off_t offset,
apr_pool_t *pool)
{
- packed_number_stream_t *stream = NULL;
+ svn_fs_fs__packed_number_stream_t *stream = NULL;
/* look for this page in our cache */
SVN_ERR(p2l_index_lookup(entries, &stream, fs, revision, offset, pool));
/* make sure we close files after usage */
- SVN_ERR(packed_stream_close(stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(stream));
return SVN_NO_ERROR;
}
@@ -2291,7 +2292,7 @@ p2l_entry_lookup_func(void **out,
static svn_error_t *
p2l_entry_lookup(svn_fs_fs__p2l_entry_t **entry_p,
- packed_number_stream_t **stream,
+ svn_fs_fs__packed_number_stream_t **stream,
svn_fs_t *fs,
svn_revnum_t revision,
apr_off_t offset,
@@ -2342,13 +2343,13 @@ svn_fs_fs__p2l_entry_lookup(svn_fs_fs__p
apr_off_t offset,
apr_pool_t *pool)
{
- packed_number_stream_t *stream = NULL;
+ svn_fs_fs__packed_number_stream_t *stream = NULL;
/* look for this info in our cache */
SVN_ERR(p2l_entry_lookup(entry_p, &stream, fs, revision, offset, pool));
/* make sure we close files after usage */
- SVN_ERR(packed_stream_close(stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(stream));
return SVN_NO_ERROR;
}
@@ -2377,7 +2378,7 @@ svn_fs_fs__p2l_get_max_offset(apr_off_t
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
- packed_number_stream_t *stream = NULL;
+ svn_fs_fs__packed_number_stream_t *stream = NULL;
p2l_header_t *header;
svn_boolean_t is_cached = FALSE;
apr_off_t *offset_p;
@@ -2400,7 +2401,7 @@ svn_fs_fs__p2l_get_max_offset(apr_off_t
*offset = header->file_size;
/* make sure we close files after usage */
- SVN_ERR(packed_stream_close(stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(stream));
return SVN_NO_ERROR;
}
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h?rev=1531982&r1=1531981&r2=1531982&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h Mon Oct 14 17:11:01 2013
@@ -24,6 +24,7 @@
#define SVN_LIBSVN_FS__INDEX_H
#include "fs.h"
+#include "rev_file.h"
/* Per-defined item index values. They are used to identify empty or
* mandatory items.
@@ -69,6 +70,10 @@ typedef struct svn_fs_fs__p2l_entry_t
svn_fs_fs__id_part_t item;
} svn_fs_fs__p2l_entry_t;
+/* Close the index file STREAM and underlying file handle. */
+svn_error_t *
+svn_fs_fs__packed_stream_close(svn_fs_fs__packed_number_stream_t *stream);
+
/* Open / create a log-to-phys index file with the full file path name
* FILE_NAME. Return the open file in *PROTO_INDEX and use POOL for
* allocations.
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c?rev=1531982&r1=1531981&r2=1531982&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c Mon Oct 14 17:11:01 2013
@@ -54,7 +54,7 @@ recover_get_largest_revision(svn_fs_t *f
while (1)
{
svn_error_t *err;
- apr_file_t *file;
+ svn_fs_fs__revision_file_t *file;
err = svn_fs_fs__open_pack_or_rev_file(&file, fs, right, iterpool);
svn_pool_clear(iterpool);
@@ -78,7 +78,7 @@ recover_get_largest_revision(svn_fs_t *f
{
svn_revnum_t probe = left + ((right - left) / 2);
svn_error_t *err;
- apr_file_t *file;
+ svn_fs_fs__revision_file_t *file;
err = svn_fs_fs__open_pack_or_rev_file(&file, fs, probe, iterpool);
svn_pool_clear(iterpool);
@@ -147,7 +147,7 @@ read_handler_recover(void *baton, char *
static svn_error_t *
recover_find_max_ids(svn_fs_t *fs,
svn_revnum_t rev,
- apr_file_t *rev_file,
+ svn_fs_fs__revision_file_t *rev_file,
apr_off_t offset,
apr_uint64_t *max_node_id,
apr_uint64_t *max_copy_id,
@@ -161,8 +161,8 @@ recover_find_max_ids(svn_fs_t *fs,
apr_pool_t *iterpool;
node_revision_t *noderev;
- baton.stream = svn_stream_from_aprfile2(rev_file, TRUE, pool);
- SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &offset, pool));
+ baton.stream = rev_file->stream;
+ SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &offset, pool));
SVN_ERR(svn_fs_fs__read_noderev(&noderev, baton.stream, pool));
/* Check that this is a directory. It should be. */
@@ -185,7 +185,7 @@ recover_find_max_ids(svn_fs_t *fs,
rely on directory entries being stored as PLAIN reps, though. */
SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev, NULL,
noderev->data_rep->item_index, pool));
- SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &offset, pool));
+ SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &offset, pool));
SVN_ERR(svn_fs_fs__read_rep_header(&header, baton.stream, pool));
if (header->type != svn_fs_fs__rep_plain)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -286,7 +286,7 @@ svn_fs_fs__find_max_ids(svn_fs_t *fs,
{
fs_fs_data_t *ffd = fs->fsap_data;
apr_off_t root_offset;
- apr_file_t *rev_file;
+ svn_fs_fs__revision_file_t *rev_file;
svn_fs_id_t *root_id;
/* call this function for old repo formats only */
@@ -302,7 +302,7 @@ svn_fs_fs__find_max_ids(svn_fs_t *fs,
SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, youngest, pool));
SVN_ERR(recover_find_max_ids(fs, youngest, rev_file, root_offset,
max_node_id, max_copy_id, pool));
- SVN_ERR(svn_io_file_close(rev_file, pool));
+ SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
return SVN_NO_ERROR;
}
Added: subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.c?rev=1531982&view=auto
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.c (added)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.c Mon Oct 14 17:11:01 2013
@@ -0,0 +1,176 @@
+/* rev_file.c --- revision file and index access functions
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#include "rev_file.h"
+#include "fs_fs.h"
+#include "index.h"
+#include "util.h"
+
+#include "../libsvn_fs/fs-loader.h"
+
+#include "svn_private_config.h"
+
+void
+svn_fs_fs__init_revision_file(svn_fs_fs__revision_file_t *file,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_pool_t *pool)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ file->is_packed = svn_fs_fs__is_packed_rev(fs, revision);
+ file->start_revision = revision < ffd->min_unpacked_rev
+ ? revision - (revision % ffd->max_files_per_dir)
+ : revision;
+
+ file->file = NULL;
+ file->stream = NULL;
+ file->p2l_stream = NULL;
+ file->l2p_stream = NULL;
+ file->pool = pool;
+}
+
+/* Core implementation of svn_fs_fs__open_pack_or_rev_file working on an
+ * existing, initialized FILE structure.
+ */
+static svn_error_t *
+open_pack_or_rev_file(svn_fs_fs__revision_file_t *file,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *pool)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+ svn_error_t *err;
+ svn_boolean_t retry = FALSE;
+
+ do
+ {
+ const char *path = svn_fs_fs__path_rev_absolute(fs, rev, pool);
+ apr_file_t *apr_file;
+
+ /* open the revision file in buffered r/o mode */
+ err = svn_io_file_open(&apr_file, path,
+ APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
+ if (!err)
+ {
+ file->file = apr_file;
+ file->stream = svn_stream_from_aprfile2(apr_file, TRUE, pool);
+
+ return SVN_NO_ERROR;
+ }
+
+ if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
+ {
+ /* Could not open the file. This may happen if the
+ * file once existed but got packed later. */
+ svn_error_clear(err);
+
+ /* if that was our 2nd attempt, leave it at that. */
+ if (retry)
+ return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+ _("No such revision %ld"), rev);
+
+ /* We failed for the first time. Refresh cache & retry. */
+ SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool));
+
+ retry = TRUE;
+ }
+ else
+ {
+ svn_error_clear(err);
+ return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+ _("No such revision %ld"), rev);
+ }
+ }
+ else
+ {
+ retry = FALSE;
+ }
+ }
+ while (retry);
+
+ return svn_error_trace(err);
+}
+
+svn_error_t *
+svn_fs_fs__open_pack_or_rev_file(svn_fs_fs__revision_file_t **file,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *pool)
+{
+ *file = apr_palloc(pool, sizeof(**file));
+ svn_fs_fs__init_revision_file(*file, fs, rev, pool);
+
+ return svn_error_trace(open_pack_or_rev_file(*file, fs, rev, pool));
+}
+
+svn_error_t *
+svn_fs_fs__reopen_revision_file(svn_fs_fs__revision_file_t *file,
+ svn_fs_t *fs,
+ svn_revnum_t rev)
+{
+ if (file->file)
+ svn_fs_fs__close_revision_file(file);
+
+ return svn_error_trace(open_pack_or_rev_file(file, fs, rev, file->pool));
+}
+
+svn_error_t *
+svn_fs_fs__open_proto_rev_file(svn_fs_fs__revision_file_t **file,
+ svn_fs_t *fs,
+ const svn_fs_fs__id_part_t *txn_id,
+ apr_pool_t *pool)
+{
+ apr_file_t *apr_file;
+ SVN_ERR(svn_io_file_open(&apr_file,
+ svn_fs_fs__path_txn_proto_rev(fs, txn_id, pool),
+ APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));
+
+ *file = apr_pcalloc(pool, sizeof(**file));
+ (*file)->file = apr_file;
+ (*file)->is_packed = FALSE;
+ (*file)->start_revision = SVN_INVALID_REVNUM;
+ (*file)->stream = svn_stream_from_aprfile2(apr_file, TRUE, pool);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__close_revision_file(svn_fs_fs__revision_file_t *file)
+{
+ if (file->stream)
+ SVN_ERR(svn_stream_close(file->stream));
+ if (file->file)
+ SVN_ERR(svn_io_file_close(file->file, file->pool));
+
+ SVN_ERR(svn_fs_fs__packed_stream_close(file->l2p_stream));
+ SVN_ERR(svn_fs_fs__packed_stream_close(file->p2l_stream));
+
+ file->file = NULL;
+ file->stream = NULL;
+ file->l2p_stream = NULL;
+ file->p2l_stream = NULL;
+
+ return SVN_NO_ERROR;
+}
Added: subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.h?rev=1531982&view=auto
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.h (added)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/rev_file.h Mon Oct 14 17:11:01 2013
@@ -0,0 +1,110 @@
+/* rev_file.h --- revision file and index access data structure
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#ifndef SVN_LIBSVN_FS__REV_FILE_H
+#define SVN_LIBSVN_FS__REV_FILE_H
+
+#include "svn_fs.h"
+#include "id.h"
+
+/* In format 7, index files must be read in sync with the respective
+ * revision / pack file. I.e. we must use packed index files for packed
+ * rev files and unpacked ones for non-packed rev files. So, the whole
+ * point is to open them with matching "is packed" setting in case some
+ * background pack process was run.
+ */
+
+/* Opaque index stream type.
+ */
+typedef struct svn_fs_fs__packed_number_stream_t
+ svn_fs_fs__packed_number_stream_t;
+
+/* All files and associated properties for START_REVISION.
+ */
+typedef struct svn_fs_fs__revision_file_t
+{
+ /* first (potentially only) revision in the rev / pack file.
+ * SVN_INVALID_REVNUM for txn proto-rev files. */
+ svn_revnum_t start_revision;
+
+ /* the revision was packed when the first file / stream got opened */
+ svn_boolean_t is_packed;
+
+ /* rev / pack file or NULL if not opened, yet */
+ 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 or NULL. Always NULL for txns. */
+ svn_fs_fs__packed_number_stream_t *p2l_stream;
+
+ /* the opened L2P index or NULL. Always NULL for txns. */
+ svn_fs_fs__packed_number_stream_t *l2p_stream;
+
+ /* pool containing this object */
+ apr_pool_t *pool;
+} svn_fs_fs__revision_file_t;
+
+/* Initialize the FILE data structure for REVISION in FS without actually
+ * opening any files. Use POOL for all future allocations in FILE.
+ */
+void
+svn_fs_fs__init_revision_file(svn_fs_fs__revision_file_t *file,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_pool_t *pool);
+
+/* Open the correct revision file for REV. If the filesystem FS has
+ * been packed, *FILE will be set to the packed file; otherwise, set *FILE
+ * to the revision file for REV. Return SVN_ERR_FS_NO_SUCH_REVISION if the
+ * file doesn't exist. Use POOL for allocations. */
+svn_error_t *
+svn_fs_fs__open_pack_or_rev_file(svn_fs_fs__revision_file_t **file,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *pool);
+
+/* Close previous files as well as streams in FILE (if open) and open the
+ * rev / pack file for REVISION in FS. This is useful when a pack operation
+ * made the current files outdated or no longer available and the caller
+ * wants to keep the same revision file data structure.
+ */
+svn_error_t *
+svn_fs_fs__reopen_revision_file(svn_fs_fs__revision_file_t *file,
+ svn_fs_t *fs,
+ svn_revnum_t revision);
+
+/* Open the proto-rev file of transaction TXN_ID in FS and return it in *FILE.
+ * Use POOL for allocations. */
+svn_error_t *
+svn_fs_fs__open_proto_rev_file(svn_fs_fs__revision_file_t **file,
+ svn_fs_t *fs,
+ const svn_fs_fs__id_part_t *txn_id,
+ apr_pool_t *pool);
+
+/* Close all files and streams in FILE.
+ */
+svn_error_t *
+svn_fs_fs__close_revision_file(svn_fs_fs__revision_file_t *file);
+
+#endif
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c?rev=1531982&r1=1531981&r2=1531982&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c Mon Oct 14 17:11:01 2013
@@ -613,58 +613,6 @@ svn_fs_fs__move_into_place(const char *o
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_fs_fs__open_pack_or_rev_file(apr_file_t **file,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *pool)
-{
- fs_fs_data_t *ffd = fs->fsap_data;
- svn_error_t *err;
- svn_boolean_t retry = FALSE;
-
- do
- {
- const char *path = svn_fs_fs__path_rev_absolute(fs, rev, pool);
-
- /* open the revision file in buffered r/o mode */
- err = svn_io_file_open(file, path,
- APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
- if (err && APR_STATUS_IS_ENOENT(err->apr_err))
- {
- if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
- {
- /* Could not open the file. This may happen if the
- * file once existed but got packed later. */
- svn_error_clear(err);
-
- /* if that was our 2nd attempt, leave it at that. */
- if (retry)
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), rev);
-
- /* We failed for the first time. Refresh cache & retry. */
- SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool));
-
- retry = TRUE;
- }
- else
- {
- svn_error_clear(err);
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), rev);
- }
- }
- else
- {
- retry = FALSE;
- }
- }
- while (retry);
-
- return svn_error_trace(err);
-}
-
svn_boolean_t
svn_fs_fs__use_log_addressing(svn_fs_t *fs,
svn_revnum_t rev)
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h?rev=1531982&r1=1531981&r2=1531982&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h Mon Oct 14 17:11:01 2013
@@ -378,23 +378,6 @@ svn_fs_fs__move_into_place(const char *o
const char *perms_reference,
apr_pool_t *pool);
-/* Open the correct revision file for REV. If the filesystem FS has
- been packed, *FILE will be set to the packed file; otherwise, set *FILE
- to the revision file for REV. Return SVN_ERR_FS_NO_SUCH_REVISION if the
- file doesn't exist.
-
- TODO: Consider returning an indication of whether this is a packed rev
- file, so the caller need not rely on is_packed_rev() which in turn
- relies on the cached FFD->min_unpacked_rev value not having changed
- since the rev file was opened.
-
- Use POOL for allocations. */
-svn_error_t *
-svn_fs_fs__open_pack_or_rev_file(apr_file_t **file,
- svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *pool);
-
/* Return TRUE, iff revision REV in FS requires logical addressing. */
svn_boolean_t
svn_fs_fs__use_log_addressing(svn_fs_t *fs,
Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c?rev=1531982&r1=1531981&r2=1531982&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c Mon Oct 14 17:11:01 2013
@@ -483,13 +483,13 @@ compare_p2l_to_rev(svn_fs_t *fs,
apr_pool_t *iterpool = svn_pool_create(pool);
apr_off_t max_offset;
apr_off_t offset = 0;
- apr_file_t *file;
+ svn_fs_fs__revision_file_t *rev_file;
/* open the pack / rev file that is covered by the p2l index */
- SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&file, fs, start, pool));
+ SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, start, pool));
/* check file size vs. range covered by index */
- SVN_ERR(svn_io_file_seek(file, APR_END, &offset, pool));
+ SVN_ERR(svn_io_file_seek(rev_file->file, APR_END, &offset, pool));
SVN_ERR(svn_fs_fs__p2l_get_max_offset(&max_offset, fs, start, pool));
if (offset != max_offset)
@@ -499,7 +499,8 @@ compare_p2l_to_rev(svn_fs_t *fs,
apr_off_t_toa(pool, offset), start,
apr_off_t_toa(pool, max_offset));
- SVN_ERR(svn_io_file_aligned_seek(file, ffd->block_size, NULL, 0, pool));
+ SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size, NULL, 0,
+ pool));
/* for all offsets in the file, get the P2L index entries and check
them against the L2P index */
@@ -542,14 +543,16 @@ compare_p2l_to_rev(svn_fs_t *fs,
{
/* skip filler entry at the end of the p2l index */
if (entry->offset != max_offset)
- SVN_ERR(read_all_nul(file, entry->size, pool));
+ SVN_ERR(read_all_nul(rev_file->file, entry->size, pool));
}
else if (entry->fnv1_checksum)
{
if (entry->size < STREAM_THRESHOLD)
- SVN_ERR(expected_buffered_checksum(file, entry, pool));
+ SVN_ERR(expected_buffered_checksum(rev_file->file, entry,
+ pool));
else
- SVN_ERR(expected_streamed_checksum(file, entry, pool));
+ SVN_ERR(expected_streamed_checksum(rev_file->file, entry,
+ pool));
}
/* advance offset */