Modified: subversion/branches/authzperf/subversion/libsvn_subr/gpg_agent.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/gpg_agent.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/gpg_agent.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/gpg_agent.c Sat Jan 3 14:00:41 2015 @@ -108,7 +108,7 @@ escape_blanks(char *str) * to other password caching mechanisms. */ static svn_error_t * get_cache_id(const char **cache_id_p, const char *realmstring, - apr_pool_t *scratch_pool, apr_pool_t *result_pool) + apr_pool_t *result_pool, apr_pool_t *scratch_pool) { const char *cache_id = NULL; svn_checksum_t *digest = NULL;
Modified: subversion/branches/authzperf/subversion/libsvn_subr/io.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/io.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/io.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/io.c Sat Jan 3 14:00:41 2015 @@ -3662,7 +3662,7 @@ svn_io_file_aligned_seek(apr_file_t *fil buffer and no I/O will actually happen in the FILL_BUFFER section below. */ - SVN_ERR(svn_io_file_seek(file, SEEK_CUR, ¤t, pool)); + SVN_ERR(svn_io_file_seek(file, APR_CUR, ¤t, pool)); fill_buffer = aligned_offset + file_buffer_size <= current || current <= aligned_offset; } @@ -3673,7 +3673,7 @@ svn_io_file_aligned_seek(apr_file_t *fil apr_status_t status; /* seek to the start of the block and cause APR to read 1 block */ - SVN_ERR(svn_io_file_seek(file, SEEK_SET, &aligned_offset, pool)); + SVN_ERR(svn_io_file_seek(file, APR_SET, &aligned_offset, pool)); status = apr_file_getc(&dummy, file); /* read may fail if we seek to or behind EOF. That's ok then. */ @@ -3686,7 +3686,7 @@ svn_io_file_aligned_seek(apr_file_t *fil /* finally, seek to the OFFSET the caller wants */ desired_offset = offset; - SVN_ERR(svn_io_file_seek(file, SEEK_SET, &offset, pool)); + SVN_ERR(svn_io_file_seek(file, APR_SET, &offset, pool)); if (desired_offset != offset) return do_io_file_wrapper_cleanup(file, APR_EOF, N_("Can't seek in file '%s'"), Modified: subversion/branches/authzperf/subversion/libsvn_subr/mergeinfo.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/mergeinfo.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/mergeinfo.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/mergeinfo.c Sat Jan 3 14:00:41 2015 @@ -99,9 +99,6 @@ parse_pathname(const char **input, if (!last_colon) return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL, _("Pathname not terminated by ':'")); - if (last_colon == *input) - return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL, - _("No pathname preceding ':'")); /* Tolerate relative repository paths, but convert them to absolute. ### Efficiency? 1 string duplication here, 2 in canonicalize. */ @@ -612,7 +609,12 @@ svn_rangelist__parse(svn_rangelist_t **r } /* Return TRUE, if all ranges in RANGELIST are in ascending order and do - * not overlap. If this returns FALSE, you probaly want to qsort() the + * not overlap and are not adjacent. + * + * ### Can yield false negatives: ranges of differing inheritance are + * allowed to be adjacent. + * + * If this returns FALSE, you probaly want to qsort() the * ranges and then call svn_rangelist__combine_adjacent_ranges(). */ static svn_boolean_t @@ -629,6 +631,20 @@ is_rangelist_normalized(svn_rangelist_t } svn_error_t * +svn_rangelist__canonicalize(svn_rangelist_t *rangelist, + apr_pool_t *scratch_pool) +{ + if (! is_rangelist_normalized(rangelist)) + { + svn_sort__array(rangelist, svn_sort_compare_ranges); + + SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool)); + } + + return SVN_NO_ERROR; +} + +svn_error_t * svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist, apr_pool_t *scratch_pool) { @@ -715,14 +731,9 @@ parse_revision_line(const char **input, /* Sort the rangelist, combine adjacent ranges into single ranges, and make sure there are no overlapping ranges. Luckily, most data in - svn:mergeinfo will already be in normalized form and we can skip this. + svn:mergeinfo will already be in normalized form and this will be quick. */ - if (! is_rangelist_normalized(rangelist)) - { - svn_sort__array(rangelist, svn_sort_compare_ranges); - - SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool)); - } + SVN_ERR(svn_rangelist__canonicalize(rangelist, scratch_pool)); /* Handle any funky mergeinfo with relative merge source paths that might exist due to issue #3547. It's possible that this issue allowed @@ -1999,6 +2010,22 @@ svn_mergeinfo_sort(svn_mergeinfo_t input return SVN_NO_ERROR; } +svn_error_t * +svn_mergeinfo__canonicalize_ranges(svn_mergeinfo_t mergeinfo, + apr_pool_t *scratch_pool) +{ + apr_hash_index_t *hi; + + for (hi = apr_hash_first(scratch_pool, mergeinfo); hi; hi = apr_hash_next(hi)) + { + apr_array_header_t *rl = apr_hash_this_val(hi); + + SVN_ERR(svn_rangelist__canonicalize(rl, scratch_pool)); + } + + return SVN_NO_ERROR; +} + svn_mergeinfo_catalog_t svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog, apr_pool_t *pool) Modified: subversion/branches/authzperf/subversion/libsvn_subr/opt.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/opt.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/opt.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/opt.c Sat Jan 3 14:00:41 2015 @@ -1012,13 +1012,6 @@ svn_opt__split_arg_at_peg_revision(const if (peg_start) { - /* Error out if target is the empty string. */ - if (ptr == utf8_target) - return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL, - _("'%s' is just a peg revision. " - "Maybe try '%s@' instead?"), - utf8_target, utf8_target); - *true_target = apr_pstrmemdup(pool, utf8_target, ptr - utf8_target); if (peg_revision) *peg_revision = apr_pstrdup(pool, peg_start); Modified: subversion/branches/authzperf/subversion/libsvn_subr/packed_data.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/packed_data.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/packed_data.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/packed_data.c Sat Jan 3 14:00:41 2015 @@ -276,6 +276,33 @@ write_packed_uint_body(unsigned char *bu return buffer; } +/* Return remapped VALUE. + * + * Due to sign conversion and diff underflow, values close to UINT64_MAX + * are almost as frequent as those close to 0. Remap them such that the + * MSB is stored in the LSB and the remainder stores the absolute distance + * to 0. + * + * This minimizes the absolute value to store in many scenarios. + * Hence, the variable-length representation on disk is shorter, too. + */ +static apr_uint64_t +remap_uint(apr_uint64_t value) +{ + return value & APR_UINT64_C(0x8000000000000000) + ? APR_UINT64_MAX - (2 * value) + : 2 * value; +} + +/* Invert remap_uint. */ +static apr_uint64_t +unmap_uint(apr_uint64_t value) +{ + return value & 1 + ? (APR_UINT64_MAX - value / 2) + : value / 2; +} + /* Empty the unprocessed integer buffer in STREAM by either pushing the * data to the sub-streams or writing to the packed data (in case there * are no sub-streams). @@ -313,8 +340,7 @@ svn_packed__data_flush_buffer(svn_packed for (i = 0; i < stream->buffer_used; ++i) { apr_uint64_t temp = stream->buffer[i]; - apr_int64_t diff = (apr_int64_t)(temp - last_value); - stream->buffer[i] = diff < 0 ? -1 - 2 * diff : 2 * diff; + stream->buffer[i] = remap_uint(temp - last_value); last_value = temp; } @@ -327,9 +353,7 @@ svn_packed__data_flush_buffer(svn_packed 63 bits. */ if (!private_data->diff && private_data->is_signed) for (i = 0; i < stream->buffer_used; ++i) - stream->buffer[i] = (apr_int64_t)stream->buffer[i] < 0 - ? -1 - 2 * stream->buffer[i] - : 2 * stream->buffer[i]; + stream->buffer[i] = remap_uint(stream->buffer[i]); /* auto-create packed data buffer. Give it some reasonable initial size - just enough for a few tens of values. */ @@ -771,8 +795,8 @@ svn_packed__data_fill_buffer(svn_packed_ else { /* use this local buffer only if the packed data is shorter than this. - The goal is that we don't need to check for overflows that is not - detected by read_packed_uint_body. */ + The goal is that read_packed_uint_body doesn't need check for + overflows. */ unsigned char local_buffer[10 * SVN__PACKED_DATA_BUFFER_SIZE]; unsigned char *p; unsigned char *start; @@ -808,9 +832,7 @@ svn_packed__data_fill_buffer(svn_packed_ apr_uint64_t last_value = private_data->last_value; for (i = end; i > 0; --i) { - apr_uint64_t temp = stream->buffer[i-1]; - temp = (temp % 2) ? -1 - temp / 2 : temp / 2; - last_value += temp; + last_value += unmap_uint(stream->buffer[i-1]); stream->buffer[i-1] = last_value; } @@ -820,9 +842,7 @@ svn_packed__data_fill_buffer(svn_packed_ /* handle signed values, if configured and not handled already */ if (!private_data->diff && private_data->is_signed) for (i = 0; i < end; ++i) - stream->buffer[i] = (stream->buffer[i] % 2) - ? -1 - stream->buffer[i] / 2 - : stream->buffer[i] / 2; + stream->buffer[i] = unmap_uint(stream->buffer[i]); } stream->buffer_used = end; Modified: subversion/branches/authzperf/subversion/libsvn_subr/path.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/path.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/path.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/path.c Sat Jan 3 14:00:41 2015 @@ -1299,7 +1299,7 @@ svn_path_resolve_repos_relative_url(cons _("Improper relative URL '%s'"), relative_url); - /* No assumptions are made about the canonicalization of the inut + /* No assumptions are made about the canonicalization of the input * arguments, it is presumed that the output will be canonicalized after * this function, which will remove any duplicate path separator. */ Modified: subversion/branches/authzperf/subversion/libsvn_subr/stream.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/stream.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/stream.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/stream.c Sat Jan 3 14:00:41 2015 @@ -78,17 +78,8 @@ svn_stream_create(void *baton, apr_pool_ { svn_stream_t *stream; - stream = apr_palloc(pool, sizeof(*stream)); + stream = apr_pcalloc(pool, sizeof(*stream)); stream->baton = baton; - stream->read_fn = NULL; - stream->skip_fn = NULL; - stream->write_fn = NULL; - stream->close_fn = NULL; - stream->mark_fn = NULL; - stream->seek_fn = NULL; - stream->data_available_fn = NULL; - stream->is_buffered_fn = NULL; - stream->file = NULL; return stream; } @@ -1089,16 +1080,13 @@ svn_stream__aprfile(svn_stream_t *stream struct zbaton { z_stream *in; /* compressed stream for reading */ z_stream *out; /* compressed stream for writing */ - svn_read_fn_t read; /* substream's read function */ - svn_write_fn_t write; /* substream's write function */ - svn_close_fn_t close; /* substream's close function */ + void *substream; /* The substream */ void *read_buffer; /* buffer used for reading from substream */ int read_flush; /* what flush mode to use while reading */ apr_pool_t *pool; /* The pool this baton is allocated on */ - void *subbaton; /* The substream's baton */ }; /* zlib alloc function. opaque is the pool we need. */ @@ -1119,8 +1107,7 @@ zfree(voidpf opaque, voidpf address) /* Helper function to figure out the sync mode */ static svn_error_t * -read_helper_gz(svn_read_fn_t read_fn, - void *baton, +read_helper_gz(svn_stream_t *substream, char *buffer, uInt *len, int *zflush) { @@ -1130,7 +1117,7 @@ read_helper_gz(svn_read_fn_t read_fn, uInt, but Subversion's API requires apr_size_t. */ apr_size_t apr_len = (apr_size_t) *len; - SVN_ERR((*read_fn)(baton, buffer, &apr_len)); + SVN_ERR(svn_stream_read_full(substream, buffer, &apr_len)); /* Type cast back to uInt type that zlib uses. On LP64 platforms apr_size_t will be bigger than uInt. */ @@ -1160,7 +1147,7 @@ read_handler_gz(void *baton, char *buffe btn->in->next_in = btn->read_buffer; btn->in->avail_in = ZBUFFER_SIZE; - SVN_ERR(read_helper_gz(btn->read, btn->subbaton, btn->read_buffer, + SVN_ERR(read_helper_gz(btn->substream, btn->read_buffer, &btn->in->avail_in, &btn->read_flush)); zerr = inflateInit(btn->in); @@ -1176,7 +1163,7 @@ read_handler_gz(void *baton, char *buffe { btn->in->avail_in = ZBUFFER_SIZE; btn->in->next_in = btn->read_buffer; - SVN_ERR(read_helper_gz(btn->read, btn->subbaton, btn->read_buffer, + SVN_ERR(read_helper_gz(btn->substream, btn->read_buffer, &btn->in->avail_in, &btn->read_flush)); } @@ -1238,7 +1225,7 @@ write_handler_gz(void *baton, const char SVN_ERR(svn_error__wrap_zlib(zerr, "deflate", btn->out->msg)); write_len = buf_size - btn->out->avail_out; if (write_len > 0) - SVN_ERR(btn->write(btn->subbaton, write_buf, &write_len)); + SVN_ERR(svn_stream_write(btn->substream, write_buf, &write_len)); } svn_pool_destroy(subpool); @@ -1277,7 +1264,7 @@ close_handler_gz(void *baton) btn->out->msg)); write_len = ZBUFFER_SIZE - btn->out->avail_out; if (write_len > 0) - SVN_ERR(btn->write(btn->subbaton, buf, &write_len)); + SVN_ERR(svn_stream_write(btn->substream, buf, &write_len)); if (zerr == Z_STREAM_END) break; } @@ -1286,10 +1273,7 @@ close_handler_gz(void *baton) SVN_ERR(svn_error__wrap_zlib(zerr, "deflateEnd", btn->out->msg)); } - if (btn->close != NULL) - return svn_error_trace(btn->close(btn->subbaton)); - else - return SVN_NO_ERROR; + return svn_error_trace(svn_stream_close(btn->substream)); } @@ -1303,10 +1287,7 @@ svn_stream_compressed(svn_stream_t *stre baton = apr_palloc(pool, sizeof(*baton)); baton->in = baton->out = NULL; - baton->read = stream->read_fn; - baton->write = stream->write_fn; - baton->close = stream->close_fn; - baton->subbaton = stream->baton; + baton->substream = stream; baton->pool = pool; baton->read_buffer = NULL; baton->read_flush = Z_SYNC_FLUSH; Modified: subversion/branches/authzperf/subversion/libsvn_subr/string.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/string.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/string.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/string.c Sat Jan 3 14:00:41 2015 @@ -26,6 +26,7 @@ #include <apr.h> +#include <assert.h> #include <string.h> /* for memcpy(), memcmp(), strlen() */ #include <apr_fnmatch.h> @@ -239,7 +240,9 @@ svn_string_ncreate(const char *bytes, ap new_string->data = data; new_string->len = size; - memcpy(data, bytes, size); + /* If SIZE is 0, NULL is valid for BYTES. */ + if (size) + memcpy(data, bytes, size); /* Null termination is the convention -- even if we suspect the data to be binary, it's not up to us to decide, it's the caller's @@ -392,7 +395,10 @@ svn_stringbuf_t * svn_stringbuf_ncreate(const char *bytes, apr_size_t size, apr_pool_t *pool) { svn_stringbuf_t *strbuf = svn_stringbuf_create_ensure(size, pool); - memcpy(strbuf->data, bytes, size); + + /* If SIZE is 0, NULL is valid for BYTES. */ + if (size) + memcpy(strbuf->data, bytes, size); /* Null termination is the convention -- even if we suspect the data to be binary, it's not up to us to decide, it's the caller's @@ -608,6 +614,10 @@ svn_stringbuf_appendbytes(svn_stringbuf_ apr_size_t total_len; void *start_address; + if (!count) + /* Allow BYTES to be NULL by avoiding passing it to memcpy. */ + return; + total_len = str->len + count; /* total size needed */ /* svn_stringbuf_ensure adds 1 for null terminator. */ @@ -660,6 +670,10 @@ svn_stringbuf_insert(svn_stringbuf_t *st const char *bytes, apr_size_t count) { + /* For COUNT==0, we allow BYTES to be NULL. It's a no-op in that case. */ + if (count == 0) + return; + if (bytes + count > str->data && bytes < str->data + str->blocksize) { /* special case: BYTES overlaps with this string -> copy the source */ @@ -700,6 +714,14 @@ svn_stringbuf_replace(svn_stringbuf_t *s const char *bytes, apr_size_t new_count) { + /* For COUNT==0, we allow BYTES to be NULL. + * In that case, this is just a substring removal. */ + if (new_count == 0) + { + svn_stringbuf_remove(str, pos, old_count); + return; + } + if (bytes + new_count > str->data && bytes < str->data + str->blocksize) { /* special case: BYTES overlaps with this string -> copy the source */ @@ -1253,7 +1275,7 @@ svn__i64toa(char * dest, apr_int64_t num return svn__ui64toa(dest, (apr_uint64_t)number); *dest = '-'; - return svn__ui64toa(dest + 1, (apr_uint64_t)(0-number)) + 1; + return svn__ui64toa(dest + 1, 0 - (apr_uint64_t)number) + 1; } static void Modified: subversion/branches/authzperf/subversion/libsvn_subr/subst.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/subst.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/subst.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/subst.c Sat Jan 3 14:00:41 2015 @@ -159,7 +159,7 @@ keyword_printf(const char *fmt, const char *author, apr_pool_t *pool) { - svn_stringbuf_t *value = svn_stringbuf_ncreate("", 0, pool); + svn_stringbuf_t *value = svn_stringbuf_create_empty(pool); const char *cur; size_t n; Modified: subversion/branches/authzperf/subversion/libsvn_subr/sysinfo.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/sysinfo.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/sysinfo.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/sysinfo.c Sat Jan 3 14:00:41 2015 @@ -940,6 +940,7 @@ system_version_plist(svn_boolean_t *serv if (!APR_STATUS_IS_ENOENT(err->apr_err)) { svn_error_clear(err); + CFRelease(resource); return NULL; } else @@ -950,6 +951,7 @@ system_version_plist(svn_boolean_t *serv if (err) { svn_error_clear(err); + CFRelease(resource); return NULL; } @@ -1042,16 +1044,17 @@ release_name_from_version(const char *os /* See http://en.wikipedia.org/wiki/History_of_OS_X#Release_timeline */ switch(num) { - case 0: return "Cheetah"; - case 1: return "Puma"; - case 2: return "Jaguar"; - case 3: return "Panther"; - case 4: return "Tiger"; - case 5: return "Leopard"; - case 6: return "Snow Leopard"; - case 7: return "Lion"; - case 8: return "Mountain Lion"; - case 9: return "Mavericks"; + case 0: return "Cheetah"; + case 1: return "Puma"; + case 2: return "Jaguar"; + case 3: return "Panther"; + case 4: return "Tiger"; + case 5: return "Leopard"; + case 6: return "Snow Leopard"; + case 7: return "Lion"; + case 8: return "Mountain Lion"; + case 9: return "Mavericks"; + case 10: return "Yosemite"; } return NULL; Propchange: subversion/branches/authzperf/subversion/libsvn_subr/utf8proc/README ------------------------------------------------------------------------------ svn:eol-style = native Modified: subversion/branches/authzperf/subversion/libsvn_wc/adm_ops.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/adm_ops.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_wc/adm_ops.c (original) +++ subversion/branches/authzperf/subversion/libsvn_wc/adm_ops.c Sat Jan 3 14:00:41 2015 @@ -63,23 +63,23 @@ struct svn_wc_committed_queue_t { /* The pool in which ->queue is allocated. */ apr_pool_t *pool; - /* Mapping (const char *) local_abspath to (committed_queue_item_t *). */ - apr_hash_t *queue; - /* Is any item in the queue marked as 'recursive'? */ - svn_boolean_t have_recursive; + /* Mapping (const char *) wcroot_abspath to svn_wc__db_commit_queue_t * */ + apr_hash_t *wc_queues; }; typedef struct committed_queue_item_t { const char *local_abspath; - svn_boolean_t recurse; - svn_boolean_t no_unlock; - svn_boolean_t keep_changelist; + svn_boolean_t recurse; /* Use legacy recursion */ + svn_boolean_t committed; /* Process the node as committed */ + svn_boolean_t remove_lock; /* Remove existing lock on node */ + svn_boolean_t remove_changelist; /* Remove changelist on node */ + + /* The pristine text checksum. NULL if the old value should be kept + and for directories */ + const svn_checksum_t *new_sha1_checksum; - /* The pristine text checksum. */ - const svn_checksum_t *sha1_checksum; - - apr_hash_t *new_dav_cache; + apr_hash_t *new_dav_cache; /* New DAV cache for the node */ } committed_queue_item_t; @@ -89,245 +89,6 @@ svn_wc__get_committed_queue_pool(const s return queue->pool; } - - -/*** Finishing updates and commits. ***/ - -/* Queue work items that will finish a commit of the file or directory - * LOCAL_ABSPATH in DB: - * - queue the removal of any "revert-base" props and text files; - * - queue an update of the DB entry for this node - * - * ### The Pristine Store equivalent should be: - * - remember the old BASE_NODE and WORKING_NODE pristine text c'sums; - * - queue an update of the DB entry for this node (incl. updating the - * BASE_NODE c'sum and setting the WORKING_NODE c'sum to NULL); - * - queue deletion of the old pristine texts by the remembered checksums. - * - * CHECKSUM is the checksum of the new text base for LOCAL_ABSPATH, and must - * be provided if there is one, else NULL. - * - * STATUS, KIND, PROP_MODS and OLD_CHECKSUM are the current in-db values of - * the node LOCAL_ABSPATH. - */ -static svn_error_t * -process_committed_leaf(svn_wc__db_t *db, - const char *local_abspath, - svn_boolean_t via_recurse, - svn_wc__db_status_t status, - svn_node_kind_t kind, - svn_boolean_t prop_mods, - const svn_checksum_t *old_checksum, - svn_revnum_t new_revnum, - apr_time_t new_changed_date, - const char *new_changed_author, - apr_hash_t *new_dav_cache, - svn_boolean_t no_unlock, - svn_boolean_t keep_changelist, - const svn_checksum_t *checksum, - apr_pool_t *scratch_pool) -{ - svn_revnum_t new_changed_rev = new_revnum; - svn_skel_t *work_item = NULL; - - SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); - - { - const char *adm_abspath; - - if (kind == svn_node_dir) - adm_abspath = local_abspath; - else - adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool); - SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool)); - } - - if (status == svn_wc__db_status_deleted) - { - return svn_error_trace( - svn_wc__db_base_remove( - db, local_abspath, - FALSE /* keep_as_working */, - FALSE /* queue_deletes */, - TRUE /* remove_locks */, - (! via_recurse) - ? new_revnum : SVN_INVALID_REVNUM, - NULL, NULL, - scratch_pool)); - } - else if (status == svn_wc__db_status_not_present) - { - /* We are committing the leaf of a copy operation. - We leave the not-present marker to allow pulling in excluded - children of a copy. - - The next update will remove the not-present marker. */ - - return SVN_NO_ERROR; - } - - SVN_ERR_ASSERT(status == svn_wc__db_status_normal - || status == svn_wc__db_status_incomplete - || status == svn_wc__db_status_added); - - if (kind != svn_node_dir) - { - /* If we sent a delta (meaning: post-copy modification), - then this file will appear in the queue and so we should have - its checksum already. */ - if (checksum == NULL) - { - /* It was copied and not modified. We must have a text - base for it. And the node should have a checksum. */ - SVN_ERR_ASSERT(old_checksum != NULL); - - checksum = old_checksum; - - /* Is the node completely unmodified and are we recursing? */ - if (via_recurse && !prop_mods) - { - /* If a copied node itself is not modified, but the op_root of - the copy is committed we have to make sure that changed_rev, - changed_date and changed_author don't change or the working - copy used for committing will show different last modified - information then a clean checkout of exactly the same - revisions. (Issue #3676) */ - - SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, - NULL, &new_changed_rev, - &new_changed_date, - &new_changed_author, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - } - } - - SVN_ERR(svn_wc__wq_build_file_commit(&work_item, - db, local_abspath, - prop_mods, - scratch_pool, scratch_pool)); - } - - /* The new text base will be found in the pristine store by its checksum. */ - SVN_ERR(svn_wc__db_global_commit(db, local_abspath, - new_revnum, new_changed_rev, - new_changed_date, new_changed_author, - checksum, - NULL /* new_children */, - new_dav_cache, - keep_changelist, - no_unlock, - work_item, - scratch_pool)); - - return SVN_NO_ERROR; -} - - -svn_error_t * -svn_wc__process_committed_internal(svn_wc__db_t *db, - const char *local_abspath, - svn_boolean_t recurse, - svn_boolean_t top_of_recurse, - svn_revnum_t new_revnum, - apr_time_t new_date, - const char *rev_author, - apr_hash_t *new_dav_cache, - svn_boolean_t no_unlock, - svn_boolean_t keep_changelist, - const svn_checksum_t *sha1_checksum, - const svn_wc_committed_queue_t *queue, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - svn_node_kind_t kind; - const svn_checksum_t *old_checksum; - svn_boolean_t prop_mods; - - SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, &old_checksum, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, &prop_mods, NULL, NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - - /* NOTE: be wary of making crazy semantic changes in this function, since - svn_wc_process_committed4() calls this. */ - - SVN_ERR(process_committed_leaf(db, local_abspath, !top_of_recurse, - status, kind, prop_mods, old_checksum, - new_revnum, new_date, rev_author, - new_dav_cache, - no_unlock, keep_changelist, - sha1_checksum, - scratch_pool)); - - /* Only check for recursion on nodes that have children */ - if (kind != svn_node_file - || status == svn_wc__db_status_not_present - || status == svn_wc__db_status_excluded - || status == svn_wc__db_status_server_excluded - /* Node deleted -> then no longer a directory */ - || status == svn_wc__db_status_deleted) - { - return SVN_NO_ERROR; - } - - if (recurse) - { - const apr_array_header_t *children; - apr_pool_t *iterpool = svn_pool_create(scratch_pool); - int i; - - /* Read PATH's entries; this is the absolute path. */ - SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath, - scratch_pool, iterpool)); - - /* Recursively loop over all children. */ - for (i = 0; i < children->nelts; i++) - { - const char *name = APR_ARRAY_IDX(children, i, const char *); - const char *this_abspath; - const committed_queue_item_t *cqi; - - svn_pool_clear(iterpool); - - this_abspath = svn_dirent_join(local_abspath, name, iterpool); - - sha1_checksum = NULL; - cqi = svn_hash_gets(queue->queue, this_abspath); - - if (cqi != NULL) - sha1_checksum = cqi->sha1_checksum; - - /* Recurse. Pass NULL for NEW_DAV_CACHE, because the - ones present in the current call are only applicable to - this one committed item. */ - SVN_ERR(svn_wc__process_committed_internal( - db, this_abspath, - TRUE /* recurse */, - FALSE /* top_of_recurse */, - new_revnum, new_date, - rev_author, - NULL /* new_dav_cache */, - TRUE /* no_unlock */, - keep_changelist, - sha1_checksum, - queue, - iterpool)); - } - - svn_pool_destroy(iterpool); - } - - return SVN_NO_ERROR; -} - - apr_hash_t * svn_wc__prop_array_to_hash(const apr_array_header_t *props, apr_pool_t *result_pool) @@ -358,76 +119,56 @@ svn_wc_committed_queue_create(apr_pool_t q = apr_palloc(pool, sizeof(*q)); q->pool = pool; - q->queue = apr_hash_make(pool); - q->have_recursive = FALSE; + q->wc_queues = apr_hash_make(pool); return q; } svn_error_t * -svn_wc_queue_committed3(svn_wc_committed_queue_t *queue, +svn_wc_queue_committed4(svn_wc_committed_queue_t *queue, svn_wc_context_t *wc_ctx, const char *local_abspath, svn_boolean_t recurse, + svn_boolean_t is_committed, const apr_array_header_t *wcprop_changes, svn_boolean_t remove_lock, svn_boolean_t remove_changelist, const svn_checksum_t *sha1_checksum, apr_pool_t *scratch_pool) { - committed_queue_item_t *cqi; + const char *wcroot_abspath; + svn_wc__db_commit_queue_t *db_queue; SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); - queue->have_recursive |= recurse; - /* Use the same pool as the one QUEUE was allocated in, to prevent lifetime issues. Intermediate operations should use SCRATCH_POOL. */ - /* Add to the array with paths and options */ - cqi = apr_palloc(queue->pool, sizeof(*cqi)); - cqi->local_abspath = local_abspath; - cqi->recurse = recurse; - cqi->no_unlock = !remove_lock; - cqi->keep_changelist = !remove_changelist; - cqi->sha1_checksum = sha1_checksum; - cqi->new_dav_cache = svn_wc__prop_array_to_hash(wcprop_changes, queue->pool); - - svn_hash_sets(queue->queue, local_abspath, cqi); - - return SVN_NO_ERROR; -} - - -/* Return TRUE if any item of QUEUE is a parent of ITEM and will be - processed recursively, return FALSE otherwise. - - The algorithmic complexity of this search implementation is O(queue - length), but it's quite quick. -*/ -static svn_boolean_t -have_recursive_parent(apr_hash_t *queue, - const committed_queue_item_t *item, - apr_pool_t *scratch_pool) -{ - apr_hash_index_t *hi; - const char *local_abspath = item->local_abspath; + SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, + wc_ctx->db, local_abspath, + scratch_pool, scratch_pool)); - for (hi = apr_hash_first(scratch_pool, queue); hi; hi = apr_hash_next(hi)) + db_queue = svn_hash_gets(queue->wc_queues, wcroot_abspath); + if (! db_queue) { - const committed_queue_item_t *qi = apr_hash_this_val(hi); + wcroot_abspath = apr_pstrdup(queue->pool, wcroot_abspath); - if (qi == item) - continue; + SVN_ERR(svn_wc__db_create_commit_queue(&db_queue, + wc_ctx->db, wcroot_abspath, + queue->pool, scratch_pool)); - if (qi->recurse && svn_dirent_is_child(qi->local_abspath, local_abspath, - NULL)) - return TRUE; + svn_hash_sets(queue->wc_queues, wcroot_abspath, db_queue); } - return FALSE; + return svn_error_trace( + svn_wc__db_commit_queue_add(db_queue, local_abspath, recurse, + is_committed, remove_lock, + remove_changelist, sha1_checksum, + svn_wc__prop_array_to_hash(wcprop_changes, + queue->pool), + queue->pool, scratch_pool)); } @@ -441,75 +182,44 @@ svn_wc_process_committed_queue2(svn_wc_c void *cancel_baton, apr_pool_t *scratch_pool) { - apr_array_header_t *sorted_queue; + apr_array_header_t *wcs; int i; apr_pool_t *iterpool = svn_pool_create(scratch_pool); apr_time_t new_date; - apr_hash_t *run_wqs = apr_hash_make(scratch_pool); - apr_hash_index_t *hi; if (rev_date) SVN_ERR(svn_time_from_cstring(&new_date, rev_date, iterpool)); else new_date = 0; - /* Process the queued items in order of their paths. (The requirement is - * probably just that a directory must be processed before its children.) */ - sorted_queue = svn_sort__hash(queue->queue, svn_sort_compare_items_as_paths, - scratch_pool); - for (i = 0; i < sorted_queue->nelts; i++) + /* Process the wc's in order of their paths. */ + wcs = svn_sort__hash(queue->wc_queues, svn_sort_compare_items_as_paths, + scratch_pool); + for (i = 0; i < wcs->nelts; i++) { const svn_sort__item_t *sort_item - = &APR_ARRAY_IDX(sorted_queue, i, svn_sort__item_t); - const committed_queue_item_t *cqi = sort_item->value; - const char *wcroot_abspath; + = &APR_ARRAY_IDX(wcs, i, svn_sort__item_t); + svn_wc__db_commit_queue_t *db_queue = sort_item->value; svn_pool_clear(iterpool); - /* Skip this item if it is a child of a recursive item, because it has - been (or will be) accounted for when that recursive item was (or - will be) processed. */ - if (queue->have_recursive && have_recursive_parent(queue->queue, cqi, - iterpool)) - continue; - - SVN_ERR(svn_wc__process_committed_internal( - wc_ctx->db, cqi->local_abspath, - cqi->recurse, - TRUE /* top_of_recurse */, - new_revnum, new_date, rev_author, - cqi->new_dav_cache, - cqi->no_unlock, - cqi->keep_changelist, - cqi->sha1_checksum, queue, - iterpool)); - - /* Don't run the wq now, but remember that we must call it for this - working copy */ - SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, - wc_ctx->db, cqi->local_abspath, - iterpool, iterpool)); - - if (! svn_hash_gets(run_wqs, wcroot_abspath)) - { - wcroot_abspath = apr_pstrdup(scratch_pool, wcroot_abspath); - svn_hash_sets(run_wqs, wcroot_abspath, wcroot_abspath); - } + SVN_ERR(svn_wc__db_process_commit_queue(wc_ctx->db, db_queue, + new_revnum, new_date, rev_author, + iterpool)); } /* Make sure nothing happens if this function is called again. */ - apr_hash_clear(queue->queue); + apr_hash_clear(queue->wc_queues); /* Ok; everything is committed now. Now we can start calling callbacks */ - if (cancel_func) SVN_ERR(cancel_func(cancel_baton)); - for (hi = apr_hash_first(scratch_pool, run_wqs); - hi; - hi = apr_hash_next(hi)) + for (i = 0; i < wcs->nelts; i++) { - const char *wcroot_abspath = apr_hash_this_key(hi); + const svn_sort__item_t *sort_item + = &APR_ARRAY_IDX(wcs, i, svn_sort__item_t); + const char *wcroot_abspath = sort_item->key; svn_pool_clear(iterpool); @@ -1231,7 +941,7 @@ svn_wc_remove_lock2(svn_wc_context_t *wc apr_pool_t *scratch_pool) { svn_error_t *err; - const svn_string_t *needs_lock; + svn_skel_t *work_item; SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); @@ -1239,7 +949,12 @@ svn_wc_remove_lock2(svn_wc_context_t *wc svn_dirent_dirname(local_abspath, scratch_pool), scratch_pool)); - err = svn_wc__db_lock_remove(wc_ctx->db, local_abspath, scratch_pool); + SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, + wc_ctx->db, local_abspath, + scratch_pool, scratch_pool)); + + err = svn_wc__db_lock_remove(wc_ctx->db, local_abspath, work_item, + scratch_pool); if (err) { if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) @@ -1253,24 +968,9 @@ svn_wc_remove_lock2(svn_wc_context_t *wc scratch_pool)); } - /* if svn:needs-lock is present, then make the file read-only. */ - err = svn_wc__internal_propget(&needs_lock, wc_ctx->db, local_abspath, - SVN_PROP_NEEDS_LOCK, scratch_pool, - scratch_pool); - if (err) - { - if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS) - return svn_error_trace(err); - - svn_error_clear(err); - return SVN_NO_ERROR; /* Node is shadowed and/or deleted, - so we shouldn't apply its lock */ - } - - if (needs_lock) - SVN_ERR(svn_io_set_file_read_only(local_abspath, FALSE, scratch_pool)); - - return SVN_NO_ERROR; + return svn_error_trace(svn_wc__wq_run(wc_ctx->db, local_abspath, + NULL, NULL /* cancel*/, + scratch_pool)); } @@ -1324,9 +1024,8 @@ get_node_changelist(const char *local_ab NULL, NULL, NULL, NULL, NULL, NULL, NULL, b->db, local_abspath, scratch_pool, scratch_pool)); - - if (svn_wc__internal_changelist_match(b->db, local_abspath, b->clhash, - scratch_pool)) + if (!b->clhash + || (changelist && svn_hash_gets(b->clhash, changelist) != NULL)) SVN_ERR(b->callback_func(b->callback_baton, local_abspath, changelist, scratch_pool)); Modified: subversion/branches/authzperf/subversion/libsvn_wc/cleanup.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/cleanup.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_wc/cleanup.c (original) +++ subversion/branches/authzperf/subversion/libsvn_wc/cleanup.c Sat Jan 3 14:00:41 2015 @@ -67,69 +67,13 @@ can_be_cleaned(int *wc_format, return SVN_NO_ERROR; } -/* Do a modifed check for LOCAL_ABSPATH, and all working children, to force - timestamp repair. */ +/* Dummy svn_wc_status_func4_t implementation */ static svn_error_t * -repair_timestamps(svn_wc__db_t *db, - const char *local_abspath, - svn_cancel_func_t cancel_func, - void *cancel_baton, - apr_pool_t *scratch_pool) +status_dummy_callback(void *baton, + const char *local_abspath, + const svn_wc_status3_t *status, + apr_pool_t *scratch_pool) { - svn_node_kind_t kind; - svn_wc__db_status_t status; - - if (cancel_func) - SVN_ERR(cancel_func(cancel_baton)); - - SVN_ERR(svn_wc__db_read_info(&status, &kind, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - db, local_abspath, scratch_pool, scratch_pool)); - - if (status == svn_wc__db_status_server_excluded - || status == svn_wc__db_status_deleted - || status == svn_wc__db_status_excluded - || status == svn_wc__db_status_not_present) - return SVN_NO_ERROR; - - if (kind == svn_node_file - || kind == svn_node_symlink) - { - svn_boolean_t modified; - SVN_ERR(svn_wc__internal_file_modified_p(&modified, - db, local_abspath, FALSE, - scratch_pool)); - } - else if (kind == svn_node_dir) - { - apr_pool_t *iterpool = svn_pool_create(scratch_pool); - const apr_array_header_t *children; - int i; - - SVN_ERR(svn_wc__db_read_children_of_working_node(&children, db, - local_abspath, - scratch_pool, - iterpool)); - for (i = 0; i < children->nelts; ++i) - { - const char *child_abspath; - - svn_pool_clear(iterpool); - - child_abspath = svn_dirent_join(local_abspath, - APR_ARRAY_IDX(children, i, - const char *), - iterpool); - - SVN_ERR(repair_timestamps(db, child_abspath, - cancel_func, cancel_baton, iterpool)); - } - svn_pool_destroy(iterpool); - } - return SVN_NO_ERROR; } @@ -188,8 +132,19 @@ cleanup_internal(svn_wc__db_t *db, } if (fix_recorded_timestamps) - SVN_ERR(repair_timestamps(db, dir_abspath, cancel_func, cancel_baton, - scratch_pool)); + { + /* Instead of implementing a separate repair step here, use the standard + status walker's optimized implementation, which performs repairs when + there is a lock. */ + SVN_ERR(svn_wc__internal_walk_status(db, dir_abspath, svn_depth_infinity, + FALSE /* get_all */, + FALSE /* no_ignore */, + FALSE /* ignore_text_mods */, + NULL /* ignore patterns */, + status_dummy_callback, NULL, + cancel_func, cancel_baton, + scratch_pool)); + } /* All done, toss the lock */ SVN_ERR(svn_wc__db_wclock_release(db, dir_abspath, scratch_pool)); Modified: subversion/branches/authzperf/subversion/libsvn_wc/copy.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/copy.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_wc/copy.c (original) +++ subversion/branches/authzperf/subversion/libsvn_wc/copy.c Sat Jan 3 14:00:41 2015 @@ -50,7 +50,14 @@ TMPDIR_ABSPATH and return the absolute path of the copy in *DST_ABSPATH. Return the node kind of SRC_ABSPATH in *KIND. If SRC_ABSPATH doesn't exist then set *DST_ABSPATH to NULL to indicate - that no copy was made. */ + that no copy was made. + + If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH. + RECORDED_SIZE (if not SVN_INVALID_FILESIZE) contains the recorded size of + SRC_ABSPATH, and RECORDED_TIME the recorded size or 0. + + These values will be used to avoid unneeded work. + */ static svn_error_t * copy_to_tmpdir(svn_skel_t **work_item, svn_node_kind_t *kind, @@ -60,6 +67,9 @@ copy_to_tmpdir(svn_skel_t **work_item, const char *tmpdir_abspath, svn_boolean_t file_copy, svn_boolean_t unversioned, + const svn_io_dirent2_t *dirent, + svn_filesize_t recorded_size, + apr_time_t recorded_time, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *result_pool, @@ -74,8 +84,14 @@ copy_to_tmpdir(svn_skel_t **work_item, *work_item = NULL; - SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special, - scratch_pool)); + if (dirent) + { + *kind = dirent->kind; + is_special = dirent->special; + } + else + SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special, + scratch_pool)); if (*kind == svn_node_none) { return SVN_NO_ERROR; @@ -104,9 +120,21 @@ copy_to_tmpdir(svn_skel_t **work_item, the timestamp might match, than to examine the destination later as the destination timestamp will never match. */ - SVN_ERR(svn_wc__internal_file_modified_p(&modified, - db, src_abspath, - FALSE, scratch_pool)); + + if (dirent + && dirent->kind == svn_node_file + && recorded_size != SVN_INVALID_FILESIZE + && recorded_size == dirent->filesize + && recorded_time == dirent->mtime) + { + modified = FALSE; /* Recorded matches on-disk. Easy out */ + } + else + { + SVN_ERR(svn_wc__internal_file_modified_p(&modified, db, src_abspath, + FALSE, scratch_pool)); + } + if (!modified) { /* Why create a temp copy if we can just reinstall from pristine? */ @@ -117,6 +145,15 @@ copy_to_tmpdir(svn_skel_t **work_item, return SVN_NO_ERROR; } } + else if (*kind == svn_node_dir && !file_copy) + { + /* Just build a new direcory from the workqueue */ + SVN_ERR(svn_wc__wq_build_dir_install(work_item, + db, dst_abspath, + result_pool, scratch_pool)); + + return SVN_NO_ERROR; + } /* Set DST_TMP_ABSPATH to a temporary unique path. If *KIND is file, leave a file there and then overwrite it; otherwise leave no node on disk at @@ -172,7 +209,14 @@ copy_to_tmpdir(svn_skel_t **work_item, versioned file itself. This also works for versioned symlinks that are stored in the db as - svn_node_file with svn:special set. */ + svn_node_file with svn:special set. + + If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH. + RECORDED_SIZE (if not SVN_INVALID_FILESIZE) contains the recorded size of + SRC_ABSPATH, and RECORDED_TIME the recorded size or 0. + + These values will be used to avoid unneeded work. +*/ static svn_error_t * copy_versioned_file(svn_wc__db_t *db, const char *src_abspath, @@ -182,6 +226,9 @@ copy_versioned_file(svn_wc__db_t *db, svn_boolean_t metadata_only, svn_boolean_t conflicted, svn_boolean_t is_move, + const svn_io_dirent2_t *dirent, + svn_filesize_t recorded_size, + apr_time_t recorded_time, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -248,6 +295,7 @@ copy_versioned_file(svn_wc__db_t *db, dst_abspath, tmpdir_abspath, TRUE /* file_copy */, handle_as_unversioned /* unversioned */, + dirent, recorded_size, recorded_time, cancel_func, cancel_baton, scratch_pool, scratch_pool)); } @@ -265,10 +313,6 @@ copy_versioned_file(svn_wc__db_t *db, scratch_pool); notify->kind = svn_node_file; - /* When we notify that we performed a copy, make sure we already did */ - if (work_items != NULL) - SVN_ERR(svn_wc__wq_run(db, dst_abspath, - cancel_func, cancel_baton, scratch_pool)); (*notify_func)(notify_baton, notify, scratch_pool); } return SVN_NO_ERROR; @@ -282,6 +326,8 @@ copy_versioned_file(svn_wc__db_t *db, data in addition to copying the directory. WITHIN_ONE_WC is TRUE if the copy/move is within a single working copy (root) + + If DIRENT is not NULL, it contains the on-disk information of SRC_ABSPATH. */ static svn_error_t * copy_versioned_dir(svn_wc__db_t *db, @@ -291,6 +337,7 @@ copy_versioned_dir(svn_wc__db_t *db, const char *tmpdir_abspath, svn_boolean_t metadata_only, svn_boolean_t is_move, + const svn_io_dirent2_t *dirent, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -314,6 +361,7 @@ copy_versioned_dir(svn_wc__db_t *db, tmpdir_abspath, FALSE /* file_copy */, FALSE /* unversioned */, + dirent, SVN_INVALID_FILESIZE, 0, cancel_func, cancel_baton, scratch_pool, scratch_pool)); } @@ -395,6 +443,12 @@ copy_versioned_dir(svn_wc__db_t *db, tmpdir_abspath, metadata_only, info->conflicted, is_move, + disk_children + ? svn_hash_gets(disk_children, + child_name) + : NULL, + info->recorded_size, + info->recorded_time, cancel_func, cancel_baton, NULL, NULL, iterpool)); @@ -404,6 +458,10 @@ copy_versioned_dir(svn_wc__db_t *db, child_src_abspath, child_dst_abspath, dst_op_root_abspath, tmpdir_abspath, metadata_only, is_move, + disk_children + ? svn_hash_gets(disk_children, + child_name) + : NULL, cancel_func, cancel_baton, NULL, NULL, iterpool)); else @@ -422,7 +480,7 @@ copy_versioned_dir(svn_wc__db_t *db, child_dst_abspath, dst_op_root_abspath, is_move, NULL, iterpool)); - /* Don't recurse on children while all we do is creating not-present + /* Don't recurse on children when all we do is creating not-present children */ } else if (info->status == svn_wc__db_status_incomplete) @@ -489,6 +547,7 @@ copy_versioned_dir(svn_wc__db_t *db, SVN_ERR(copy_to_tmpdir(&work_item, NULL, db, unver_src_abspath, unver_dst_abspath, tmpdir_abspath, TRUE /* recursive */, TRUE /* unversioned */, + NULL, SVN_INVALID_FILESIZE, 0, cancel_func, cancel_baton, scratch_pool, iterpool)); @@ -534,6 +593,8 @@ copy_or_move(svn_boolean_t *move_degrade svn_boolean_t within_one_wc; svn_wc__db_status_t src_status; svn_error_t *err; + svn_filesize_t recorded_size; + apr_time_t recorded_time; SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath)); SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath)); @@ -551,7 +612,8 @@ copy_or_move(svn_boolean_t *move_degrade err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL, &src_repos_relpath, &src_repos_root_url, &src_repos_uuid, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + &recorded_size, &recorded_time, NULL, &conflicted, NULL, NULL, NULL, NULL, NULL, NULL, db, src_abspath, scratch_pool, scratch_pool); @@ -775,6 +837,7 @@ copy_or_move(svn_boolean_t *move_degrade err = copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath, tmpdir_abspath, metadata_only, conflicted, is_move, + NULL, recorded_size, recorded_time, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool); @@ -810,6 +873,7 @@ copy_or_move(svn_boolean_t *move_degrade err = copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath, tmpdir_abspath, metadata_only, is_move, + NULL /* dirent */, cancel_func, cancel_baton, notify_func, notify_baton, scratch_pool); Modified: subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c (original) +++ subversion/branches/authzperf/subversion/libsvn_wc/deprecated.c Sat Jan 3 14:00:41 2015 @@ -652,6 +652,24 @@ svn_wc_get_pristine_contents(svn_stream_ return svn_error_trace(svn_wc_context_destroy(wc_ctx)); } +svn_error_t * +svn_wc_queue_committed3(svn_wc_committed_queue_t *queue, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t recurse, + const apr_array_header_t *wcprop_changes, + svn_boolean_t remove_lock, + svn_boolean_t remove_changelist, + const svn_checksum_t *sha1_checksum, + apr_pool_t *scratch_pool) +{ + return svn_error_trace( + svn_wc_queue_committed4(queue, wc_ctx, local_abspath, + recurse, TRUE /* is_committed */, + wcprop_changes, remove_lock, + remove_changelist, sha1_checksum, + scratch_pool)); +} svn_error_t * svn_wc_queue_committed2(svn_wc_committed_queue_t *queue, @@ -668,7 +686,9 @@ svn_wc_queue_committed2(svn_wc_committed const char *local_abspath; const svn_checksum_t *sha1_checksum = NULL; - SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, + svn_wc__adm_get_db(adm_access), + scratch_pool)); SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool)); if (md5_checksum != NULL) @@ -759,15 +779,11 @@ svn_wc_process_committed4(const char *pa const char *local_abspath; const svn_checksum_t *md5_checksum; const svn_checksum_t *sha1_checksum = NULL; - apr_time_t new_date; - apr_hash_t *wcprop_changes_hash; + svn_wc_context_t *wc_ctx; + svn_wc_committed_queue_t *queue; SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); - - if (rev_date) - SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool)); - else - new_date = 0; + SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL, db, pool)); if (digest) md5_checksum = svn_checksum__from_digest_md5(digest, pool); @@ -790,15 +806,20 @@ svn_wc_process_committed4(const char *pa SVN_ERR(err); } - wcprop_changes_hash = svn_wc__prop_array_to_hash(wcprop_changes, pool); - SVN_ERR(svn_wc__process_committed_internal(db, local_abspath, recurse, TRUE, - new_revnum, new_date, rev_author, - wcprop_changes_hash, - !remove_lock, !remove_changelist, - sha1_checksum, NULL, pool)); + queue = svn_wc_committed_queue_create(pool); + SVN_ERR(svn_wc_queue_committed3(queue, wc_ctx, local_abspath, recurse, + wcprop_changes, remove_lock, + remove_changelist, + sha1_checksum /* or NULL if not modified + or directory */, + pool)); + + SVN_ERR(svn_wc_process_committed_queue2(queue, wc_ctx, + new_revnum, rev_date, rev_author, + NULL, NULL /* cancel */, + pool)); - /* Run the log file(s) we just created. */ - return svn_error_trace(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool)); + return svn_error_trace(svn_wc_context_destroy(wc_ctx)); } Modified: subversion/branches/authzperf/subversion/libsvn_wc/diff.h URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_wc/diff.h?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_wc/diff.h (original) +++ subversion/branches/authzperf/subversion/libsvn_wc/diff.h Sat Jan 3 14:00:41 2015 @@ -47,9 +47,6 @@ extern "C" { svn_wc__db_status_added. When DIFF_PRISTINE is TRUE, report the pristine version of LOCAL_ABSPATH as ADDED. In this case an svn_wc__db_status_deleted may shadow an added or deleted node. - - If CHANGELIST_HASH is not NULL and LOCAL_ABSPATH's changelist is not - in the changelist, don't report the node. */ svn_error_t * svn_wc__diff_local_only_file(svn_wc__db_t *db, @@ -57,7 +54,6 @@ svn_wc__diff_local_only_file(svn_wc__db_ const char *relpath, const svn_diff_tree_processor_t *processor, void *processor_parent_baton, - apr_hash_t *changelist_hash, svn_boolean_t diff_pristine, svn_cancel_func_t cancel_func, void *cancel_baton, @@ -73,9 +69,6 @@ svn_wc__diff_local_only_file(svn_wc__db_ svn_wc__db_status_added. When DIFF_PRISTINE is TRUE, report the pristine version of LOCAL_ABSPATH as ADDED. In this case an svn_wc__db_status_deleted may shadow an added or deleted node. - - If CHANGELIST_HASH is not NULL and LOCAL_ABSPATH's changelist is not - in the changelist, don't report the node. */ svn_error_t * svn_wc__diff_local_only_dir(svn_wc__db_t *db, @@ -84,7 +77,6 @@ svn_wc__diff_local_only_dir(svn_wc__db_t svn_depth_t depth, const svn_diff_tree_processor_t *processor, void *processor_parent_baton, - apr_hash_t *changelist_hash, svn_boolean_t diff_pristine, svn_cancel_func_t cancel_func, void *cancel_baton, @@ -132,7 +124,6 @@ svn_wc__diff_base_working_diff(svn_wc__d const char *local_abspath, const char *relpath, svn_revnum_t revision, - apr_hash_t *changelist_hash, const svn_diff_tree_processor_t *processor, void *processor_dir_baton, svn_boolean_t diff_pristine, @@ -140,6 +131,32 @@ svn_wc__diff_base_working_diff(svn_wc__d void *cancel_baton, apr_pool_t *scratch_pool); +/* Return a tree processor filter that filters by changelist membership. + * + * This filter only passes on the changes for a file if the file's path + * (in the WC) is assigned to one of the changelists in @a changelist_hash. + * It also passes on the opening and closing of each directory that contains + * such a change, and possibly also of other directories, but not addition + * or deletion or changes to a directory. + * + * If @a changelist_hash is null then no filtering is performed and the + * returned diff processor is driven exactly like the input @a processor. + * + * @a wc_ctx is the WC context and @a root_local_abspath is the WC path of + * the root of the diff (for which relpath = "" in the diff processor). + * + * Allocate the returned diff processor in @a result_pool, or if no + * filtering is required then the input pointer @a processor itself may be + * returned. + */ +const svn_diff_tree_processor_t * +svn_wc__changelist_filter_tree_processor_create( + const svn_diff_tree_processor_t *processor, + svn_wc_context_t *wc_ctx, + const char *root_local_abspath, + apr_hash_t *changelist_hash, + apr_pool_t *result_pool); + #ifdef __cplusplus }
