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/01/13 19:58:09 UTC
svn commit: r1432701 - in
/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs: index.c index.h
Author: stefan2
Date: Sun Jan 13 18:58:09 2013
New Revision: 1432701
URL: http://svn.apache.org/viewvc?rev=1432701&view=rev
Log:
On the fsfs-format7 branch: Change the way the proto-l2p-index is being
created. Instead of implicitly assigning logical item indexes, specify
then explicitly.
Also, provide a function to convert an item_index into a file offset.
It is suitable for direct as well as logical addressing.
* subversion/libsvn_fs_fs/index.h
(svn_fs_fs__l2p_proto_index_add_offset): renamed to ...
(svn_fs_fs__l2p_proto_index_add_entry): ... this; add item_index parameter
(svn_fs_fs__item_offset): declare new internal API function
* subversion/libsvn_fs_fs/index.c
(l2_proto_index_entry_t): new internal data structure
(write_number_to_proto_index): renamed to ...
(write_entry_to_proto_index): ... this; write pairs instead of ints
(svn_fs_fs__l2p_proto_index_add_revision,
svn_fs_fs__l2p_proto_index_add_entry,
svn_fs_fs__l2p_index_create): update
(svn_fs_fs__l2p_index_lookup): offsets are now stored as offset+1
(svn_fs_fs__p2l_index_lookup): implement new internal API function
Modified:
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c
subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c?rev=1432701&r1=1432700&r2=1432701&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.c Sun Jan 13 18:58:09 2013
@@ -25,13 +25,15 @@
#include "index.h"
#include "util.h"
+#include "pack.h"
#include "private/svn_subr_private.h"
#include "private/svn_temp_serializer.h"
#include "svn_private_config.h"
#include "temp_serializer.h"
-#include <apr_poll.h>
+
+#include "../libsvn_fs/fs-loader.h"
#define ENCODED_INT_LENGTH 10
@@ -56,6 +58,12 @@ typedef struct l2p_index_page_t
apr_off_t *offsets;
} l2p_index_page_t;
+typedef struct l2_proto_index_entry_t
+{
+ apr_uint64_t offset;
+ apr_uint64_t item_index;
+} l2_proto_index_entry_t;
+
typedef struct p2l_index_header_t
{
svn_revnum_t first_revision;
@@ -77,14 +85,14 @@ svn_fs_fs__l2p_proto_index_open(apr_file
}
static svn_error_t *
-write_number_to_proto_index(apr_file_t *proto_index,
- apr_uint64_t value,
- apr_pool_t *pool)
+write_entry_to_proto_index(apr_file_t *proto_index,
+ l2_proto_index_entry_t entry,
+ apr_pool_t *pool)
{
- apr_size_t written = sizeof(value);
+ apr_size_t written = sizeof(entry);
- SVN_ERR(svn_io_file_write(proto_index, &value, &written, pool));
- SVN_ERR_ASSERT(written == sizeof(value));
+ SVN_ERR(svn_io_file_write(proto_index, &entry, &written, pool));
+ SVN_ERR_ASSERT(written == sizeof(entry));
return SVN_NO_ERROR;
}
@@ -93,16 +101,33 @@ svn_error_t *
svn_fs_fs__l2p_proto_index_add_revision(apr_file_t *proto_index,
apr_pool_t *pool)
{
- return write_number_to_proto_index(proto_index, (apr_uint64_t)(-1), pool);
+ l2_proto_index_entry_t entry;
+ entry.offset = 0;
+ entry.item_index = 0;
+
+ return svn_error_trace(write_entry_to_proto_index(proto_index, entry,
+ pool));
}
svn_error_t *
-svn_fs_fs__l2p_proto_index_add_offset(apr_file_t *proto_index,
- apr_off_t offset,
- apr_pool_t *pool)
+svn_fs_fs__l2p_proto_index_add_entry(apr_file_t *proto_index,
+ apr_off_t offset,
+ apr_uint64_t item_index,
+ apr_pool_t *pool)
{
+ l2_proto_index_entry_t entry;
+
+ /* make sure the conversion to uint64 works */
SVN_ERR_ASSERT(offset >= 0);
- return write_number_to_proto_index(proto_index, (apr_uint64_t)offset, pool);
+ entry.offset = (apr_uint64_t)offset;
+
+ /* make sure we can use item_index as an array index when building the
+ * final index file */
+ SVN_ERR_ASSERT(item_index < UINT_MAX / 2);
+ entry.item_index = item_index;
+
+ return svn_error_trace(write_entry_to_proto_index(proto_index, entry,
+ pool));
}
static apr_size_t
@@ -133,12 +158,8 @@ svn_fs_fs__l2p_index_create(apr_file_t *
apr_file_t *index_file;
unsigned char encoded[ENCODED_INT_LENGTH];
- apr_uint64_t page_start = 0; /* first source entry number of the
- current page */
int last_page_count = 0; /* total page count at the start of
the current revision */
- apr_size_t last_buffer_size = 0; /* byte offset in the spill buffer at
- the begin of the current revision */
/* temporary data structures that collect the data which will be moved
to the target file in a second step */
@@ -150,6 +171,10 @@ svn_fs_fs__l2p_index_create(apr_file_t *
apr_array_header_t *entry_counts
= apr_array_make(local_pool, 16, sizeof(apr_uint64_t));
+ /* collects the item offsets for the current revision */
+ apr_array_header_t *offsets
+ = apr_array_make(local_pool, 256, sizeof(apr_uint64_t));
+
/* 64k blocks, spill after 16MB */
svn_spillbuf_t *buffer
= svn_spillbuf__create(0x10000, 0x1000000, local_pool);
@@ -161,52 +186,55 @@ svn_fs_fs__l2p_index_create(apr_file_t *
/* process all entries until we fail due to EOF */
for (entry = 0; !eof; ++entry)
{
- apr_uint64_t value = 0;
+ l2_proto_index_entry_t proto_entry;
apr_size_t read = 0;
- svn_boolean_t revision_boundary;
- svn_boolean_t page_full;
/* (attempt to) read the next entry from the source */
- SVN_ERR(svn_io_file_read_full2(proto_index, &value, sizeof(value),
+ SVN_ERR(svn_io_file_read_full2(proto_index,
+ &proto_entry, sizeof(proto_entry),
&read, &eof, local_pool));
- SVN_ERR_ASSERT(read == sizeof(value));
+ SVN_ERR_ASSERT(read == sizeof(proto_entry));
- /* end the page after 8k entries */
- page_full = (entry - page_start) > 0x2000;
- revision_boundary = value == -1 || eof;
-
- /* end the page after 4k entries or after */
- if (revision_boundary || page_full)
+ /* handle new revision */
+ if ((entry > 0 && proto_entry.offset == -1) || eof)
{
- /* store prev. page's dimensions, iff that exists */
- if (entry > 0)
+ /* dump entries, grouped into pages */
+
+ int k = 0;
+ for (i = 0; i < offsets->nelts; i = k)
{
- APR_ARRAY_PUSH(entry_counts, apr_uint64_t)
- = entry - page_start;
+ /* 1 page with up to 8k entries */
+ int entry_count = offsets->nelts - i < 0x2000
+ ? offsets->nelts
+ : 0x2000;
+ apr_size_t last_buffer_size = svn_spillbuf__get_size(buffer);
+
+ for (k = i; k < i + entry_count; ++k)
+ {
+ apr_uint64_t value = APR_ARRAY_IDX(offsets, k, apr_uint64_t);
+ SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
+ encode_uint(encoded, value),
+ local_pool));
+ }
+
+ APR_ARRAY_PUSH(entry_counts, apr_uint64_t) = entry_count;
APR_ARRAY_PUSH(page_sizes, apr_uint64_t)
= svn_spillbuf__get_size(buffer) - last_buffer_size;
}
- last_buffer_size = svn_spillbuf__get_size(buffer);
- page_start = entry;
- }
-
- /* handle new revision */
- if (revision_boundary)
- {
- /* store number of pages in previous rev, iff that exists */
- if (entry > 0)
- APR_ARRAY_PUSH(page_counts, apr_uint64_t)
- = page_sizes->nelts - last_page_count;
+ /* store the number of pages in this revision */
+ APR_ARRAY_PUSH(page_counts, apr_uint64_t)
+ = page_sizes->nelts - last_page_count;
last_page_count = page_sizes->nelts;
- page_start = entry + 1;
}
else
{
- SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded,
- encode_uint(encoded, value),
- local_pool));
+ int idx = (apr_size_t)proto_entry.item_index;
+ while (idx <= offsets->nelts)
+ APR_ARRAY_PUSH(offsets, apr_uint64_t) = 0;
+
+ APR_ARRAY_IDX(offsets, idx, apr_uint64_t) = proto_entry.offset + 1;
}
}
@@ -411,7 +439,7 @@ svn_fs_fs__l2p_index_lookup(apr_off_t *o
" too large in revision %ld"),
item_index, revision);
- *offset = page->offsets[item_index];
+ *offset = page->offsets[item_index] - 1;
return SVN_NO_ERROR;
}
@@ -711,3 +739,30 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_fs_fs__item_offset(apr_off_t *offset,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_uint64_t item_index,
+ apr_pool_t *pool)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+ if (ffd->format < SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+ {
+ *offset = (apr_off_t)item_index - 1;
+ if (is_packed_rev(fs, revision))
+ {
+ apr_off_t rev_offset;
+
+ SVN_ERR(svn_fs_fs__get_packed_offset(&rev_offset, fs, revision,
+ pool));
+ *offset += rev_offset;
+ }
+
+ return SVN_NO_ERROR;
+ }
+
+ return svn_error_trace(svn_fs_fs__l2p_index_lookup(offset, fs, revision,
+ item_index, pool));
+}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h?rev=1432701&r1=1432700&r2=1432701&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/index.h Sun Jan 13 18:58:09 2013
@@ -35,9 +35,10 @@ svn_fs_fs__l2p_proto_index_add_revision(
apr_pool_t *pool);
svn_error_t *
-svn_fs_fs__l2p_proto_index_add_offset(apr_file_t *proto_index,
- apr_off_t offset,
- apr_pool_t *pool);
+svn_fs_fs__l2p_proto_index_add_entry(apr_file_t *proto_index,
+ apr_off_t offset,
+ apr_uint64_t item_index,
+ apr_pool_t *pool);
svn_error_t *
svn_fs_fs__l2p_index_create(apr_file_t *proto_index,
@@ -84,4 +85,11 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
apr_off_t offset,
apr_pool_t *pool);
+svn_error_t *
+svn_fs_fs__item_offset(apr_off_t *offset,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_uint64_t item_index,
+ apr_pool_t *pool);
+
#endif