Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db.h URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db.h?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db.h (original) +++ subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db.h Sun Jan 6 02:33:34 2013 @@ -74,7 +74,7 @@ extern "C" { The pool that DB is allocated within (the "state" pool) is only used for a few, limited allocations to track each of the working copy roots that the DB is asked to operate upon. The memory usage on this pool - os O(# wcroots), which should normally be one or a few. Custom clients + is O(# wcroots), which should normally be one or a few. Custom clients which hold open structures over a significant period of time should pay particular attention to the number of roots touched, and the resulting impact on memory consumption (which should still be minimal). @@ -213,7 +213,7 @@ typedef struct svn_wc__db_lock_t { /* - @defgroup svn_wc__db_admin General administractive functions + @defgroup svn_wc__db_admin General administrative functions @{ */ @@ -729,6 +729,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db, LOCK NULL HAD_PROPS FALSE + PROPS NULL UPDATE_ROOT FALSE @@ -744,6 +745,11 @@ svn_wc__db_base_remove(svn_wc__db_t *db, If TARGET is requested, and the node is NOT a symlink, then it will be set to NULL. + *PROPS maps "const char *" names to "const svn_string_t *" values. If + the base node is capable of having properties but has none, set + *PROPS to an empty hash. If its status is such that it cannot have + properties, set *PROPS to NULL. + If UPDATE_ROOT is requested, set it to TRUE if the node should only be updated when it is the root of an update (e.g. file externals). @@ -765,6 +771,7 @@ svn_wc__db_base_get_info(svn_wc__db_stat const char **target, svn_wc__db_lock_t **lock, svn_boolean_t *had_props, + apr_hash_t **props, svn_boolean_t *update_root, svn_wc__db_t *db, const char *local_abspath, @@ -800,7 +807,8 @@ svn_wc__db_base_get_children_info(apr_ha *PROPS maps "const char *" names to "const svn_string_t *" values. If the node has no properties, set *PROPS to an empty hash. *PROPS will never be set to NULL. - If the node is not present in the BASE tree, return an error. + If the node is not present in the BASE tree (with presence 'normal' + or 'incomplete'), return an error. Allocate *PROPS and its keys and values in RESULT_POOL. */ svn_error_t * @@ -987,12 +995,10 @@ svn_wc__db_pristine_get_sha1(const svn_c /* If necessary transfers the PRISTINE file of SRC_LOCAL_ABSPATH to the - working copy identified by DST_WRI_ABSPATH. If CHECKSUM is not NULL, use - CHECKSUM to identify which pristine file to transfer. */ + working copy identified by DST_WRI_ABSPATH. */ svn_error_t * svn_wc__db_pristine_transfer(svn_wc__db_t *db, const char *src_local_abspath, - const svn_checksum_t *checksum, const char *dst_wri_abspath, svn_cancel_func_t cancel_func, void *cancel_baton, @@ -1150,7 +1156,7 @@ svn_wc__db_external_remove(svn_wc__db_t When KIND is requested then the value will be set to the kind of external. - If DEFININING_ABSPATH is requested, then the value will be set to the + If DEFINING_ABSPATH is requested, then the value will be set to the absolute path of the directory which originally defined the external. (The path with the svn:externals property) @@ -1284,7 +1290,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db, * of SRC_ABSPATH (so SRC_ABSPATH must be an op_root) to dst_abspaths * parents layer. * - * This operation is recursive. It copies all the descandants at the lower + * This operation is recursive. It copies all the descendants at the lower * layer and adds base-deleted nodes on dst_abspath layer to mark these nodes * properly deleted. * @@ -1370,31 +1376,37 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t /* ### add a new versioned directory. a list of children is NOT passed ### since they are added in future, distinct calls to db_op_add_*. - ### this is freshly added, so it has no properties. */ + PROPS gives the properties; empty or NULL means none. */ /* ### do we need a CONFLICTS param? */ svn_error_t * svn_wc__db_op_add_directory(svn_wc__db_t *db, const char *local_abspath, + const apr_hash_t *props, const svn_skel_t *work_items, apr_pool_t *scratch_pool); -/* ### as a new file, there are no properties. this file has no "pristine" +/* Add a file. + PROPS gives the properties; empty or NULL means none. + ### this file has no "pristine" ### contents, so a checksum [reference] is not required. */ /* ### do we need a CONFLICTS param? */ svn_error_t * svn_wc__db_op_add_file(svn_wc__db_t *db, const char *local_abspath, + const apr_hash_t *props, const svn_skel_t *work_items, apr_pool_t *scratch_pool); -/* ### newly added symlinks have no properties. */ +/* Add a symlink. + PROPS gives the properties; empty or NULL means none. */ /* ### do we need a CONFLICTS param? */ svn_error_t * svn_wc__db_op_add_symlink(svn_wc__db_t *db, const char *local_abspath, const char *target, + const apr_hash_t *props, const svn_skel_t *work_items, apr_pool_t *scratch_pool); @@ -1409,8 +1421,8 @@ svn_wc__db_op_add_symlink(svn_wc__db_t * If PROPS is NULL, set the properties to be the same as the pristine properties. - CONFLICT is used to register a conflict on this node at the same time - the properties are changed. + If CONFLICT is not NULL, it is used to register a conflict on this + node at the same time the properties are changed. WORK_ITEMS are inserted into the work queue, as additional things that need to be completed before the working copy is stable. @@ -1437,42 +1449,6 @@ svn_wc__db_op_set_props(svn_wc__db_t *db const svn_skel_t *work_items, apr_pool_t *scratch_pool); -/* See props.h */ -#ifdef SVN__SUPPORT_BASE_MERGE -/* ### Set the properties of the node LOCAL_ABSPATH in the BASE tree to PROPS. - ### - ### This function should not exist because properties should be stored - ### onto the BASE node at construction time, in a single atomic operation. - ### - ### PROPS maps "const char *" names to "const svn_string_t *" values. - ### To specify no properties, PROPS must be an empty hash, not NULL. - ### If the node is not present, SVN_ERR_WC_PATH_NOT_FOUND is returned. -*/ -svn_error_t * -svn_wc__db_temp_base_set_props(svn_wc__db_t *db, - const char *local_abspath, - const apr_hash_t *props, - apr_pool_t *scratch_pool); - - -/* ### Set the properties of the node LOCAL_ABSPATH in the WORKING tree - ### to PROPS. - ### - ### This function should not exist because properties should be stored - ### onto the WORKING node at construction time, in a single atomic - ### operation. - ### - ### PROPS maps "const char *" names to "const svn_string_t *" values. - ### To specify no properties, PROPS must be an empty hash, not NULL. - ### If the node is not present, SVN_ERR_WC_PATH_NOT_FOUND is returned. -*/ -svn_error_t * -svn_wc__db_temp_working_set_props(svn_wc__db_t *db, - const char *local_abspath, - const apr_hash_t *props, - apr_pool_t *scratch_pool); -#endif - /* Mark LOCAL_ABSPATH, and all children, for deletion. * * This function removes the file externals (and if DELETE_DIR_EXTERNALS is @@ -1723,7 +1699,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t LOCK NULL RECORDED_SIZE SVN_INVALID_FILESIZE - RECORDED_MOD_TIME 0 + RECORDED_TIME 0 CHANGELIST NULL CONFLICTED FALSE @@ -1807,7 +1783,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t If HAD_PROPS is requested and the node has pristine props, the value will be set to TRUE. - If PROP_MODS is requested and the node has property modification the value + If PROPS_MOD is requested and the node has property modification the value will be set to TRUE. ### add information about the need to scan upwards to get a complete @@ -1818,7 +1794,7 @@ svn_wc__db_revert_list_done(svn_wc__db_t ### the TEXT_MOD may become an enumerated value at some point to ### indicate different states of knowledge about text modifications. ### for example, an "svn edit" command in the future might set a - ### flag indicating adminstratively-defined modification. and/or we + ### flag indicating administratively-defined modification. and/or we ### might have a status indicating that we saw it was modified while ### performing a filesystem traversal. @@ -1875,7 +1851,7 @@ svn_wc__db_read_info(svn_wc__db_status_t /* Recorded for files present in the working copy */ svn_filesize_t *recorded_size, - apr_time_t *recorded_mod_time, + apr_time_t *recorded_time, /* From ACTUAL */ const char **changelist, @@ -1911,7 +1887,7 @@ struct svn_wc__db_info_t { svn_depth_t depth; svn_filesize_t recorded_size; - apr_time_t recorded_mod_time; + apr_time_t recorded_time; const char *changelist; svn_boolean_t conflicted; @@ -1975,6 +1951,11 @@ struct svn_wc__db_walker_info_t { calling svn_wc__db_read_info(). (All other information (like original_*) can be obtained via other apis). + + *PROPS maps "const char *" names to "const svn_string_t *" values. If + the pristine node is capable of having properties but has none, set + *PROPS to an empty hash. If its status is such that it cannot have + properties, set *PROPS to NULL. */ svn_error_t * svn_wc__db_read_pristine_info(svn_wc__db_status_t *status, @@ -1986,6 +1967,7 @@ svn_wc__db_read_pristine_info(svn_wc__db const svn_checksum_t **checksum, /* files only */ const char **target, /* symlinks only */ svn_boolean_t *had_props, + apr_hash_t **props, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *result_pool, @@ -2013,7 +1995,7 @@ svn_wc__db_read_node_install_info(const apr_pool_t *scratch_pool); /* Return in *NODES a hash mapping name->struct svn_wc__db_walker_info_t for - the children of DIR_ABSPATH. "name" is the child's name relatve to + the children of DIR_ABSPATH. "name" is the child's name relative to DIR_ABSPATH, not an absolute path. */ svn_error_t * svn_wc__db_read_children_walker_info(apr_hash_t **nodes, @@ -2057,11 +2039,8 @@ svn_wc__db_read_props(apr_hash_t **props * a hash table mapping <tt>char *</tt> names onto svn_string_t * * values for any properties of child nodes of LOCAL_ABSPATH (up to DEPTH). * - * If BASE_PROPS is FALSE, read the properties from the WORKING layer (highest - * op_depth). - * - * If BASE_PROPS is FALSE and, PRISTINE is TRUE, the local modifications will - * be suppressed. If PRISTINE is FALSE, local modifications will be visible. + * If PRISTINE is FALSE, read the properties from the WORKING layer (highest + * op_depth); if PRISTINE is FALSE, local modifications will be visible. */ svn_error_t * svn_wc__db_read_props_streamily(svn_wc__db_t *db, @@ -2171,7 +2150,7 @@ svn_wc__db_prop_retrieve_recursive(apr_h Return every path that refers to a child of the working node at LOCAL_ABSPATH. Do not include a path just because it was a child of a deleted directory that existed at LOCAL_ABSPATH if that directory is now - sheduled to be replaced by the working node at LOCAL_ABSPATH. + scheduled to be replaced by the working node at LOCAL_ABSPATH. Allocate *CHILDREN in RESULT_POOL and do temporary allocations in SCRATCH_POOL. @@ -2302,23 +2281,28 @@ svn_wc__db_node_check_replace(svn_boolea ### changelist usage -- we may already assume the list fits in memory. */ -/* Checks if LOCAL_ABSPATH has a parent directory that knows about its - * existance. Set *IS_ROOT to FALSE if a parent is found, and to TRUE - * if there is no such parent. +/* The DB-private version of svn_wc__is_wcroot(), which see. */ svn_error_t * -svn_wc__db_is_wcroot(svn_boolean_t *is_root, +svn_wc__db_is_wcroot(svn_boolean_t *is_wcroot, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *scratch_pool); -/* Checks if LOCAL_ABSPATH is a working copy root, switched and a directory. - With these answers we can answer all 'is anchor' questions that we need for - the different ra operations with just a single sqlite transaction and - filestat. +/* Check whether a node is a working copy root and/or switched. + + If LOCAL_ABSPATH is the root of a working copy, set *IS_WC_ROOT to TRUE, + otherwise to FALSE. + + If LOCAL_ABSPATH is switched against its parent in the same working copy + set *IS_SWITCHED to TRUE, otherwise to FALSE. - All output arguments can be null to specify that the result is not - interesting to the caller + If KIND is not null, set *KIND to the node type of LOCAL_ABSPATH. + + Any of the output arguments can be null to specify that the result is not + interesting to the caller. + + Use SCRATCH_POOL for temporary allocations. */ svn_error_t * svn_wc__db_is_switched(svn_boolean_t *is_wcroot, @@ -2373,7 +2357,7 @@ svn_wc__db_global_relocate(svn_wc__db_t CHANGED_REVISION is the new 'last changed' revision. If the node is modified its value is equivalent to NEW_REVISION, but in case of a - decendant of a copy/move it can be an older revision. + descendant of a copy/move it can be an older revision. CHANGED_DATE is the (server-side) date of CHANGED_REVISION. It may be 0 if the revprop is missing on the revision. @@ -2496,23 +2480,23 @@ svn_wc__db_op_bump_revisions_post_update apr_pool_t *scratch_pool); -/* Record the TRANSLATED_SIZE and LAST_MOD_TIME for a versioned node. +/* Record the RECORDED_SIZE and RECORDED_TIME for a versioned node. This function will record the information within the WORKING node, if present, or within the BASE tree. If neither node is present, then SVN_ERR_WC_PATH_NOT_FOUND will be returned. - TRANSLATED_SIZE may be SVN_INVALID_FILESIZE, which will be recorded + RECORDED_SIZE may be SVN_INVALID_FILESIZE, which will be recorded as such, implying "unknown size". - LAST_MOD_TIME may be 0, which will be recorded as such, implying + RECORDED_TIME may be 0, which will be recorded as such, implying "unknown last mod time". */ svn_error_t * svn_wc__db_global_record_fileinfo(svn_wc__db_t *db, const char *local_abspath, - svn_filesize_t translated_size, - apr_time_t last_mod_time, + svn_filesize_t recorded_size, + apr_time_t recorded_time, apr_pool_t *scratch_pool); @@ -3116,7 +3100,7 @@ svn_wc__db_get_not_present_descendants(c * Only nodes with op_depth zero and presence 'normal' or 'incomplete' * are considered, so that added, deleted or excluded nodes do not affect * the result. If COMMITTED is TRUE, set *MIN_REVISION and *MAX_REVISION - * to the lowest and highest comitted (i.e. "last changed") revision numbers, + * to the lowest and highest committed (i.e. "last changed") revision numbers, * respectively. * * Indicate in *IS_SPARSE_CHECKOUT whether any of the nodes within @@ -3151,7 +3135,7 @@ svn_wc__db_revision_status(svn_revnum_t * Only nodes with op_depth zero and presence 'normal' or 'incomplete' * are considered, so that added, deleted or excluded nodes do not affect * the result. If COMMITTED is TRUE, set *MIN_REVISION and *MAX_REVISION - * to the lowest and highest comitted (i.e. "last changed") revision numbers, + * to the lowest and highest committed (i.e. "last changed") revision numbers, * respectively. Use SCRATCH_POOL for temporary allocations. * * Either of MIN_REVISION and MAX_REVISION may be passed as NULL if @@ -3247,8 +3231,8 @@ svn_wc__db_follow_moved_to(apr_array_hea * need to run as part of marking the conflict resolved. */ svn_error_t * svn_wc__db_update_moved_away_conflict_victim(svn_skel_t **work_items, - const char *victim_abspath, svn_wc__db_t *db, + const char *victim_abspath, svn_wc_notify_func2_t notify_func, void *notify_baton, svn_cancel_func_t cancel_func, @@ -3256,6 +3240,13 @@ svn_wc__db_update_moved_away_conflict_vi apr_pool_t *result_pool, apr_pool_t *scratch_pool); +/* Recover space from the database file for LOCAL_ABSPATH by running + * the "vacuum" command. */ +svn_error_t * +svn_wc__db_vacuum(svn_wc__db_t *db, + const char *local_abspath, + apr_pool_t *scratch_pool); + /* @} */
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_pristine.c URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_pristine.c?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_pristine.c (original) +++ subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_pristine.c Sun Jan 6 02:33:34 2013 @@ -143,43 +143,30 @@ svn_wc__db_pristine_get_future_path(cons return SVN_NO_ERROR; } -/* Data for pristine_read_txn(). */ -typedef struct pristine_read_baton_t -{ - /* Where to put the result stream. */ - svn_stream_t **contents; - /* The pristine text's SHA-1 checksum. */ - const svn_checksum_t *sha1_checksum; - /* The path to the pristine file (within the pristine store). */ - const char *pristine_abspath; - - /* Pointer to where to place the size (if requested) */ - svn_filesize_t *size; - - /* The pool from which to allocate the result stream. */ - apr_pool_t *result_pool; -} pristine_read_baton_t; - -/* Set (*BATON->contents) to a readable stream from which the pristine text - * identified by BATON->sha1_checksum can be read from the pristine store of - * SDB. If that text is not in the pristine store, return an error. +/* Set *CONTENTS to a readable stream from which the pristine text + * identified by SHA1_CHECKSUM and PRISTINE_ABSPATH can be read from the + * pristine store of WCROOT. If SIZE is not null, set *SIZE to the size + * in bytes of that text. If that text is not in the pristine store, + * return an error. * * Even if the pristine text is removed from the store while it is being * read, the stream will remain valid and readable until it is closed. * - * Allocate the stream in BATON->result_pool. + * Allocate the stream in RESULT_POOL. * * This function expects to be executed inside a SQLite txn. * * Implements 'notes/wc-ng/pristine-store' section A-3(d). - * Implements svn_sqlite__transaction_callback_t. */ + */ static svn_error_t * -pristine_read_txn(void *baton, +pristine_read_txn(svn_stream_t **contents, + svn_filesize_t *size, svn_wc__db_wcroot_t *wcroot, - const char *local_relpath, + const svn_checksum_t *sha1_checksum, + const char *pristine_abspath, + apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - pristine_read_baton_t *b = baton; svn_sqlite__stmt_t *stmt; svn_boolean_t have_row; @@ -187,11 +174,11 @@ pristine_read_txn(void *baton, * of the file is not sufficient.) */ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_PRISTINE_SIZE)); - SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool)); + SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool)); SVN_ERR(svn_sqlite__step(&have_row, stmt)); - if (b->size) - *b->size = svn_sqlite__column_int64(stmt, 0); + if (size) + *size = svn_sqlite__column_int64(stmt, 0); SVN_ERR(svn_sqlite__reset(stmt)); if (! have_row) @@ -199,14 +186,14 @@ pristine_read_txn(void *baton, return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL, _("Pristine text '%s' not present"), svn_checksum_to_cstring_display( - b->sha1_checksum, scratch_pool)); + sha1_checksum, scratch_pool)); } /* Open the file as a readable stream. It will remain readable even when * deleted from disk; APR guarantees that on Windows as well as Unix. */ - if (b->contents) - SVN_ERR(svn_stream_open_readonly(b->contents, b->pristine_abspath, - b->result_pool, scratch_pool)); + if (contents) + SVN_ERR(svn_stream_open_readonly(contents, pristine_abspath, + result_pool, scratch_pool)); return SVN_NO_ERROR; } @@ -221,7 +208,7 @@ svn_wc__db_pristine_read(svn_stream_t ** { svn_wc__db_wcroot_t *wcroot; const char *local_relpath; - pristine_read_baton_t b; + const char *pristine_abspath; SVN_ERR_ASSERT(contents != NULL); SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath)); @@ -240,15 +227,14 @@ svn_wc__db_pristine_read(svn_stream_t ** wri_abspath, scratch_pool, scratch_pool)); VERIFY_USABLE_WCROOT(wcroot); - b.contents = contents; - b.sha1_checksum = sha1_checksum; - b.size = size; - b.result_pool = result_pool; - SVN_ERR(get_pristine_fname(&b.pristine_abspath, wcroot->abspath, + SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath, sha1_checksum, scratch_pool, scratch_pool)); - SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, pristine_read_txn, &b, - scratch_pool)); + SVN_WC__DB_WITH_TXN( + pristine_read_txn(contents, size, + wcroot, sha1_checksum, pristine_abspath, + result_pool, scratch_pool), + wcroot); return SVN_NO_ERROR; } @@ -288,20 +274,6 @@ svn_wc__db_pristine_get_tempdir(const ch } -/* Data for pristine_install_txn(). */ -typedef struct pristine_install_baton_t -{ - /* The path to the source file that is to be moved into place. */ - const char *tempfile_abspath; - /* The target path for the file (within the pristine store). */ - const char *pristine_abspath; - /* The pristine text's SHA-1 checksum. */ - const svn_checksum_t *sha1_checksum; - /* The pristine text's MD-5 checksum. */ - const svn_checksum_t *md5_checksum; -} pristine_install_baton_t; - - /* Install the pristine text described by BATON into the pristine store of * SDB. If it is already stored then just delete the new file * BATON->tempfile_abspath. @@ -310,13 +282,19 @@ typedef struct pristine_install_baton_t * acquired a 'RESERVED' lock. * * Implements 'notes/wc-ng/pristine-store' section A-3(a). - * Implements svn_sqlite__transaction_callback_t. */ + */ static svn_error_t * -pristine_install_txn(void *baton, - svn_sqlite__db_t *sdb, +pristine_install_txn(svn_sqlite__db_t *sdb, + /* The path to the source file that is to be moved into place. */ + const char *tempfile_abspath, + /* The target path for the file (within the pristine store). */ + const char *pristine_abspath, + /* The pristine text's SHA-1 checksum. */ + const svn_checksum_t *sha1_checksum, + /* The pristine text's MD-5 checksum. */ + const svn_checksum_t *md5_checksum, apr_pool_t *scratch_pool) { - pristine_install_baton_t *b = baton; apr_finfo_t finfo; svn_sqlite__stmt_t *stmt; svn_boolean_t have_row; @@ -325,7 +303,7 @@ pristine_install_txn(void *baton, /* If this pristine text is already present in the store, just keep it: * delete the new one and return. */ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_PRISTINE)); - SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool)); + SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool)); SVN_ERR(svn_sqlite__step(&have_row, stmt)); SVN_ERR(svn_sqlite__reset(stmt)); if (have_row) @@ -335,30 +313,30 @@ pristine_install_txn(void *baton, * ### We could check much more. */ { apr_finfo_t finfo1, finfo2; - SVN_ERR(svn_io_stat(&finfo1, b->tempfile_abspath, APR_FINFO_SIZE, + SVN_ERR(svn_io_stat(&finfo1, tempfile_abspath, APR_FINFO_SIZE, scratch_pool)); - SVN_ERR(svn_io_stat(&finfo2, b->pristine_abspath, APR_FINFO_SIZE, + SVN_ERR(svn_io_stat(&finfo2, pristine_abspath, APR_FINFO_SIZE, scratch_pool)); if (finfo1.size != finfo2.size) { return svn_error_createf( SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL, _("New pristine text '%s' has different size: %ld versus %ld"), - svn_checksum_to_cstring_display(b->sha1_checksum, scratch_pool), + svn_checksum_to_cstring_display(sha1_checksum, scratch_pool), (long int)finfo1.size, (long int)finfo2.size); } } #endif /* Remove the temp file: it's already there */ - SVN_ERR(svn_io_remove_file2(b->tempfile_abspath, + SVN_ERR(svn_io_remove_file2(tempfile_abspath, FALSE /* ignore_enoent */, scratch_pool)); return SVN_NO_ERROR; } /* Move the file to its target location. (If it is already there, it is * an orphan file and it doesn't matter if we overwrite it.) */ - err = svn_io_file_rename(b->tempfile_abspath, b->pristine_abspath, + err = svn_io_file_rename(tempfile_abspath, pristine_abspath, scratch_pool); /* Maybe the directory doesn't exist yet? */ @@ -366,7 +344,7 @@ pristine_install_txn(void *baton, { svn_error_t *err2; - err2 = svn_io_dir_make(svn_dirent_dirname(b->pristine_abspath, + err2 = svn_io_dir_make(svn_dirent_dirname(pristine_abspath, scratch_pool), APR_OS_DEFAULT, scratch_pool); @@ -377,19 +355,19 @@ pristine_install_txn(void *baton, /* We could create a directory: retry install */ svn_error_clear(err); - SVN_ERR(svn_io_file_rename(b->tempfile_abspath, b->pristine_abspath, + SVN_ERR(svn_io_file_rename(tempfile_abspath, pristine_abspath, scratch_pool)); } else SVN_ERR(err); - SVN_ERR(svn_io_stat(&finfo, b->pristine_abspath, APR_FINFO_SIZE, + SVN_ERR(svn_io_stat(&finfo, pristine_abspath, APR_FINFO_SIZE, scratch_pool)); SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_PRISTINE)); - SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool)); - SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, b->md5_checksum, scratch_pool)); + SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool)); + SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool)); SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size)); SVN_ERR(svn_sqlite__insert(NULL, stmt)); @@ -407,7 +385,7 @@ svn_wc__db_pristine_install(svn_wc__db_t svn_wc__db_wcroot_t *wcroot; const char *local_relpath; const char *wri_abspath; - struct pristine_install_baton_t b; + const char *pristine_abspath; SVN_ERR_ASSERT(svn_dirent_is_absolute(tempfile_abspath)); SVN_ERR_ASSERT(sha1_checksum != NULL); @@ -429,19 +407,18 @@ svn_wc__db_pristine_install(svn_wc__db_t wri_abspath, scratch_pool, scratch_pool)); VERIFY_USABLE_WCROOT(wcroot); - b.tempfile_abspath = tempfile_abspath; - b.sha1_checksum = sha1_checksum; - b.md5_checksum = md5_checksum; - - SVN_ERR(get_pristine_fname(&b.pristine_abspath, wcroot->abspath, + SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath, sha1_checksum, scratch_pool, scratch_pool)); /* Ensure the SQL txn has at least a 'RESERVED' lock before we start looking * at the disk, to ensure no concurrent pristine install/delete txn. */ - SVN_ERR(svn_sqlite__with_immediate_transaction(wcroot->sdb, - pristine_install_txn, &b, - scratch_pool)); + SVN_SQLITE__WITH_IMMEDIATE_TXN( + pristine_install_txn(wcroot->sdb, + tempfile_abspath, pristine_abspath, + sha1_checksum, md5_checksum, + scratch_pool), + wcroot->sdb); return SVN_NO_ERROR; } @@ -523,71 +500,55 @@ svn_wc__db_pristine_get_sha1(const svn_c return svn_error_trace(svn_sqlite__reset(stmt)); } -/* Baton for pristine_transfer() */ -struct pristine_transfer_baton -{ - svn_wc__db_wcroot_t *src_wcroot; - svn_wc__db_wcroot_t *dst_wcroot; - svn_cancel_func_t cancel_func; - void * cancel_baton; - - /* pristine install baton, filled from pristine_transfer() */ - struct pristine_install_baton_t ib; -}; - /* Transaction implementation of svn_wc__db_pristine_transfer(). - Calls itself again to obtain locks in both working copies */ + We have a lock on DST_WCROOT and a lock on SRC_WCROOT. + + Outputs: + *TEMPFILE_ABSPATH is the path to the source file that is to be moved + into place. + *PRISTINE_ABSPATH is the target path for the file (within the pristine + store). + *SHA1_CHECKSUM is the pristine text's SHA-1 checksum. + *MD5_CHECKSUM is the pristine text's MD-5 checksum. + + If there is nothing to transfer (it is not found in the source, or is + already in the destination), then set *TEMPFILE_ABSPATH_P to NULL. + */ static svn_error_t * -pristine_transfer(void *baton, svn_wc__db_wcroot_t *wcroot, - const char *local_relpath, apr_pool_t *scratch_pool) +pristine_transfer_txn2(const char **tempfile_abspath, + const char **pristine_abspath, + const svn_checksum_t **sha1_checksum, + const svn_checksum_t **md5_checksum, + svn_wc__db_wcroot_t *src_wcroot, + svn_wc__db_wcroot_t *dst_wcroot, + const char *src_relpath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool) { - struct pristine_transfer_baton *tb = baton; svn_sqlite__stmt_t *stmt; svn_boolean_t have_row; - /* Is this the initial call or the recursive call? */ - if (wcroot == tb->dst_wcroot) - { - /* The initial call: */ - - /* Get all the info within a src wcroot lock */ - SVN_ERR(svn_wc__db_with_txn(tb->src_wcroot, local_relpath, - pristine_transfer, tb, scratch_pool)); - - /* And do the final install, while we still have the dst lock */ - if (tb->ib.tempfile_abspath) - SVN_ERR(pristine_install_txn(&(tb->ib), tb->dst_wcroot->sdb, - scratch_pool)); - return SVN_NO_ERROR; - } - - /* We have a lock on tb->dst_wcroot and tb->src_wcroot */ - - /* Get the right checksum if it wasn't passed */ - if (!tb->ib.sha1_checksum) - { - SVN_ERR(svn_sqlite__get_statement(&stmt, tb->src_wcroot->sdb, - STMT_SELECT_NODE_INFO)); - - SVN_ERR(svn_sqlite__bindf(stmt, "is", - tb->src_wcroot->wc_id, local_relpath)); - - SVN_ERR(svn_sqlite__step(&have_row, stmt)); - - if (have_row) - SVN_ERR(svn_sqlite__column_checksum(&(tb->ib.sha1_checksum), stmt, 6, - scratch_pool)); + *tempfile_abspath = NULL; - SVN_ERR(svn_sqlite__reset(stmt)); + /* Get the SHA1 checksum */ + SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb, + STMT_SELECT_NODE_INFO)); + SVN_ERR(svn_sqlite__bindf(stmt, "is", + src_wcroot->wc_id, src_relpath)); + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + if (have_row) + SVN_ERR(svn_sqlite__column_checksum(sha1_checksum, stmt, 6, + scratch_pool)); + SVN_ERR(svn_sqlite__reset(stmt)); - if (!tb->ib.sha1_checksum) - return SVN_NO_ERROR; /* Nothing to transfer */ - } + if (! *sha1_checksum) + return SVN_NO_ERROR; /* Nothing to transfer */ /* Check if we have the pristine in the destination wcroot */ - SVN_ERR(svn_sqlite__get_statement(&stmt, tb->dst_wcroot->sdb, + SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb, STMT_SELECT_PRISTINE)); - SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, tb->ib.sha1_checksum, + SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, *sha1_checksum, scratch_pool)); SVN_ERR(svn_sqlite__step(&have_row, stmt)); SVN_ERR(svn_sqlite__reset(stmt)); @@ -597,9 +558,9 @@ pristine_transfer(void *baton, svn_wc__d return SVN_NO_ERROR; /* Verify if the pristine actually exists and get the MD5 in one query */ - SVN_ERR(svn_sqlite__get_statement(&stmt, tb->src_wcroot->sdb, + SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb, STMT_SELECT_PRISTINE)); - SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, tb->ib.sha1_checksum, + SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, *sha1_checksum, scratch_pool)); SVN_ERR(svn_sqlite__step(&have_row, stmt)); @@ -609,13 +570,13 @@ pristine_transfer(void *baton, svn_wc__d _("The pristine text with checksum '%s' was " "not found"), svn_checksum_to_cstring_display( - tb->ib.sha1_checksum, scratch_pool)); + *sha1_checksum, scratch_pool)); } - SVN_ERR(svn_sqlite__column_checksum(&(tb->ib.md5_checksum), stmt, 0, + SVN_ERR(svn_sqlite__column_checksum(md5_checksum, stmt, 0, scratch_pool)); SVN_ERR(svn_sqlite__reset(stmt)); - /* We now have read locks in both working copies, so we can safely copy the + /* We have read locks in both working copies, so we can safely copy the file to the temp location of the destination working copy */ { svn_stream_t *src_stream; @@ -624,14 +585,14 @@ pristine_transfer(void *baton, svn_wc__d const char *src_abspath; SVN_ERR(svn_stream_open_unique(&dst_stream, &tmp_abspath, - pristine_get_tempdir(tb->dst_wcroot, + pristine_get_tempdir(dst_wcroot, scratch_pool, scratch_pool), svn_io_file_del_on_pool_cleanup, scratch_pool, scratch_pool)); - SVN_ERR(get_pristine_fname(&src_abspath, tb->src_wcroot->abspath, - tb->ib.sha1_checksum, + SVN_ERR(get_pristine_fname(&src_abspath, src_wcroot->abspath, + *sha1_checksum, scratch_pool, scratch_pool)); SVN_ERR(svn_stream_open_readonly(&src_stream, src_abspath, @@ -639,56 +600,86 @@ pristine_transfer(void *baton, svn_wc__d /* ### Should we verify the SHA1 or MD5 here, or is that too expensive? */ SVN_ERR(svn_stream_copy3(src_stream, dst_stream, - tb->cancel_func, tb->cancel_baton, + cancel_func, cancel_baton, scratch_pool)); /* And now set the right information to install once we leave the src transaction */ - SVN_ERR(get_pristine_fname(&(tb->ib.pristine_abspath), - tb->dst_wcroot->abspath, - tb->ib.sha1_checksum, + SVN_ERR(get_pristine_fname(pristine_abspath, + dst_wcroot->abspath, + *sha1_checksum, scratch_pool, scratch_pool)); - tb->ib.tempfile_abspath = tmp_abspath; + *tempfile_abspath = tmp_abspath; } return SVN_NO_ERROR; } +/* Transaction implementation of svn_wc__db_pristine_transfer(). + We have a lock on DST_WCROOT. + */ +static svn_error_t * +pristine_transfer_txn1(svn_wc__db_wcroot_t *src_wcroot, + svn_wc__db_wcroot_t *dst_wcroot, + const char *src_relpath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool) +{ + const char *tempfile_abspath; + const char *pristine_abspath; + const svn_checksum_t *sha1_checksum; + const svn_checksum_t *md5_checksum; + + /* Get all the info within a src wcroot lock */ + SVN_WC__DB_WITH_TXN( + pristine_transfer_txn2(&tempfile_abspath, &pristine_abspath, + &sha1_checksum, &md5_checksum, + src_wcroot, dst_wcroot, src_relpath, + cancel_func, cancel_baton, scratch_pool), + src_wcroot); + + /* And do the final install, while we still have the dst lock */ + if (tempfile_abspath) + SVN_ERR(pristine_install_txn(dst_wcroot->sdb, + tempfile_abspath, pristine_abspath, + sha1_checksum, md5_checksum, + scratch_pool)); + return SVN_NO_ERROR; +} + svn_error_t * svn_wc__db_pristine_transfer(svn_wc__db_t *db, const char *src_local_abspath, - const svn_checksum_t *checksum, const char *dst_wri_abspath, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *scratch_pool) { - const char *src_relpath; - const char *dst_relpath; - struct pristine_transfer_baton tb; - memset(&tb, 0, sizeof(tb)); + svn_wc__db_wcroot_t *src_wcroot, *dst_wcroot; + const char *src_relpath, *dst_relpath; - SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&tb.src_wcroot, &src_relpath, + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&src_wcroot, &src_relpath, db, src_local_abspath, scratch_pool, scratch_pool)); - VERIFY_USABLE_WCROOT(tb.src_wcroot); - SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&tb.dst_wcroot, &dst_relpath, + VERIFY_USABLE_WCROOT(src_wcroot); + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&dst_wcroot, &dst_relpath, db, dst_wri_abspath, scratch_pool, scratch_pool)); - VERIFY_USABLE_WCROOT(tb.dst_wcroot); + VERIFY_USABLE_WCROOT(dst_wcroot); - if (tb.src_wcroot == tb.dst_wcroot - || tb.src_wcroot->sdb == tb.dst_wcroot->sdb) + if (src_wcroot == dst_wcroot + || src_wcroot->sdb == dst_wcroot->sdb) { return SVN_NO_ERROR; /* Nothing to transfer */ } - tb.cancel_func = cancel_func; - tb.cancel_baton = cancel_baton; + SVN_WC__DB_WITH_TXN( + pristine_transfer_txn1(src_wcroot, dst_wcroot, src_relpath, + cancel_func, cancel_baton, scratch_pool), + dst_wcroot); - return svn_error_trace(svn_wc__db_with_txn(tb.dst_wcroot, src_relpath, - pristine_transfer, &tb, - scratch_pool)); + return SVN_NO_ERROR; } @@ -730,36 +721,27 @@ remove_file(const char *file_abspath, return SVN_NO_ERROR; } -/* Data for pristine_remove_if_unreferenced_txn(). */ -typedef struct pristine_remove_baton_t -{ - svn_wc__db_wcroot_t *wcroot; - /* The pristine text's SHA-1 checksum. */ - const svn_checksum_t *sha1_checksum; - /* The path to the pristine file (within the pristine store). */ - const char *pristine_abspath; -} pristine_remove_baton_t; - -/* If the pristine text referenced by BATON in SDB has a reference count of +/* If the pristine text referenced by SHA1_CHECKSUM in WCROOT/SDB, whose path + * within the pristine store is PRISTINE_ABSPATH, has a reference count of * zero, delete it (both the database row and the disk file). * * This function expects to be executed inside a SQLite txn that has already * acquired a 'RESERVED' lock. - * - * Implements svn_sqlite__transaction_callback_t. */ + */ static svn_error_t * -pristine_remove_if_unreferenced_txn(void *baton, - svn_sqlite__db_t *sdb, +pristine_remove_if_unreferenced_txn(svn_sqlite__db_t *sdb, + svn_wc__db_wcroot_t *wcroot, + const svn_checksum_t *sha1_checksum, + const char *pristine_abspath, apr_pool_t *scratch_pool) { - pristine_remove_baton_t *b = baton; svn_sqlite__stmt_t *stmt; int affected_rows; /* Remove the DB row, if refcount is 0. */ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_PRISTINE_IF_UNREFERENCED)); - SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, scratch_pool)); + SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool)); SVN_ERR(svn_sqlite__update(&affected_rows, stmt)); /* If we removed the DB row, then remove the file. */ @@ -774,7 +756,7 @@ pristine_remove_if_unreferenced_txn(void svn_boolean_t ignore_enoent = TRUE; #endif - SVN_ERR(remove_file(b->pristine_abspath, b->wcroot, ignore_enoent, + SVN_ERR(remove_file(pristine_abspath, wcroot, ignore_enoent, scratch_pool)); } @@ -791,17 +773,17 @@ pristine_remove_if_unreferenced(svn_wc__ const svn_checksum_t *sha1_checksum, apr_pool_t *scratch_pool) { - pristine_remove_baton_t b; + const char *pristine_abspath; - b.wcroot = wcroot; - b.sha1_checksum = sha1_checksum; - SVN_ERR(get_pristine_fname(&b.pristine_abspath, wcroot->abspath, + SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath, sha1_checksum, scratch_pool, scratch_pool)); /* Ensure the SQL txn has at least a 'RESERVED' lock before we start looking * at the disk, to ensure no concurrent pristine install/delete txn. */ - SVN_ERR(svn_sqlite__with_immediate_transaction( - wcroot->sdb, pristine_remove_if_unreferenced_txn, &b, scratch_pool)); + SVN_SQLITE__WITH_IMMEDIATE_TXN( + pristine_remove_if_unreferenced_txn( + wcroot->sdb, wcroot, sha1_checksum, pristine_abspath, scratch_pool), + wcroot->sdb); return SVN_NO_ERROR; } Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_private.h URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_private.h?rev=1429457&r1=1429456&r2=1429457&view=diff ============================================================================== --- subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_private.h (original) +++ subversion/branches/tree-read-api/subversion/libsvn_wc/wc_db_private.h Sun Jan 6 02:33:34 2013 @@ -96,7 +96,7 @@ typedef struct svn_wc__db_wcroot_t { Typically just one or two locks maximum. */ apr_array_header_t *owned_locks; - /* Map a working copy diretory to a cached adm_access baton. + /* Map a working copy directory to a cached adm_access baton. const char *local_abspath -> svn_wc_adm_access_t *adm_access */ apr_hash_t *access_cache; @@ -254,6 +254,7 @@ svn_wc__db_base_get_info_internal(svn_wc const char **target, svn_wc__db_lock_t **lock, svn_boolean_t *had_props, + apr_hash_t **props, svn_boolean_t *update_root, svn_wc__db_wcroot_t *wcroot, const char *local_relpath, @@ -262,7 +263,18 @@ svn_wc__db_base_get_info_internal(svn_wc /* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH * instead of DB+LOCAL_ABSPATH, an explicit op-depth of the node to get - * information about, and outputting REPOS_ID instead of URL+UUID. */ + * information about, and outputting REPOS_ID instead of URL+UUID, and + * without the LOCK or UPDATE_ROOT outputs. + * + * OR + * + * Similar to svn_wc__db_base_get_info_internal(), but taking an explicit + * op-depth OP_DEPTH of the node to get information about, and without the + * LOCK or UPDATE_ROOT outputs. + * + * ### [JAF] TODO: Harmonize svn_wc__db_base_get_info[_internal] with + * svn_wc__db_depth_get_info -- common API, common implementation. + */ svn_error_t * svn_wc__db_depth_get_info(svn_wc__db_status_t *status, svn_kind_t *kind, @@ -276,6 +288,7 @@ svn_wc__db_depth_get_info(svn_wc__db_sta const svn_checksum_t **checksum, const char **target, svn_boolean_t *had_props, + apr_hash_t **props, svn_wc__db_wcroot_t *wcroot, const char *local_relpath, int op_depth, @@ -291,6 +304,14 @@ svn_wc__db_read_conflict_internal(svn_sk apr_pool_t *result_pool, apr_pool_t *scratch_pool); +/* Like svn_wc__db_op_mark_conflict(), but with WCROOT+LOCAL_RELPATH instead of + DB+LOCAL_ABSPATH. */ +svn_error_t * +svn_wc__db_mark_conflict_internal(svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + const svn_skel_t *conflict_skel, + apr_pool_t *scratch_pool); + /* Transaction handling */ @@ -311,5 +332,39 @@ svn_wc__db_with_txn(svn_wc__db_wcroot_t void *cb_baton, apr_pool_t *scratch_pool); +/* Evaluate the expression EXPR within a transaction. + * + * Begin a transaction in WCROOT's DB; evaluate the expression EXPR, which would + * typically be a function call that does some work in DB; finally commit + * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back + * the transaction. + */ +#define SVN_WC__DB_WITH_TXN(expr, wcroot) \ + SVN_SQLITE__WITH_LOCK(expr, (wcroot)->sdb) + + +/* Return CHILDREN mapping const char * names to svn_kind_t * for the + children of LOCAL_RELPATH at OP_DEPTH. */ +svn_error_t * +svn_wc__db_get_children_op_depth(apr_hash_t **children, + svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + int op_depth, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +svn_error_t * +svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + svn_kind_t kind, + int op_depth, + apr_pool_t *scratch_pool); + +svn_error_t * +svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + int op_depth, + apr_pool_t *scratch_pool); #endif /* WC_DB_PRIVATE_H */
