Modified: subversion/branches/revprop-packing/subversion/libsvn_delta/editor.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_delta/editor.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_delta/editor.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_delta/editor.c Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_delta/svndiff.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_delta/svndiff.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_delta/svndiff.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_delta/svndiff.c Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_delta/text_delta.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_delta/text_delta.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_delta/text_delta.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_delta/text_delta.c Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_delta/xdelta.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_delta/xdelta.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_delta/xdelta.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_delta/xdelta.c Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_fs/fs-loader.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs/fs-loader.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs/fs-loader.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs/fs-loader.c Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_fs/fs-loader.h URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs/fs-loader.h?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs/fs-loader.h (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs/fs-loader.h Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_fs_base/bdb/env.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs_base/bdb/env.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs_base/bdb/env.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs_base/bdb/env.c Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_fs_base/fs.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs_base/fs.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs_base/fs.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs_base/fs.c Mon Mar 5 09:25:25 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 <[email protected]>:\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" }, }; @@ -883,6 +890,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/revprop-packing/subversion/libsvn_fs_base/notes/structure URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs_base/notes/structure?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs_base/notes/structure (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs_base/notes/structure Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_fs_fs/caching.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs_fs/caching.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs_fs/caching.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs_fs/caching.c Mon Mar 5 09:25:25 2012 @@ -360,6 +360,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/revprop-packing/subversion/libsvn_fs_fs/fs.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs.c (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs.c Mon Mar 5 09:25:25 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/revprop-packing/subversion/libsvn_fs_fs/fs.h URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs.h?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs.h (original) +++ subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs.h Mon Mar 5 09:25:25 2012 @@ -232,15 +232,17 @@ 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; /* Pack manifest cache; a cache mapping (svn_revnum_t) shard number to @@ -252,6 +254,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;
