You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2012/03/06 18:50:31 UTC
svn commit: r1297604 [4/12] - in
/subversion/branches/reintegrate-keep-alive: ./ build/ build/ac-macros/
build/generator/ build/generator/templates/ build/win32/ notes/
notes/api-errata/1.7/ subversion/bindings/javahl/native/
subversion/bindings/javahl...
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/compat.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/compat.c Tue Mar 6 17:50:23 2012
@@ -85,8 +85,8 @@ svn_compat_wrap_file_rev_handler(svn_fil
/* The following code maps the calls to a traditional delta editor to an
* Editorv2 editor. It does this by keeping track of a lot of state, and
* then communicating that state to Ev2 upon closure of the file or dir (or
- * edit). Note that Ev2 calls add_symlink() and set_target() are not present
- * in the delta editor paradigm, so we never call them.
+ * edit). Note that Ev2 calls add_symlink() and alter_symlink() are not
+ * present in the delta editor paradigm, so we never call them.
*
* The general idea here is that we have to see *all* the actions on a node's
* parent before we can process that node, which means we need to buffer a
@@ -118,7 +118,7 @@ typedef svn_error_t *(*unlock_func_t)(
const char *path,
apr_pool_t *scratch_pool);
-/* svn_editor__See insert_shims() for more information. */
+/* See svn_editor__insert_shims() for more information. */
struct extra_baton
{
start_edit_func_t start_edit;
@@ -129,9 +129,14 @@ struct extra_baton
struct ev2_edit_baton
{
svn_editor_t *editor;
+
apr_hash_t *paths;
+ apr_array_header_t *path_order;
+ int paths_processed;
+
apr_pool_t *edit_pool;
struct extra_baton *exb;
+ svn_boolean_t closed;
svn_boolean_t *found_abs_paths; /* Did we strip an incoming '/' from the
paths? */
@@ -189,6 +194,7 @@ struct prop_args
const char *name;
svn_revnum_t base_revision;
const svn_string_t *value;
+ svn_kind_t kind;
};
struct copy_args
@@ -201,7 +207,6 @@ struct path_checksum_args
{
const char *path;
svn_revnum_t base_revision;
- svn_checksum_t *checksum;
};
static svn_error_t *
@@ -220,10 +225,12 @@ add_action(struct ev2_edit_baton *eb,
if (action_list == NULL)
{
+ const char *path_dup = apr_pstrdup(eb->edit_pool, path);
+
action_list = apr_array_make(eb->edit_pool, 1,
sizeof(struct path_action *));
- apr_hash_set(eb->paths, apr_pstrdup(eb->edit_pool, path),
- APR_HASH_KEY_STRING, action_list);
+ apr_hash_set(eb->paths, path_dup, APR_HASH_KEY_STRING, action_list);
+ APR_ARRAY_PUSH(eb->path_order, const char *) = path_dup;
}
APR_ARRAY_PUSH(action_list, struct path_action *) = p_action;
@@ -231,6 +238,42 @@ add_action(struct ev2_edit_baton *eb,
return SVN_NO_ERROR;
}
+/* Find all the paths which are immediate children of PATH and return their
+ basenames in a list. */
+static apr_array_header_t *
+get_children(struct ev2_edit_baton *eb,
+ const char *path,
+ apr_pool_t *pool)
+{
+ apr_array_header_t *children = apr_array_make(pool, 1, sizeof(const char *));
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(pool, eb->paths); hi; hi = apr_hash_next(hi))
+ {
+ const char *p = svn__apr_hash_index_key(hi);
+ const char *child;
+
+ /* Sanitize our paths. */
+ if (*p == '/')
+ p++;
+
+ /* Find potential children. */
+ child = svn_relpath_skip_ancestor(path, p);
+ if (!child || !*child)
+ continue;
+
+ /* If we have a path separator, it's a deep child, so just ignore it.
+ ### Is there an API we should be using for this? */
+ if (strchr(child, '/') != NULL)
+ continue;
+
+ APR_ARRAY_PUSH(children, const char *) = child;
+ }
+
+ return children;
+}
+
+
static svn_error_t *
process_actions(void *edit_baton,
const char *path,
@@ -244,13 +287,13 @@ process_actions(void *edit_baton,
svn_boolean_t need_copy = FALSE;
const char *copyfrom_path;
svn_revnum_t copyfrom_rev;
- apr_array_header_t *children;
+ apr_array_header_t *children = NULL;
svn_stream_t *contents = NULL;
svn_checksum_t *checksum = NULL;
svn_revnum_t delete_revnum = SVN_INVALID_REVNUM;
svn_revnum_t props_base_revision = SVN_INVALID_REVNUM;
svn_revnum_t text_base_revision = SVN_INVALID_REVNUM;
- svn_kind_t kind;
+ svn_kind_t kind = svn_kind_unknown;
int i;
if (*path == '/')
@@ -272,6 +315,8 @@ process_actions(void *edit_baton,
{
const struct prop_args *p_args = action->args;
+ kind = p_args->kind;
+
if (!SVN_IS_VALID_REVNUM(props_base_revision))
props_base_revision = p_args->base_revision;
else
@@ -283,6 +328,12 @@ process_actions(void *edit_baton,
the modifications to it. */
if (need_delete && need_add)
props = apr_hash_make(scratch_pool);
+ else if (need_copy)
+ SVN_ERR(eb->fetch_props_func(&props,
+ eb->fetch_props_baton,
+ copyfrom_path,
+ copyfrom_rev,
+ scratch_pool, scratch_pool));
else
SVN_ERR(eb->fetch_props_func(&props,
eb->fetch_props_baton,
@@ -310,8 +361,7 @@ process_actions(void *edit_baton,
if (kind == svn_kind_dir)
{
- children = apr_array_make(scratch_pool, 1,
- sizeof(const char *));
+ children = get_children(eb, path, scratch_pool);
}
else
{
@@ -327,9 +377,13 @@ process_actions(void *edit_baton,
{
struct path_checksum_args *pca = action->args;
+ /* We can only set text on files. */
+ kind = svn_kind_file;
+
+ SVN_ERR(svn_io_file_checksum2(&checksum, pca->path,
+ svn_checksum_sha1, scratch_pool));
SVN_ERR(svn_stream_open_readonly(&contents, pca->path,
scratch_pool, scratch_pool));
- checksum = pca->checksum;
if (!SVN_IS_VALID_REVNUM(text_base_revision))
text_base_revision = pca->base_revision;
@@ -375,10 +429,14 @@ process_actions(void *edit_baton,
{
/* If we're only doing a delete, do it here. */
SVN_ERR(svn_editor_delete(eb->editor, path, delete_revnum));
+ return SVN_NO_ERROR;
}
if (need_add)
{
+ if (props == NULL)
+ props = apr_hash_make(scratch_pool);
+
if (kind == svn_kind_dir)
{
SVN_ERR(svn_editor_add_directory(eb->editor, path, children,
@@ -399,19 +457,29 @@ process_actions(void *edit_baton,
delete_revnum));
}
- if (props)
+ if (props || contents)
{
- /* We fetched and modified the props in some way. Apply 'em now that
- we have the new set. */
- SVN_ERR(svn_editor_set_props(eb->editor, path, props_base_revision,
- props, contents == NULL));
- }
+ /* We fetched and modified the props or content in some way. Apply 'em
+ now. */
+ svn_revnum_t base_revision;
+
+ if (SVN_IS_VALID_REVNUM(props_base_revision)
+ && SVN_IS_VALID_REVNUM(text_base_revision))
+ SVN_ERR_ASSERT(props_base_revision == text_base_revision);
+
+ if (SVN_IS_VALID_REVNUM(props_base_revision))
+ base_revision = props_base_revision;
+ else if (SVN_IS_VALID_REVNUM(text_base_revision))
+ base_revision = text_base_revision;
+ else
+ base_revision = SVN_INVALID_REVNUM;
- if (contents)
- {
- /* If we have an content for this node, set it now. */
- SVN_ERR(svn_editor_set_text(eb->editor, path, text_base_revision,
- checksum, contents));
+ if (kind == svn_kind_dir)
+ SVN_ERR(svn_editor_alter_directory(eb->editor, path, base_revision,
+ props));
+ else
+ SVN_ERR(svn_editor_alter_file(eb->editor, path, base_revision, props,
+ checksum, contents));
}
return SVN_NO_ERROR;
@@ -422,29 +490,21 @@ run_ev2_actions(void *edit_baton,
apr_pool_t *scratch_pool)
{
struct ev2_edit_baton *eb = edit_baton;
- apr_array_header_t *sorted_hash;
apr_pool_t *iterpool;
- int i;
-
- /* Sort the paths touched by this edit.
- * Ev2 doesn't really have any particular need for depth-first-ness, but
- * we want to ensure all parent directories are handled before children in
- * the case of adds (which does introduce an element of depth-first-ness). */
- sorted_hash = svn_sort__hash(eb->paths, svn_sort_compare_items_as_paths,
- scratch_pool);
iterpool = svn_pool_create(scratch_pool);
- for (i = 0; i < sorted_hash->nelts; i++)
- {
- svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i, svn_sort__item_t);
- apr_array_header_t *actions = item->value;
- const char *path = item->key;
+
+ /* Possibly pick up where we left off. Ocassionally, we do some of these
+ as part of close_edit() and then some more as part of abort_edit() */
+ for (; eb->paths_processed < eb->path_order->nelts; ++eb->paths_processed)
+ {
+ const char *path = APR_ARRAY_IDX(eb->path_order, eb->paths_processed,
+ const char *);
+ apr_array_header_t *actions = apr_hash_get(eb->paths, path,
+ APR_HASH_KEY_STRING);
svn_pool_clear(iterpool);
SVN_ERR(process_actions(edit_baton, path, actions, iterpool));
-
- /* Remove this item from the hash. */
- apr_hash_set(eb->paths, path, APR_HASH_KEY_STRING, NULL);
}
svn_pool_destroy(iterpool);
@@ -589,6 +649,7 @@ ev2_change_dir_prop(void *dir_baton,
p_args->name = apr_pstrdup(db->eb->edit_pool, name);
p_args->value = value ? svn_string_dup(value, db->eb->edit_pool) : NULL;
p_args->base_revision = db->base_revision;
+ p_args->kind = svn_kind_dir;
SVN_ERR(add_action(db->eb, db->path, ACTION_PROPSET, p_args));
@@ -609,7 +670,7 @@ ev2_absent_directory(const char *path,
{
struct ev2_dir_baton *pb = parent_baton;
svn_kind_t *kind = apr_palloc(pb->eb->edit_pool, sizeof(*kind));
-
+
*kind = svn_kind_dir;
SVN_ERR(add_action(pb->eb, path, ACTION_ADD_ABSENT, kind));
@@ -705,6 +766,8 @@ struct handler_baton
svn_txdelta_window_handler_t apply_handler;
void *apply_baton;
+ svn_stream_t *source;
+
apr_pool_t *pool;
};
@@ -718,6 +781,8 @@ window_handler(svn_txdelta_window_t *win
if (window != NULL && !err)
return SVN_NO_ERROR;
+ SVN_ERR(svn_stream_close(hb->source));
+
svn_pool_destroy(hb->pool);
return svn_error_trace(err);
@@ -734,7 +799,6 @@ ev2_apply_textdelta(void *file_baton,
struct ev2_file_baton *fb = file_baton;
apr_pool_t *handler_pool = svn_pool_create(fb->eb->edit_pool);
struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb));
- svn_stream_t *source;
svn_stream_t *target;
struct path_checksum_args *pca = apr_pcalloc(fb->eb->edit_pool,
sizeof(*pca));
@@ -742,27 +806,22 @@ ev2_apply_textdelta(void *file_baton,
pca->base_revision = fb->base_revision;
if (! fb->delta_base)
- source = svn_stream_empty(handler_pool);
+ hb->source = svn_stream_empty(handler_pool);
else
- SVN_ERR(svn_stream_open_readonly(&source, fb->delta_base, handler_pool,
+ SVN_ERR(svn_stream_open_readonly(&hb->source, fb->delta_base, handler_pool,
result_pool));
SVN_ERR(svn_stream_open_unique(&target, &pca->path, NULL,
svn_io_file_del_on_pool_cleanup,
fb->eb->edit_pool, result_pool));
- /* Wrap our target with a checksum'ing stream. */
- target = svn_stream_checksummed2(target, NULL, &pca->checksum,
- svn_checksum_sha1, TRUE,
- fb->eb->edit_pool);
-
- svn_txdelta_apply(source, target,
+ svn_txdelta_apply(hb->source, target,
NULL, NULL,
handler_pool,
&hb->apply_handler, &hb->apply_baton);
hb->pool = handler_pool;
-
+
*handler_baton = hb;
*handler = window_handler;
@@ -792,6 +851,7 @@ ev2_change_file_prop(void *file_baton,
p_args->name = apr_pstrdup(fb->eb->edit_pool, name);
p_args->value = value ? svn_string_dup(value, fb->eb->edit_pool) : NULL;
p_args->base_revision = fb->base_revision;
+ p_args->kind = svn_kind_file;
SVN_ERR(add_action(fb->eb, fb->path, ACTION_PROPSET, p_args));
@@ -813,7 +873,7 @@ ev2_absent_file(const char *path,
{
struct ev2_dir_baton *pb = parent_baton;
svn_kind_t *kind = apr_palloc(pb->eb->edit_pool, sizeof(*kind));
-
+
*kind = svn_kind_file;
SVN_ERR(add_action(pb->eb, path, ACTION_ADD_ABSENT, kind));
@@ -827,6 +887,7 @@ ev2_close_edit(void *edit_baton,
struct ev2_edit_baton *eb = edit_baton;
SVN_ERR(run_ev2_actions(edit_baton, scratch_pool));
+ eb->closed = TRUE;
return svn_error_trace(svn_editor_complete(eb->editor));
}
@@ -837,7 +898,10 @@ ev2_abort_edit(void *edit_baton,
struct ev2_edit_baton *eb = edit_baton;
SVN_ERR(run_ev2_actions(edit_baton, scratch_pool));
- return svn_error_trace(svn_editor_abort(eb->editor));
+ if (!eb->closed)
+ return svn_error_trace(svn_editor_abort(eb->editor));
+ else
+ return SVN_NO_ERROR;
}
/* Return a svn_delta_editor_t * in DEDITOR, with an accompanying baton in
@@ -859,7 +923,7 @@ ev2_abort_edit(void *edit_baton,
* - EXB: An 'extra baton' which is used to communicate between the shims.
* Its callbacks should be invoked at the appropriate time by this
* shim.
- */
+ */
static svn_error_t *
delta_from_editor(const svn_delta_editor_t **deditor,
void **dedit_baton,
@@ -897,6 +961,7 @@ delta_from_editor(const svn_delta_editor
eb->editor = editor;
eb->paths = apr_hash_make(pool);
+ eb->path_order = apr_array_make(pool, 1, sizeof(const char *));
eb->edit_pool = pool;
eb->found_abs_paths = found_abs_paths;
*eb->found_abs_paths = FALSE;
@@ -1055,19 +1120,15 @@ build(struct editor_baton *eb,
apr_hash_t *current_props;
apr_array_header_t *propdiffs;
- /* Only fetch the kind if operating on something other than the root,
- as we already know the kind on the root. */
- if (operation->path)
- {
- if (kind == svn_kind_unknown)
- SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
- relpath, rev, scratch_pool));
- else
- operation->kind = kind;
- }
+ operation->kind = kind;
if (operation->operation == OP_REPLACE)
current_props = apr_hash_make(scratch_pool);
+ else if (operation->copyfrom_url)
+ SVN_ERR(eb->fetch_props_func(¤t_props, eb->fetch_props_baton,
+ operation->copyfrom_url,
+ operation->copyfrom_revision,
+ scratch_pool, scratch_pool));
else
SVN_ERR(eb->fetch_props_func(¤t_props, eb->fetch_props_baton,
relpath, rev, scratch_pool,
@@ -1081,7 +1142,7 @@ build(struct editor_baton *eb,
actual structures, not pointers to them. */
svn_prop_t *prop = &APR_ARRAY_IDX(propdiffs, i, svn_prop_t);
if (!prop->value)
- APR_ARRAY_PUSH(operation->prop_dels, const char *) =
+ APR_ARRAY_PUSH(operation->prop_dels, const char *) =
apr_pstrdup(eb->edit_pool, prop->name);
else
apr_hash_set(operation->prop_mods,
@@ -1285,68 +1346,89 @@ add_absent_cb(void *baton,
return SVN_NO_ERROR;
}
-/* This implements svn_editor_cb_set_props_t */
+/* This implements svn_editor_cb_alter_directory_t */
static svn_error_t *
-set_props_cb(void *baton,
- const char *relpath,
- svn_revnum_t revision,
- apr_hash_t *props,
- svn_boolean_t complete,
- apr_pool_t *scratch_pool)
+alter_directory_cb(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_hash_t *props,
+ apr_pool_t *scratch_pool)
{
struct editor_baton *eb = baton;
- SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_unknown,
+ /* ### should we verify the kind is truly a directory? */
+
+ SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_dir,
NULL, SVN_INVALID_REVNUM,
props, NULL, NULL, revision, scratch_pool));
return SVN_NO_ERROR;
}
-/* This implements svn_editor_cb_set_text_t */
+/* This implements svn_editor_cb_alter_file_t */
static svn_error_t *
-set_text_cb(void *baton,
- const char *relpath,
- svn_revnum_t revision,
- const svn_checksum_t *checksum,
- svn_stream_t *contents,
- apr_pool_t *scratch_pool)
+alter_file_cb(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_hash_t *props,
+ const svn_checksum_t *checksum,
+ svn_stream_t *contents,
+ apr_pool_t *scratch_pool)
{
struct editor_baton *eb = baton;
const char *tmp_filename;
svn_stream_t *tmp_stream;
svn_checksum_t *md5_checksum;
- /* We may need to re-checksum these contents */
- if (!(checksum && checksum->kind == svn_checksum_md5))
- contents = svn_stream_checksummed2(contents, &md5_checksum, NULL,
- svn_checksum_md5, TRUE, scratch_pool);
- else
- md5_checksum = (svn_checksum_t *)checksum;
+ /* ### should we verify the kind is truly a file? */
- /* Spool the contents to a tempfile, and provide that to the driver. */
- SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_filename, NULL,
- svn_io_file_del_on_pool_cleanup,
- eb->edit_pool, scratch_pool));
- SVN_ERR(svn_stream_copy3(contents, tmp_stream, NULL, NULL, scratch_pool));
+ if (contents)
+ {
+ /* We may need to re-checksum these contents */
+ if (!(checksum && checksum->kind == svn_checksum_md5))
+ contents = svn_stream_checksummed2(contents, &md5_checksum, NULL,
+ svn_checksum_md5, TRUE,
+ scratch_pool);
+ else
+ md5_checksum = (svn_checksum_t *)checksum;
- SVN_ERR(build(eb, ACTION_PUT, relpath, svn_kind_file,
- NULL, SVN_INVALID_REVNUM,
- NULL, tmp_filename, md5_checksum, revision, scratch_pool));
+ /* Spool the contents to a tempfile, and provide that to the driver. */
+ SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_filename, NULL,
+ svn_io_file_del_on_pool_cleanup,
+ eb->edit_pool, scratch_pool));
+ SVN_ERR(svn_stream_copy3(contents, tmp_stream, NULL, NULL,
+ scratch_pool));
+
+ SVN_ERR(build(eb, ACTION_PUT, relpath, svn_kind_file,
+ NULL, SVN_INVALID_REVNUM,
+ NULL, tmp_filename, md5_checksum, revision, scratch_pool));
+ }
+
+ if (props)
+ {
+ SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_file,
+ NULL, SVN_INVALID_REVNUM,
+ props, NULL, NULL, revision, scratch_pool));
+ }
return SVN_NO_ERROR;
}
-/* This implements svn_editor_cb_set_target_t */
+/* This implements svn_editor_cb_alter_symlink_t */
static svn_error_t *
-set_target_cb(void *baton,
- const char *relpath,
- svn_revnum_t revision,
- const char *target,
- apr_pool_t *scratch_pool)
+alter_symlink_cb(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_hash_t *props,
+ const char *target,
+ apr_pool_t *scratch_pool)
{
struct editor_baton *eb = baton;
+ /* ### should we verify the kind is truly a symlink? */
+
+ /* ### do something */
+
return SVN_NO_ERROR;
}
@@ -1489,7 +1571,8 @@ drive_tree(struct operation *op,
{
/* Open or create our baton. */
if (op->operation == OP_OPEN || op->operation == OP_PROPSET)
- SVN_ERR(editor->open_directory(path, parent_op->baton, op->base_revision,
+ SVN_ERR(editor->open_directory(path, parent_op->baton,
+ op->base_revision,
scratch_pool, &op->baton));
else if (op->operation == OP_ADD || op->operation == OP_REPLACE)
@@ -1529,7 +1612,7 @@ drive_tree(struct operation *op,
I don't know that that's a valid assumption... */
void *file_baton = NULL;
-
+
/* Open or create our baton. */
if (op->operation == OP_OPEN || op->operation == OP_PROPSET)
SVN_ERR(editor->open_file(path, parent_op->baton, op->base_revision,
@@ -1604,7 +1687,7 @@ drive_root(struct operation *root,
svn_pool_clear(iterpool);
SVN_ERR(drive_tree(child, root, editor, make_abs_paths, iterpool));
}
-
+
/* We need to close the root directory, but leave it to our caller to call
close_ or abort_edit(). */
SVN_ERR(editor->close_directory(root->baton, scratch_pool));
@@ -1767,9 +1850,9 @@ editor_from_delta(svn_editor_t **editor_
add_file_cb,
add_symlink_cb,
add_absent_cb,
- set_props_cb,
- set_text_cb,
- set_target_cb,
+ alter_directory_cb,
+ alter_file_cb,
+ alter_symlink_cb,
delete_cb,
copy_cb,
move_cb,
@@ -1865,6 +1948,10 @@ svn_editor__insert_shims(const svn_delta
unlock_func_t unlock_func;
void *unlock_baton;
+ SVN_ERR_ASSERT(shim_callbacks->fetch_kind_func != NULL);
+ SVN_ERR_ASSERT(shim_callbacks->fetch_props_func != NULL);
+ SVN_ERR_ASSERT(shim_callbacks->fetch_base_func != NULL);
+
SVN_ERR(editor_from_delta(&editor, &exb, &unlock_func, &unlock_baton,
deditor_in, dedit_baton_in,
found_abs_paths, NULL, NULL,
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/editor.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/editor.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/editor.c Tue Mar 6 17:50:23 2012
@@ -33,7 +33,7 @@
/* This enables runtime checks of the editor API constraints. This may
introduce additional memory and runtime overhead, and should not be used
in production builds.
-
+
### Remove before release? */
#define ENABLE_ORDERING_CHECK
#endif
@@ -57,13 +57,129 @@ struct svn_editor_t
#ifdef ENABLE_ORDERING_CHECK
apr_hash_t *pending_incomplete_children;
apr_hash_t *completed_nodes;
- apr_hash_t *needs_text_or_target;
svn_boolean_t finished;
apr_pool_t *result_pool;
#endif
};
+#ifdef ENABLE_ORDERING_CHECK
+
+/* Marker to indicate no further changes are allowed on this node. */
+static const int marker_done;
+#define MARKER_DONE (&marker_done)
+
+/* Marker indicating that add_* may be called for this path, or that it
+ can be the destination of a copy or move. For copy/move, the path
+ will switch to MARKER_ALLOW_ALTER, to enable further tweaks. */
+static const int marker_allow_add;
+#define MARKER_ALLOW_ADD (&marker_allow_add)
+
+/* Marker indicating that alter_* may be called for this path. */
+static const int marker_allow_alter;
+#define MARKER_ALLOW_ALTER (&marker_allow_alter)
+
+/* Just like MARKER_DONE, but also indicates that the node was created
+ via add_directory(). This allows us to verify that the CHILDREN param
+ was comprehensive. */
+static const int marker_added_dir;
+#define MARKER_ADDED_DIR (&marker_added_dir)
+
+#define MARK_FINISHED(editor) ((editor)->finished = TRUE)
+#define SHOULD_NOT_BE_FINISHED(editor) SVN_ERR_ASSERT(!(editor)->finished)
+
+#define CLEAR_INCOMPLETE(editor, relpath) \
+ apr_hash_set((editor)->pending_incomplete_children, relpath, \
+ APR_HASH_KEY_STRING, NULL);
+
+#define MARK_RELPATH(editor, relpath, value) \
+ apr_hash_set((editor)->completed_nodes, \
+ apr_pstrdup((editor)->result_pool, relpath), \
+ APR_HASH_KEY_STRING, value)
+
+#define MARK_COMPLETED(editor, relpath) \
+ MARK_RELPATH(editor, relpath, MARKER_DONE)
+#define SHOULD_NOT_BE_COMPLETED(editor, relpath) \
+ SVN_ERR_ASSERT(apr_hash_get((editor)->completed_nodes, relpath, \
+ APR_HASH_KEY_STRING) == NULL)
+
+#define MARK_ALLOW_ADD(editor, relpath) \
+ MARK_RELPATH(editor, relpath, MARKER_ALLOW_ADD)
+#define SHOULD_ALLOW_ADD(editor, relpath) \
+ SVN_ERR_ASSERT(allow_either(editor, relpath, MARKER_ALLOW_ADD, NULL))
+
+#define MARK_ALLOW_ALTER(editor, relpath) \
+ MARK_RELPATH(editor, relpath, MARKER_ALLOW_ALTER)
+#define SHOULD_ALLOW_ALTER(editor, relpath) \
+ SVN_ERR_ASSERT(allow_either(editor, relpath, MARKER_ALLOW_ALTER, NULL))
+
+#define MARK_ADDED_DIR(editor, relpath) \
+ MARK_RELPATH(editor, relpath, MARKER_ADDED_DIR)
+#define CHECK_UNKNOWN_CHILD(editor, relpath) \
+ SVN_ERR_ASSERT(check_unknown_child(editor, relpath))
+
+static svn_boolean_t
+allow_either(const svn_editor_t *editor,
+ const char *relpath,
+ const void *marker1,
+ const void *marker2)
+{
+ void *value = apr_hash_get(editor->completed_nodes, relpath,
+ APR_HASH_KEY_STRING);
+ return value == marker1 || value == marker2;
+}
+
+static svn_boolean_t
+check_unknown_child(const svn_editor_t *editor,
+ const char *relpath)
+{
+ const char *parent;
+
+ /* If we already know about the new child, then exit early. */
+ if (apr_hash_get(editor->pending_incomplete_children, relpath,
+ APR_HASH_KEY_STRING) != NULL)
+ return TRUE;
+
+ parent = svn_relpath_dirname(relpath, editor->scratch_pool);
+
+ /* Was this parent created via svn_editor_add_directory() ? */
+ if (apr_hash_get(editor->completed_nodes, parent, APR_HASH_KEY_STRING)
+ == MARKER_ADDED_DIR)
+ {
+ /* Whoops. This child should have been listed in that add call,
+ and placed into ->pending_incomplete_children. */
+ return FALSE;
+ }
+
+ /* The parent was not added in this drive. */
+ return TRUE;
+}
+
+#else
+
+/* Be wary with the definition of these macros so that we don't
+ end up with "statement with no effect" warnings. Obviously, this
+ depends upon particular usage, which is easy to verify. */
+
+#define MARK_FINISHED(editor) /* empty */
+#define SHOULD_NOT_BE_FINISHED(editor) /* empty */
+
+#define CLEAR_INCOMPLETE(editor, relpath) /* empty */
+
+#define MARK_COMPLETED(editor, relpath) /* empty */
+#define SHOULD_NOT_BE_COMPLETED(editor, relpath) /* empty */
+
+#define MARK_ALLOW_ADD(editor, relpath) /* empty */
+#define SHOULD_ALLOW_ADD(editor, relpath) /* empty */
+
+#define MARK_ALLOW_ALTER(editor, relpath) /* empty */
+#define SHOULD_ALLOW_ALTER(editor, relpath) /* empty */
+
+#define MARK_ADDED_DIR(editor, relpath) /* empty */
+#define CHECK_UNKNOWN_CHILD(editor, relpath) /* empty */
+
+#endif /* ENABLE_ORDERING_CHECK */
+
svn_error_t *
svn_editor_create(svn_editor_t **editor,
@@ -79,10 +195,10 @@ svn_editor_create(svn_editor_t **editor,
(*editor)->cancel_func = cancel_func;
(*editor)->cancel_baton = cancel_baton;
(*editor)->scratch_pool = svn_pool_create(result_pool);
+
#ifdef ENABLE_ORDERING_CHECK
(*editor)->pending_incomplete_children = apr_hash_make(result_pool);
(*editor)->completed_nodes = apr_hash_make(result_pool);
- (*editor)->needs_text_or_target = apr_hash_make(result_pool);
(*editor)->finished = FALSE;
(*editor)->result_pool = result_pool;
#endif
@@ -132,31 +248,31 @@ svn_editor_setcb_add_absent(svn_editor_t
svn_error_t *
-svn_editor_setcb_set_props(svn_editor_t *editor,
- svn_editor_cb_set_props_t callback,
- apr_pool_t *scratch_pool)
+svn_editor_setcb_alter_directory(svn_editor_t *editor,
+ svn_editor_cb_alter_directory_t callback,
+ apr_pool_t *scratch_pool)
{
- editor->funcs.cb_set_props = callback;
+ editor->funcs.cb_alter_directory = callback;
return SVN_NO_ERROR;
}
svn_error_t *
-svn_editor_setcb_set_text(svn_editor_t *editor,
- svn_editor_cb_set_text_t callback,
- apr_pool_t *scratch_pool)
+svn_editor_setcb_alter_file(svn_editor_t *editor,
+ svn_editor_cb_alter_file_t callback,
+ apr_pool_t *scratch_pool)
{
- editor->funcs.cb_set_text = callback;
+ editor->funcs.cb_alter_file = callback;
return SVN_NO_ERROR;
}
svn_error_t *
-svn_editor_setcb_set_target(svn_editor_t *editor,
- svn_editor_cb_set_target_t callback,
- apr_pool_t *scratch_pool)
+svn_editor_setcb_alter_symlink(svn_editor_t *editor,
+ svn_editor_cb_alter_symlink_t callback,
+ apr_pool_t *scratch_pool)
{
- editor->funcs.cb_set_target = callback;
+ editor->funcs.cb_alter_symlink = callback;
return SVN_NO_ERROR;
}
@@ -232,9 +348,9 @@ svn_editor_setcb_many(svn_editor_t *edit
COPY_CALLBACK(cb_add_file);
COPY_CALLBACK(cb_add_symlink);
COPY_CALLBACK(cb_add_absent);
- COPY_CALLBACK(cb_set_props);
- COPY_CALLBACK(cb_set_text);
- COPY_CALLBACK(cb_set_target);
+ COPY_CALLBACK(cb_alter_directory);
+ COPY_CALLBACK(cb_alter_file);
+ COPY_CALLBACK(cb_alter_symlink);
COPY_CALLBACK(cb_delete);
COPY_CALLBACK(cb_copy);
COPY_CALLBACK(cb_move);
@@ -257,11 +373,11 @@ svn_editor_add_directory(svn_editor_t *e
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SVN_ERR_ASSERT(children != NULL);
+ SVN_ERR_ASSERT(props != NULL);
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ADD(editor, relpath);
+ CHECK_UNKNOWN_CHILD(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
@@ -270,12 +386,11 @@ svn_editor_add_directory(svn_editor_t *e
err = editor->funcs.cb_add_directory(editor->baton, relpath, children,
props, replaces_rev,
editor->scratch_pool);
+
+ MARK_ADDED_DIR(editor, relpath);
+ CLEAR_INCOMPLETE(editor, relpath);
+
#ifdef ENABLE_ORDERING_CHECK
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
- apr_hash_set(editor->pending_incomplete_children, relpath,
- APR_HASH_KEY_STRING, NULL);
{
int i;
for (i = 0; i < children->nelts; i++)
@@ -285,10 +400,11 @@ svn_editor_add_directory(svn_editor_t *e
editor->result_pool);
apr_hash_set(editor->pending_incomplete_children, child,
- APR_HASH_KEY_STRING, (void *)0xdeadbeef);
+ APR_HASH_KEY_STRING, "");
}
}
#endif
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -304,11 +420,13 @@ svn_editor_add_file(svn_editor_t *editor
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SVN_ERR_ASSERT(checksum != NULL
+ && checksum->kind == SVN_EDITOR_CHECKSUM_KIND);
+ SVN_ERR_ASSERT(contents != NULL);
+ SVN_ERR_ASSERT(props != NULL);
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ADD(editor, relpath);
+ CHECK_UNKNOWN_CHILD(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
@@ -317,13 +435,10 @@ svn_editor_add_file(svn_editor_t *editor
err = editor->funcs.cb_add_file(editor->baton, relpath,
checksum, contents, props,
replaces_rev, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
- apr_hash_set(editor->pending_incomplete_children, relpath,
- APR_HASH_KEY_STRING, NULL);
-#endif
+
+ MARK_COMPLETED(editor, relpath);
+ CLEAR_INCOMPLETE(editor, relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -338,11 +453,10 @@ svn_editor_add_symlink(svn_editor_t *edi
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SVN_ERR_ASSERT(props != NULL);
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ADD(editor, relpath);
+ CHECK_UNKNOWN_CHILD(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
@@ -350,13 +464,10 @@ svn_editor_add_symlink(svn_editor_t *edi
if (editor->funcs.cb_add_symlink)
err = editor->funcs.cb_add_symlink(editor->baton, relpath, target, props,
replaces_rev, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
- apr_hash_set(editor->pending_incomplete_children, relpath,
- APR_HASH_KEY_STRING, NULL);
-#endif
+
+ MARK_COMPLETED(editor, relpath);
+ CLEAR_INCOMPLETE(editor, relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -370,11 +481,9 @@ svn_editor_add_absent(svn_editor_t *edit
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ADD(editor, relpath);
+ CHECK_UNKNOWN_CHILD(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
@@ -382,120 +491,100 @@ svn_editor_add_absent(svn_editor_t *edit
if (editor->funcs.cb_add_absent)
err = editor->funcs.cb_add_absent(editor->baton, relpath, kind,
replaces_rev, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
- apr_hash_set(editor->pending_incomplete_children, relpath,
- APR_HASH_KEY_STRING, NULL);
-#endif
+
+ MARK_COMPLETED(editor, relpath);
+ CLEAR_INCOMPLETE(editor, relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
svn_error_t *
-svn_editor_set_props(svn_editor_t *editor,
- const char *relpath,
- svn_revnum_t revision,
- apr_hash_t *props,
- svn_boolean_t complete)
+svn_editor_alter_directory(svn_editor_t *editor,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_hash_t *props)
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SVN_ERR_ASSERT(props != NULL);
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ALTER(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- if (editor->funcs.cb_set_props)
- err = editor->funcs.cb_set_props(editor->baton, relpath, revision, props,
- complete, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- /* ### Some of the ordering here depends upon the kind of RELPATH, but
- * ### we have no way of determining what that is. */
- if (complete)
- {
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
- }
- else
- {
- apr_hash_set(editor->needs_text_or_target,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0xba5eba11);
- }
-#endif
+ if (editor->funcs.cb_alter_directory)
+ err = editor->funcs.cb_alter_directory(editor->baton,
+ relpath, revision, props,
+ editor->scratch_pool);
+
+ MARK_COMPLETED(editor, relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
svn_error_t *
-svn_editor_set_text(svn_editor_t *editor,
- const char *relpath,
- svn_revnum_t revision,
- const svn_checksum_t *checksum,
- svn_stream_t *contents)
+svn_editor_alter_file(svn_editor_t *editor,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_hash_t *props,
+ const svn_checksum_t *checksum,
+ svn_stream_t *contents)
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SVN_ERR_ASSERT((checksum != NULL && contents != NULL)
+ || (checksum == NULL && contents == NULL));
+ SVN_ERR_ASSERT(props != NULL || checksum != NULL);
+ if (checksum)
+ SVN_ERR_ASSERT(checksum->kind == SVN_EDITOR_CHECKSUM_KIND);
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ALTER(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- if (editor->funcs.cb_set_text)
- err = editor->funcs.cb_set_text(editor->baton, relpath, revision,
- checksum, contents, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- apr_hash_set(editor->needs_text_or_target, relpath, APR_HASH_KEY_STRING,
- NULL);
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
-#endif
+ if (editor->funcs.cb_alter_file)
+ err = editor->funcs.cb_alter_file(editor->baton,
+ relpath, revision, props,
+ checksum, contents,
+ editor->scratch_pool);
+
+ MARK_COMPLETED(editor, relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
svn_error_t *
-svn_editor_set_target(svn_editor_t *editor,
- const char *relpath,
- svn_revnum_t revision,
- const char *target)
+svn_editor_alter_symlink(svn_editor_t *editor,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_hash_t *props,
+ const char *target)
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SVN_ERR_ASSERT(props != NULL || target != NULL);
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ALTER(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
- if (editor->funcs.cb_set_target)
- err = editor->funcs.cb_set_target(editor->baton, relpath, revision,
- target, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- apr_hash_set(editor->needs_text_or_target, relpath, APR_HASH_KEY_STRING,
- NULL);
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
-#endif
+ if (editor->funcs.cb_alter_symlink)
+ err = editor->funcs.cb_alter_symlink(editor->baton,
+ relpath, revision, props,
+ target,
+ editor->scratch_pool);
+
+ MARK_COMPLETED(editor, relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -508,11 +597,8 @@ svn_editor_delete(svn_editor_t *editor,
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_NOT_BE_COMPLETED(editor, relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
@@ -520,11 +606,9 @@ svn_editor_delete(svn_editor_t *editor,
if (editor->funcs.cb_delete)
err = editor->funcs.cb_delete(editor->baton, relpath, revision,
editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
-#endif
+
+ MARK_COMPLETED(editor, relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -539,11 +623,8 @@ svn_editor_copy(svn_editor_t *editor,
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, dst_relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_ALLOW_ADD(editor, dst_relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
@@ -552,6 +633,10 @@ svn_editor_copy(svn_editor_t *editor,
err = editor->funcs.cb_copy(editor->baton, src_relpath, src_revision,
dst_relpath, replaces_rev,
editor->scratch_pool);
+
+ MARK_ALLOW_ALTER(editor, dst_relpath);
+ CLEAR_INCOMPLETE(editor, dst_relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -566,13 +651,9 @@ svn_editor_move(svn_editor_t *editor,
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, src_relpath,
- APR_HASH_KEY_STRING));
- SVN_ERR_ASSERT(!apr_hash_get(editor->completed_nodes, dst_relpath,
- APR_HASH_KEY_STRING));
-#endif
+ SHOULD_NOT_BE_FINISHED(editor);
+ SHOULD_NOT_BE_COMPLETED(editor, src_relpath);
+ SHOULD_ALLOW_ADD(editor, dst_relpath);
if (editor->cancel_func)
SVN_ERR(editor->cancel_func(editor->cancel_baton));
@@ -581,22 +662,11 @@ svn_editor_move(svn_editor_t *editor,
err = editor->funcs.cb_move(editor->baton, src_relpath, src_revision,
dst_relpath, replaces_rev,
editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- /* ### after moving a node away, a new one can be created. how does
- ### affect the "replaces_rev" concept elsewhere? */
-#if 0
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, src_relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
-#endif
- /* ### hmm. post-move, it should be possible to change props/contents. */
-#if 0
- apr_hash_set(editor->completed_nodes,
- apr_pstrdup(editor->result_pool, dst_relpath),
- APR_HASH_KEY_STRING, (void *) 0x5ca1ab1e);
-#endif
-#endif
+ MARK_ALLOW_ADD(editor, src_relpath);
+ MARK_ALLOW_ALTER(editor, dst_relpath);
+ CLEAR_INCOMPLETE(editor, dst_relpath);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -609,9 +679,16 @@ svn_editor_rotate(svn_editor_t *editor,
{
svn_error_t *err = SVN_NO_ERROR;
+ SHOULD_NOT_BE_FINISHED(editor);
#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
- /* ### something more */
+ {
+ int i;
+ for (i = 0; i < relpaths->nelts; i++)
+ {
+ const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
+ SHOULD_NOT_BE_COMPLETED(editor, relpath);
+ }
+ }
#endif
if (editor->cancel_func)
@@ -620,9 +697,18 @@ svn_editor_rotate(svn_editor_t *editor,
if (editor->funcs.cb_rotate)
err = editor->funcs.cb_rotate(editor->baton, relpaths, revisions,
editor->scratch_pool);
+
#ifdef ENABLE_ORDERING_CHECK
- /* ### something more */
+ {
+ int i;
+ for (i = 0; i < relpaths->nelts; i++)
+ {
+ const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
+ MARK_ALLOW_ALTER(editor, relpath);
+ }
+ }
#endif
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -633,18 +719,16 @@ svn_editor_complete(svn_editor_t *editor
{
svn_error_t *err = SVN_NO_ERROR;
+ SHOULD_NOT_BE_FINISHED(editor);
#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
SVN_ERR_ASSERT(apr_hash_count(editor->pending_incomplete_children) == 0);
- SVN_ERR_ASSERT(apr_hash_count(editor->needs_text_or_target) == 0);
#endif
if (editor->funcs.cb_complete)
err = editor->funcs.cb_complete(editor->baton, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- if (!err)
- editor->finished = TRUE;
-#endif
+
+ MARK_FINISHED(editor);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
@@ -655,15 +739,13 @@ svn_editor_abort(svn_editor_t *editor)
{
svn_error_t *err = SVN_NO_ERROR;
-#ifdef ENABLE_ORDERING_CHECK
- SVN_ERR_ASSERT(!editor->finished);
-#endif
+ SHOULD_NOT_BE_FINISHED(editor);
if (editor->funcs.cb_abort)
err = editor->funcs.cb_abort(editor->baton, editor->scratch_pool);
-#ifdef ENABLE_ORDERING_CHECK
- editor->finished = TRUE;
-#endif
+
+ MARK_FINISHED(editor);
+
svn_pool_clear(editor->scratch_pool);
return err;
}
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/svndiff.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/svndiff.c Tue Mar 6 17:50:23 2012
@@ -645,7 +645,7 @@ decode_window(svn_txdelta_window_t *wind
svn_stringbuf_t *ndout = svn_stringbuf_create_empty(pool);
/* these may in fact simply return references to insend */
-
+
SVN_ERR(zlib_decode(insend, newlen, ndout,
SVN_DELTA_WINDOW_SIZE));
SVN_ERR(zlib_decode(data, insend - data, instout,
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/text_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/text_delta.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/text_delta.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/text_delta.c Tue Mar 6 17:50:23 2012
@@ -291,7 +291,7 @@ svn_txdelta__remove_copy(svn_txdelta__op
/* we can't modify svn_txdelta_target ops -> stop there */
if (op->action_code == svn_txdelta_target)
break;
-
+
/* handle the case that we cannot remove the op entirely */
if (op->length + len > max_len)
{
@@ -303,18 +303,18 @@ svn_txdelta__remove_copy(svn_txdelta__op
op->length -= max_len - len;
len = max_len;
}
-
+
break;
}
-
+
/* drop the op entirely */
if (op->action_code == svn_txdelta_new)
build_baton->new_data->len -= op->length;
-
+
len += op->length;
--build_baton->num_ops;
}
-
+
return len;
}
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/xdelta.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/xdelta.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/xdelta.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_delta/xdelta.c Tue Mar 6 17:50:23 2012
@@ -257,14 +257,18 @@ reverse_match_length(const char *a, cons
break;
pos -= sizeof(apr_size_t);
-
+
#endif
+ /* If we find a mismatch at -pos, pos-1 characters matched.
+ */
while (++pos <= max_len)
- if (a[-pos] != b[-pos])
- break;
-
- return pos-1;
+ if (a[0-pos] != b[0-pos])
+ return pos - 1;
+
+ /* No mismatch found -> at least MAX_LEN machting chars.
+ */
+ return max_len;
}
@@ -390,7 +394,7 @@ compute_delta(svn_txdelta__ops_baton_t *
apr_size_t lo = 0, pending_insert_start = 0;
/* Optimization: directly compare window starts. If more than 4
- * bytes match, we can immediately create a matching windows.
+ * bytes match, we can immediately create a matching windows.
* Shorter sequences result in a net data increase. */
lo = match_length(a, b, asize > bsize ? bsize : asize);
if ((lo > 4) || (lo == bsize))
@@ -442,7 +446,7 @@ compute_delta(svn_txdelta__ops_baton_t *
svn_txdelta__insert_op(build_baton, svn_txdelta_new,
0, lo - pending_insert_start,
b + pending_insert_start, pool);
- else
+ else
{
/* the match borders on the previous op. Maybe, we found a
* match that is better than / overlapping the previous one. */
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.c Tue Mar 6 17:50:23 2012
@@ -155,7 +155,7 @@ get_library_vtable_direct(fs_library_vta
/* Invoke the FS module's initfunc function with the common
pool protected by a lock. */
- SVN_MUTEX__WITH_LOCK(common_pool_lock,
+ SVN_MUTEX__WITH_LOCK(common_pool_lock,
initfunc(my_version, vtable, common_pool));
}
fs_version = (*vtable)->get_version();
@@ -357,7 +357,7 @@ svn_fs_create(svn_fs_t **fs_p, const cha
/* Perform the actual creation. */
*fs_p = fs_new(fs_config, pool);
-
+
SVN_MUTEX__WITH_LOCK(common_pool_lock,
vtable->create(*fs_p, path, pool, common_pool));
return SVN_NO_ERROR;
@@ -394,7 +394,9 @@ svn_error_t *
svn_fs_verify(const char *path,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- apr_pool_t *pool)
+ svn_revnum_t start,
+ svn_revnum_t end,
+ apr_pool_t *pool)
{
fs_library_vtable_t *vtable;
svn_fs_t *fs;
@@ -404,7 +406,7 @@ svn_fs_verify(const char *path,
SVN_MUTEX__WITH_LOCK(common_pool_lock,
vtable->verify_fs(fs, path, cancel_func, cancel_baton,
- pool, common_pool));
+ start, end, pool, common_pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.h?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs/fs-loader.h Tue Mar 6 17:50:23 2012
@@ -90,6 +90,8 @@ typedef struct fs_library_vtable_t
svn_error_t *(*verify_fs)(svn_fs_t *fs, const char *path,
/* ### notification? */
svn_cancel_func_t cancel_func, void *cancel_baton,
+ svn_revnum_t start,
+ svn_revnum_t end,
apr_pool_t *pool,
apr_pool_t *common_pool);
svn_error_t *(*delete_fs)(const char *path, apr_pool_t *pool);
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/bdb/env.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/bdb/env.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/bdb/env.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/bdb/env.c Tue Mar 6 17:50:23 2012
@@ -378,7 +378,7 @@ bdb_init_cb(void *baton, apr_pool_t *poo
{
bdb_cache_pool = svn_pool_create(pool);
bdb_cache = apr_hash_make(bdb_cache_pool);
-
+
SVN_ERR(svn_mutex__init(&bdb_cache_lock, TRUE, bdb_cache_pool));
apr_pool_cleanup_register(bdb_cache_pool, NULL, clear_cache,
apr_pool_cleanup_null);
@@ -493,7 +493,7 @@ static svn_error_t *
svn_fs_bdb__close_internal(bdb_env_t *bdb)
{
svn_error_t *err = SVN_NO_ERROR;
-
+
if (--bdb->refcount != 0)
{
/* If the environment is panicked and automatic recovery is not
@@ -543,7 +543,7 @@ svn_fs_bdb__close(bdb_env_baton_t *bdb_b
/* This may run during final pool cleanup when the lock is NULL. */
SVN_MUTEX__WITH_LOCK(bdb_cache_lock, svn_fs_bdb__close_internal(bdb));
-
+
return SVN_NO_ERROR;
}
@@ -587,7 +587,7 @@ cleanup_env_baton(void *data)
static svn_error_t *
-svn_fs_bdb__open_internal(bdb_env_baton_t **bdb_batonp,
+svn_fs_bdb__open_internal(bdb_env_baton_t **bdb_batonp,
const char *path,
u_int32_t flags, int mode,
apr_pool_t *pool)
@@ -643,7 +643,7 @@ svn_fs_bdb__open_internal(bdb_env_baton_
svn_error_clear(bdb_close(bdb));
return svn_error_trace(err);
}
-
+
apr_hash_set(bdb_cache, &bdb->key, sizeof bdb->key, bdb);
bdb->flags = flags;
bdb->refcount = 1;
@@ -669,11 +669,11 @@ svn_fs_bdb__open(bdb_env_baton_t **bdb_b
u_int32_t flags, int mode,
apr_pool_t *pool)
{
- SVN_MUTEX__WITH_LOCK(bdb_cache_lock,
- svn_fs_bdb__open_internal(bdb_batonp,
- path,
- flags,
- mode,
+ SVN_MUTEX__WITH_LOCK(bdb_cache_lock,
+ svn_fs_bdb__open_internal(bdb_batonp,
+ path,
+ flags,
+ mode,
pool));
return SVN_NO_ERROR;
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/fs.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/fs.c Tue Mar 6 17:50:23 2012
@@ -333,9 +333,10 @@ bdb_write_config(svn_fs_t *fs)
"#\n"
"# Make sure you read the documentation at:\n"
"#\n"
- "# http://www.oracle.com/technology/documentation/berkeley-db/db/ref/lock/max.html\n"
+ "# http://docs.oracle.com/cd/E17076_02/html/programmer_reference/lock_max.html\n"
"#\n"
"# before tweaking these values.\n"
+ "#\n"
"set_lk_max_locks 2000\n"
"set_lk_max_lockers 2000\n"
"set_lk_max_objects 2000\n"
@@ -344,9 +345,9 @@ bdb_write_config(svn_fs_t *fs)
"#\n"
"# Make sure you read the documentation at:\n"
"#\n"
- "# http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_lg_bsize.html\n"
- "# http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_lg_max.html\n"
- "# http://www.oracle.com/technology/documentation/berkeley-db/db/ref/log/limits.html\n"
+ "# http://docs.oracle.com/cd/E17076_02/html/api_reference/C/envset_lg_bsize.html\n"
+ "# http://docs.oracle.com/cd/E17076_02/html/api_reference/C/envset_lg_max.html\n"
+ "# http://docs.oracle.com/cd/E17076_02/html/programmer_reference/log_limits.html\n"
"#\n"
"# Increase the size of the in-memory log buffer from the default\n"
"# of 32 Kbytes to 256 Kbytes. Decrease the log file size from\n"
@@ -354,24 +355,28 @@ bdb_write_config(svn_fs_t *fs)
"# space required for hot backups. The size of the log file must be\n"
"# at least four times the size of the in-memory log buffer.\n"
"#\n"
- "# Note: Decreasing the in-memory buffer size below 256 Kbytes\n"
- "# will hurt commit performance. For details, see this post from\n"
- "# Daniel Berlin <da...@dberlin.org>:\n"
+ "# Note: Decreasing the in-memory buffer size below 256 Kbytes will hurt\n"
+ "# hurt commit performance. For details, see:\n"
+ "#\n"
+ "# http://svn.haxx.se/dev/archive-2002-02/0141.shtml\n"
"#\n"
- "# http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgId=161960\n"
"set_lg_bsize 262144\n"
"set_lg_max 1048576\n"
"#\n"
"# If you see \"log region out of memory\" errors, bump lg_regionmax.\n"
- "# See http://www.oracle.com/technology/documentation/berkeley-db/db/ref/log/config.html\n"
- "# and http://svn.haxx.se/users/archive-2004-10/1001.shtml for more.\n"
+ "# For more information, see:\n"
+ "#\n"
+ "# http://docs.oracle.com/cd/E17076_02/html/programmer_reference/log_config.html\n"
+ "# http://svn.haxx.se/users/archive-2004-10/1000.shtml\n"
+ "#\n"
"set_lg_regionmax 131072\n"
"#\n"
/* ### Configure this with "svnadmin create --bdb-cache-size" */
"# The default cache size in BDB is only 256k. As explained in\n"
- "# http://svn.haxx.se/dev/archive-2004-12/0369.shtml, this is too\n"
+ "# http://svn.haxx.se/dev/archive-2004-12/0368.shtml, this is too\n"
"# small for most applications. Bump this number if \"db_stat -m\"\n"
"# shows too many cache misses.\n"
+ "#\n"
"set_cachesize 0 1048576 1\n";
/* Run-time configurable options.
@@ -397,11 +402,12 @@ bdb_write_config(svn_fs_t *fs)
"# Disable fsync of log files on transaction commit. Read the\n"
"# documentation about DB_TXN_NOSYNC at:\n"
"#\n"
- "# http://www.oracle.com/technology/documentation/berkeley-db/db/ref/log/config.html\n"
+ "# http://docs.oracle.com/cd/E17076_02/html/programmer_reference/log_config.html\n"
"#\n"
- "# [requires Berkeley DB 4.0]\n",
+ "# [requires Berkeley DB 4.0]\n"
+ "#\n",
/* inactive */
- "# set_flags DB_TXN_NOSYNC\n",
+ "#set_flags DB_TXN_NOSYNC\n",
/* active */
"set_flags DB_TXN_NOSYNC\n" },
/* Controlled by "svnadmin create --bdb-log-keep" */
@@ -411,11 +417,12 @@ bdb_write_config(svn_fs_t *fs)
"# Enable automatic removal of unused transaction log files.\n"
"# Read the documentation about DB_LOG_AUTOREMOVE at:\n"
"#\n"
- "# http://www.oracle.com/technology/documentation/berkeley-db/db/ref/log/config.html\n"
+ "# http://docs.oracle.com/cd/E17076_02/html/programmer_reference/log_config.html\n"
"#\n"
- "# [requires Berkeley DB 4.2]\n",
+ "# [requires Berkeley DB 4.2]\n"
+ "#\n",
/* inactive */
- "# set_flags DB_LOG_AUTOREMOVE\n",
+ "#set_flags DB_LOG_AUTOREMOVE\n",
/* active */
"set_flags DB_LOG_AUTOREMOVE\n" },
};
@@ -876,6 +883,8 @@ static svn_error_t *
base_verify(svn_fs_t *fs, const char *path,
svn_cancel_func_t cancel_func,
void *cancel_baton,
+ svn_revnum_t start,
+ svn_revnum_t end,
apr_pool_t *pool,
apr_pool_t *common_pool)
{
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/notes/structure
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/notes/structure?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/notes/structure (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_base/notes/structure Tue Mar 6 17:50:23 2012
@@ -104,8 +104,8 @@ structure summary" section of this docum
NODE-REVISION: how we represent a node revision
We represent a given revision of a file or directory node using a list
-skel (see skel.h for an explanation of skels). A node revision skel
-has the form:
+skel (see include/private/svn_skel.h for an explanation of skels).
+A node revision skel has the form:
(HEADER PROP-KEY KIND-SPECIFIC ...)
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/caching.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/caching.c Tue Mar 6 17:50:23 2012
@@ -339,6 +339,27 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
SVN_ERR(init_callbacks(ffd->fulltext_cache, fs, no_handler, pool));
+ /* initialize revprop cache, if full-text caching has been enabled */
+ if (cache_fulltexts)
+ {
+ SVN_ERR(create_cache(&(ffd->revprop_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ svn_fs_fs__serialize_properties,
+ svn_fs_fs__deserialize_properties,
+ APR_HASH_KEY_STRING,
+ apr_pstrcat(pool, prefix, "REVPROP",
+ (char *)NULL),
+ fs->pool));
+ }
+ else
+ {
+ ffd->revprop_cache = NULL;
+ }
+
+ SVN_ERR(init_callbacks(ffd->revprop_cache, fs, no_handler, pool));
+
/* initialize txdelta window cache, if that has been enabled */
if (cache_txdeltas)
{
@@ -360,6 +381,27 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
SVN_ERR(init_callbacks(ffd->txdelta_window_cache, fs, no_handler, pool));
+ /* initialize txdelta window cache, if that has been enabled */
+ if (cache_txdeltas)
+ {
+ SVN_ERR(create_cache(&(ffd->combined_window_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ /* Values are svn_stringbuf_t */
+ NULL, NULL,
+ APR_HASH_KEY_STRING,
+ apr_pstrcat(pool, prefix, "COMBINED_WINDOW",
+ (char *)NULL),
+ fs->pool));
+ }
+ else
+ {
+ ffd->combined_window_cache = NULL;
+ }
+
+ SVN_ERR(init_callbacks(ffd->combined_window_cache, fs, no_handler, pool));
+
/* initialize node revision cache, if caching has been enabled */
SVN_ERR(create_cache(&(ffd->node_revision_cache),
NULL,
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.c?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.c Tue Mar 6 17:50:23 2012
@@ -92,7 +92,7 @@ fs_serialized_init(svn_fs_t *fs, apr_poo
SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
/* ... not to mention locking the txn-current file. */
- SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock,
+ SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock,
SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
SVN_ERR(svn_mutex__init(&ffsd->txn_list_lock,
@@ -243,6 +243,8 @@ static svn_error_t *
fs_verify(svn_fs_t *fs, const char *path,
svn_cancel_func_t cancel_func,
void *cancel_baton,
+ svn_revnum_t start,
+ svn_revnum_t end,
apr_pool_t *pool,
apr_pool_t *common_pool)
{
@@ -251,7 +253,7 @@ fs_verify(svn_fs_t *fs, const char *path
SVN_ERR(svn_fs_fs__open(fs, path, pool));
SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
SVN_ERR(fs_serialized_init(fs, common_pool, pool));
- return svn_fs_fs__verify(fs, cancel_func, cancel_baton, pool);
+ return svn_fs_fs__verify(fs, cancel_func, cancel_baton, start, end, pool);
}
static svn_error_t *
Modified: subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.h?rev=1297604&r1=1297603&r2=1297604&view=diff
==============================================================================
--- subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/reintegrate-keep-alive/subversion/libsvn_fs_fs/fs.h Tue Mar 6 17:50:23 2012
@@ -60,6 +60,8 @@ extern "C" {
#define PATH_LOCKS_DIR "locks" /* Directory of locks */
#define PATH_MIN_UNPACKED_REV "min-unpacked-rev" /* Oldest revision which
has not been packed. */
+#define PATH_REVPROP_GEN "revprop-gen" /* File containing the
+ revprop change counter */
/* If you change this, look at tests/svn_test_fs.c(maybe_install_fsfs_conf) */
#define PATH_CONFIG "fsfs.conf" /* Configuration */
@@ -198,7 +200,8 @@ typedef struct fs_fs_shared_data_t
apr_pool_t *common_pool;
} fs_fs_shared_data_t;
-/* Private (non-shared) FSFS-specific data for each svn_fs_t object. */
+/* Private (non-shared) FSFS-specific data for each svn_fs_t object.
+ Any caches in here may be NULL. */
typedef struct fs_fs_data_t
{
/* The format number of this FS. */
@@ -224,17 +227,28 @@ typedef struct fs_fs_data_t
(svn_fs_id_t *). (Not threadsafe.) */
svn_cache__t *rev_root_id_cache;
- /* DAG node cache for immutable nodes */
+ /* DAG node cache for immutable nodes. Maps (revision, fspath)
+ to (dag_node_t *). */
svn_cache__t *rev_node_cache;
/* A cache of the contents of immutable directories; maps from
- unparsed FS ID to ###x. */
+ unparsed FS ID to a apr_hash_t * mapping (const char *) dirent
+ names to (svn_fs_dirent_t *). */
svn_cache__t *dir_cache;
/* Fulltext cache; currently only used with memcached. Maps from
- rep key to svn_string_t. */
+ rep key (revision/offset) to svn_string_t. */
svn_cache__t *fulltext_cache;
+ /* Revprop "generation" that is valid for this svn_fs_t.
+ It is the revprop change counter read once from "revprop-gen".
+ Will be read upon first access. 0 means that the value has not
+ been read from disk, yet. */
+ apr_int64_t revprop_generation;
+
+ /* Revision property cache. Maps from (rev,generation) to apr_hash_t. */
+ svn_cache__t *revprop_cache;
+
/* Pack manifest cache; a cache mapping (svn_revnum_t) shard number to
a manifest; and a manifest is a mapping from (svn_revnum_t) revision
number offset within a shard to (apr_off_t) byte-offset in the
@@ -244,6 +258,10 @@ typedef struct fs_fs_data_t
/* Cache for txdelta_window_t objects; the key is (revFilePath, offset) */
svn_cache__t *txdelta_window_cache;
+ /* Cache for combined windows as svn_stringbuf_t objects;
+ the key is (revFilePath, offset) */
+ svn_cache__t *combined_window_cache;
+
/* Cache for node_revision_t objects; the key is (revision, id offset) */
svn_cache__t *node_revision_cache;