Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/tree.h Fri Sep 11 15:51:30 2015 @@ -20,10 +20,11 @@ * ==================================================================== */ -#ifndef SVN_LIBSVN_FS_TREE_H -#define SVN_LIBSVN_FS_TREE_H +#ifndef SVN_LIBSVN_FS_X_TREE_H +#define SVN_LIBSVN_FS_X_TREE_H #include "fs.h" +#include "dag.h" #ifdef __cplusplus extern "C" { @@ -31,9 +32,13 @@ extern "C" { -/* In RESULT_POOL, create an instance of a DAG node 1st level cache. */ -svn_fs_x__dag_cache_t* -svn_fs_x__create_dag_cache(apr_pool_t *result_pool); +/* Return the transaction ID to a given transaction ROOT. */ +svn_fs_x__txn_id_t +svn_fs_x__root_txn_id(svn_fs_root_t *root); + +/* Return the change set to a given ROOT. */ +svn_fs_x__change_set_t +svn_fs_x__root_change_set(svn_fs_root_t *root); /* Set *ROOT_P to the root directory of revision REV in filesystem FS. Allocate the structure in POOL. */ @@ -109,4 +114,4 @@ svn_fs_x__info_config_files(apr_array_he } #endif /* __cplusplus */ -#endif /* SVN_LIBSVN_FS_TREE_H */ +#endif /* SVN_LIBSVN_FS_X_TREE_H */
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.c Fri Sep 11 15:51:30 2015 @@ -110,11 +110,24 @@ svn_fs_x__path_current(svn_fs_t *fs, } const char * +svn_fs_x__path_next(svn_fs_t *fs, + apr_pool_t *result_pool) +{ + return svn_dirent_join(fs->path, PATH_NEXT, result_pool); +} + +const char * svn_fs_x__path_txn_current(svn_fs_t *fs, apr_pool_t *result_pool) { - return svn_dirent_join(fs->path, PATH_TXN_CURRENT, - result_pool); + return svn_dirent_join(fs->path, PATH_TXN_CURRENT, result_pool); +} + +const char * +svn_fs_x__path_txn_next(svn_fs_t *fs, + apr_pool_t *result_pool) +{ + return svn_dirent_join(fs->path, PATH_TXN_NEXT, result_pool); } const char * @@ -147,14 +160,12 @@ svn_fs_x__path_revprop_generation(svn_fs /* Return the full path of the file FILENAME within revision REV's shard in * FS. If FILENAME is NULL, return the shard directory directory itself. - * REVPROPS indicates the parent of the shard parent folder ("revprops" or - * "revs"). PACKED says whether we want the packed shard's name. + * PACKED says whether we want the packed shard's name. * * Allocate the result in RESULT_POOL. */static const char* construct_shard_sub_path(svn_fs_t *fs, svn_revnum_t rev, - svn_boolean_t revprops, svn_boolean_t packed, const char *filename, apr_pool_t *result_pool) @@ -162,9 +173,6 @@ construct_shard_sub_path(svn_fs_t *fs, svn_fs_x__data_t *ffd = fs->fsap_data; char buffer[SVN_INT64_BUFFER_SIZE + sizeof(PATH_EXT_PACKED_SHARD)] = { 0 }; - /* Select the appropriate parent path constant. */ - const char *parent = revprops ? PATH_REVPROPS_DIR : PATH_REVS_DIR; - /* String containing the shard number. */ apr_size_t len = svn__i64toa(buffer, rev / ffd->max_files_per_dir); @@ -173,7 +181,7 @@ construct_shard_sub_path(svn_fs_t *fs, strncpy(buffer + len, PATH_EXT_PACKED_SHARD, sizeof(buffer) - len - 1); /* This will also work for NULL FILENAME as well. */ - return svn_dirent_join_many(result_pool, fs->path, parent, buffer, + return svn_dirent_join_many(result_pool, fs->path, PATH_REVS_DIR, buffer, filename, SVN_VA_NULL); } @@ -184,15 +192,15 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs, apr_pool_t *result_pool) { assert(svn_fs_x__is_packed_rev(fs, rev)); - return construct_shard_sub_path(fs, rev, FALSE, TRUE, kind, result_pool); + return construct_shard_sub_path(fs, rev, TRUE, kind, result_pool); } const char * -svn_fs_x__path_rev_shard(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *result_pool) +svn_fs_x__path_shard(svn_fs_t *fs, + svn_revnum_t rev, + apr_pool_t *result_pool) { - return construct_shard_sub_path(fs, rev, FALSE, FALSE, NULL, result_pool); + return construct_shard_sub_path(fs, rev, FALSE, NULL, result_pool); } const char * @@ -200,11 +208,12 @@ svn_fs_x__path_rev(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *result_pool) { - char buffer[SVN_INT64_BUFFER_SIZE]; - svn__i64toa(buffer, rev); + char buffer[SVN_INT64_BUFFER_SIZE + 1]; + buffer[0] = 'r'; + svn__i64toa(buffer + 1, rev); assert(! svn_fs_x__is_packed_rev(fs, rev)); - return construct_shard_sub_path(fs, rev, FALSE, FALSE, buffer, result_pool); + return construct_shard_sub_path(fs, rev, FALSE, buffer, result_pool); } const char * @@ -218,19 +227,11 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs } const char * -svn_fs_x__path_revprops_shard(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *result_pool) -{ - return construct_shard_sub_path(fs, rev, TRUE, FALSE, NULL, result_pool); -} - -const char * -svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs, +svn_fs_x__path_pack_shard(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *result_pool) { - return construct_shard_sub_path(fs, rev, TRUE, TRUE, NULL, result_pool); + return construct_shard_sub_path(fs, rev, TRUE, NULL, result_pool); } const char * @@ -238,11 +239,17 @@ svn_fs_x__path_revprops(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *result_pool) { - char buffer[SVN_INT64_BUFFER_SIZE]; - svn__i64toa(buffer, rev); + char buffer[SVN_INT64_BUFFER_SIZE + 1]; + buffer[0] = 'p'; + svn__i64toa(buffer + 1, rev); assert(! svn_fs_x__is_packed_revprop(fs, rev)); - return construct_shard_sub_path(fs, rev, TRUE, FALSE, buffer, result_pool); + + /* Revprops for packed r0 are not packed, yet stored in the packed shard. + Hence, the second flag must check for packed _rev_ - not revprop. */ + return construct_shard_sub_path(fs, rev, + svn_fs_x__is_packed_rev(fs, rev) /* sic! */, + buffer, result_pool); } const char * @@ -340,14 +347,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs, return construct_txn_path(fs, txn_id, PATH_TXN_PROPS, result_pool); } -const char * -svn_fs_x__path_txn_props_final(svn_fs_t *fs, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *result_pool) -{ - return construct_txn_path(fs, txn_id, PATH_TXN_PROPS_FINAL, result_pool); -} - const char* svn_fs_x__path_l2p_proto_index(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, @@ -583,15 +582,20 @@ svn_fs_x__write_current(svn_fs_t *fs, { char *buf; const char *tmp_name, *name; + apr_file_t *file; /* Now we can just write out this line. */ buf = apr_psprintf(scratch_pool, "%ld\n", rev); name = svn_fs_x__path_current(fs, scratch_pool); - SVN_ERR(svn_io_write_unique(&tmp_name, - svn_dirent_dirname(name, scratch_pool), - buf, strlen(buf), - svn_io_file_del_none, scratch_pool)); + tmp_name = svn_fs_x__path_next(fs, scratch_pool); + + SVN_ERR(svn_io_file_open(&file, tmp_name, + APR_WRITE | APR_CREATE | APR_BUFFERED, + APR_OS_DEFAULT, scratch_pool)); + SVN_ERR(svn_io_file_write_full(file, buf, strlen(buf), NULL, + scratch_pool)); + SVN_ERR(svn_io_file_close(file, scratch_pool)); return svn_fs_x__move_into_place(tmp_name, name, name, scratch_pool); } @@ -730,7 +734,7 @@ svn_fs_x__move_into_place(const char *ol SVN_ERR(svn_io_copy_perms(perms_reference, old_filename, scratch_pool)); /* Move the file into place. */ - err = svn_io_file_rename(old_filename, new_filename, scratch_pool); + err = svn_io_file_rename2(old_filename, new_filename, FALSE, scratch_pool); if (err && APR_STATUS_IS_EXDEV(err->apr_err)) { apr_file_t *file; Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/util.h Fri Sep 11 15:51:30 2015 @@ -20,8 +20,8 @@ * ==================================================================== */ -#ifndef SVN_LIBSVN_FS__UTIL_H -#define SVN_LIBSVN_FS__UTIL_H +#ifndef SVN_LIBSVN_FS_X_UTIL_H +#define SVN_LIBSVN_FS_X_UTIL_H #include "svn_fs.h" #include "id.h" @@ -102,6 +102,12 @@ const char * svn_fs_x__path_current(svn_fs_t *fs, apr_pool_t *result_pool); +/* Return the path to the 'next' file in FS. + Perform allocation in RESULT_POOL. */ +const char * +svn_fs_x__path_next(svn_fs_t *fs, + apr_pool_t *result_pool); + /* Return the full path of the "uuid" file in FS. * The result will be allocated in RESULT_POOL. */ @@ -116,6 +122,13 @@ const char * svn_fs_x__path_txn_current(svn_fs_t *fs, apr_pool_t *result_pool); +/* Return the full path of the "txn-next" file in FS. + * The result will be allocated in RESULT_POOL. + */ +const char * +svn_fs_x__path_txn_next(svn_fs_t *fs, + apr_pool_t *result_pool); + /* Return the full path of the "txn-current-lock" file in FS. * The result will be allocated in RESULT_POOL. */ @@ -158,9 +171,9 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs, * revision REV in FS. Allocate the result in RESULT_POOL. */ const char * -svn_fs_x__path_rev_shard(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *result_pool); +svn_fs_x__path_shard(svn_fs_t *fs, + svn_revnum_t rev, + apr_pool_t *result_pool); /* Return the full path of the non-packed rev file containing revision REV * in FS. Allocate the result in RESULT_POOL. @@ -183,23 +196,13 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs svn_revnum_t rev, apr_pool_t *result_pool); -/* Return the full path of the revision properties shard directory that - * will contain the properties of revision REV in FS. - * Allocate the result in RESULT_POOL. - */ -const char * -svn_fs_x__path_revprops_shard(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *result_pool); - -/* Return the full path of the revision properties pack shard directory - * that will contain the packed properties of revision REV in FS. - * Allocate the result in RESULT_POOL. +/* Return the full path of the pack shard directory that will contain the + * packed revision REV in FS. Allocate the result in RESULT_POOL. */ const char * -svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *result_pool); +svn_fs_x__path_pack_shard(svn_fs_t *fs, + svn_revnum_t rev, + apr_pool_t *result_pool); /* Return the full path of the non-packed revision properties file that * contains the props for revision REV in FS. @@ -287,15 +290,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, apr_pool_t *result_pool); -/* Return the path of the file containing the "final" transaction - * properties for the transaction identified by TXN_ID in FS. - * The result will be allocated in RESULT_POOL. - */ -const char * -svn_fs_x__path_txn_props_final(svn_fs_t *fs, - svn_fs_x__txn_id_t txn_id, - apr_pool_t *result_pool); - /* Return the path of the file containing the node and copy ID counters for * the transaction identified by TXN_ID in FS. * The result will be allocated in RESULT_POOL. Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.c Fri Sep 11 15:51:30 2015 @@ -141,30 +141,27 @@ verify_rep_cache(svn_fs_t *fs, * indedx NAME in the error message. Supports cancellation with CANCEL_FUNC * and CANCEL_BATON. SCRATCH_POOL is for temporary allocations. */ static svn_error_t * -verify_index_checksum(apr_file_t *file, +verify_index_checksum(svn_fs_x__revision_file_t *file, const char *name, - apr_off_t start, - apr_off_t end, - svn_checksum_t *expected, + svn_fs_x__index_info_t *index_info, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *scratch_pool) { unsigned char buffer[SVN__STREAM_CHUNK_SIZE]; - apr_off_t size = end - start; + apr_off_t size = index_info->end - index_info->start; svn_checksum_t *actual; svn_checksum_ctx_t *context = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool); /* Calculate the index checksum. */ - SVN_ERR(svn_io_file_seek(file, APR_SET, &start, scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_seek(file, NULL, index_info->start)); while (size > 0) { apr_size_t to_read = size > sizeof(buffer) ? sizeof(buffer) : (apr_size_t)size; - SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL, - scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read)); SVN_ERR(svn_checksum_update(context, buffer, to_read)); size -= to_read; @@ -175,12 +172,13 @@ verify_index_checksum(apr_file_t *file, SVN_ERR(svn_checksum_final(&actual, context, scratch_pool)); /* Verify that it matches the expected checksum. */ - if (!svn_checksum_match(expected, actual)) + if (!svn_checksum_match(index_info->checksum, actual)) { const char *file_name; - SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool)); - SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool, + SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool)); + SVN_ERR(svn_checksum_mismatch_err(index_info->checksum, actual, + scratch_pool, _("%s checksum mismatch in file %s"), name, file_name)); } @@ -201,20 +199,18 @@ verify_index_checksums(svn_fs_t *fs, apr_pool_t *scratch_pool) { svn_fs_x__revision_file_t *rev_file; + svn_fs_x__index_info_t l2p_index_info; + svn_fs_x__index_info_t p2l_index_info; /* Open the rev / pack file and read the footer */ - SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, - scratch_pool, scratch_pool)); - SVN_ERR(svn_fs_x__auto_read_footer(rev_file)); + SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file)); + SVN_ERR(svn_fs_x__rev_file_p2l_info(&p2l_index_info, rev_file)); /* Verify the index contents against the checksum from the footer. */ - SVN_ERR(verify_index_checksum(rev_file->file, "L2P index", - rev_file->l2p_offset, rev_file->p2l_offset, - rev_file->l2p_checksum, + SVN_ERR(verify_index_checksum(rev_file, "L2P index", &l2p_index_info, cancel_func, cancel_baton, scratch_pool)); - SVN_ERR(verify_index_checksum(rev_file->file, "P2L index", - rev_file->p2l_offset, rev_file->footer_offset, - rev_file->p2l_checksum, + SVN_ERR(verify_index_checksum(rev_file, "P2L index", &p2l_index_info, cancel_func, cancel_baton, scratch_pool)); /* Done. */ @@ -242,8 +238,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, /* common file access structure */ svn_fs_x__revision_file_t *rev_file; - SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool, - iterpool)); + SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool)); /* determine the range of items to check for each revision */ SVN_ERR(svn_fs_x__l2p_get_max_ids(&max_ids, fs, start, count, scratch_pool, @@ -334,8 +329,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, /* common file access structure */ svn_fs_x__revision_file_t *rev_file; - SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool, - iterpool)); + SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool)); /* get the size of the rev / pack file as covered by the P2L index */ SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start, @@ -424,7 +418,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, * exceed STREAM_THRESHOLD. Use SCRATCH_POOL for temporary allocations. */ static svn_error_t * -expect_buffer_nul(apr_file_t *file, +expect_buffer_nul(svn_fs_x__revision_file_t *file, apr_off_t size, apr_pool_t *scratch_pool) { @@ -439,8 +433,7 @@ expect_buffer_nul(apr_file_t *file, /* read the whole data block; error out on failure */ data.chunks[(size - 1)/ sizeof(apr_uint64_t)] = 0; - SVN_ERR(svn_io_file_read_full2(file, data.buffer, size, NULL, NULL, - scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_read(file, data.buffer, size)); /* chunky check */ for (i = 0; i < size / sizeof(apr_uint64_t); ++i) @@ -454,8 +447,8 @@ expect_buffer_nul(apr_file_t *file, const char *file_name; apr_off_t offset; - SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool)); - SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_offset(&offset, file)); offset -= size - i; return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, @@ -472,7 +465,7 @@ expect_buffer_nul(apr_file_t *file, * Use SCRATCH_POOL for temporary allocations. */ static svn_error_t * -read_all_nul(apr_file_t *file, +read_all_nul(svn_fs_x__revision_file_t *file, apr_off_t size, apr_pool_t *scratch_pool) { @@ -490,7 +483,7 @@ read_all_nul(apr_file_t *file, * in error message. Allocate temporary data in SCRATCH_POOL. */ static svn_error_t * -expected_checksum(apr_file_t *file, +expected_checksum(svn_fs_x__revision_file_t *file, svn_fs_x__p2l_entry_t *entry, apr_uint32_t actual, apr_pool_t *scratch_pool) @@ -499,8 +492,7 @@ expected_checksum(apr_file_t *file, { const char *file_name; - SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool)); - SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool)); return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, _("Checksum mismatch in item at offset %s of " "length %s bytes in file %s"), @@ -517,15 +509,14 @@ expected_checksum(apr_file_t *file, * exceed STREAM_THRESHOLD. Use SCRATCH_POOL for temporary allocations. */ static svn_error_t * -expected_buffered_checksum(apr_file_t *file, +expected_buffered_checksum(svn_fs_x__revision_file_t *file, svn_fs_x__p2l_entry_t *entry, apr_pool_t *scratch_pool) { unsigned char buffer[STREAM_THRESHOLD]; SVN_ERR_ASSERT(entry->size <= STREAM_THRESHOLD); - SVN_ERR(svn_io_file_read_full2(file, buffer, (apr_size_t)entry->size, - NULL, NULL, scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_read(file, buffer, (apr_size_t)entry->size)); SVN_ERR(expected_checksum(file, entry, svn__fnv1a_32x4(buffer, (apr_size_t)entry->size), scratch_pool)); @@ -538,7 +529,7 @@ expected_buffered_checksum(apr_file_t *f * Use SCRATCH_POOL for temporary allocations. */ static svn_error_t * -expected_streamed_checksum(apr_file_t *file, +expected_streamed_checksum(svn_fs_x__revision_file_t *file, svn_fs_x__p2l_entry_t *entry, apr_pool_t *scratch_pool) { @@ -553,8 +544,7 @@ expected_streamed_checksum(apr_file_t *f apr_size_t to_read = size > sizeof(buffer) ? sizeof(buffer) : (apr_size_t)size; - SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL, - scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read)); SVN_ERR(svn_checksum_update(context, buffer, to_read)); size -= to_read; } @@ -588,28 +578,27 @@ compare_p2l_to_rev(svn_fs_t *fs, apr_off_t max_offset; apr_off_t offset = 0; svn_fs_x__revision_file_t *rev_file; + svn_fs_x__index_info_t l2p_index_info; /* open the pack / rev file that is covered by the p2l index */ - SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool, - iterpool)); + SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool)); /* check file size vs. range covered by index */ - SVN_ERR(svn_fs_x__auto_read_footer(rev_file)); + SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file)); SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start, scratch_pool)); - if (rev_file->l2p_offset != max_offset) + if (l2p_index_info.start != max_offset) return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("File size of %s for revision r%ld does " "not match p2l index size of %s"), apr_off_t_toa(scratch_pool, - rev_file->l2p_offset), + l2p_index_info.start), start, apr_off_t_toa(scratch_pool, max_offset)); - SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size, NULL, 0, - scratch_pool)); + SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, 0)); /* for all offsets in the file, get the P2L index entries and check them against the L2P index */ @@ -627,8 +616,7 @@ compare_p2l_to_rev(svn_fs_t *fs, /* The above might have moved the file pointer. * Ensure we actually start reading at OFFSET. */ - SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size, - NULL, offset, iterpool)); + SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, offset)); /* process all entries (and later continue with the next block) */ for (i = 0; i < entries->nelts; ++i) @@ -661,15 +649,15 @@ compare_p2l_to_rev(svn_fs_t *fs, { /* skip filler entry at the end of the p2l index */ if (entry->offset != max_offset) - SVN_ERR(read_all_nul(rev_file->file, entry->size, iterpool)); + SVN_ERR(read_all_nul(rev_file, entry->size, iterpool)); } else { if (entry->size < STREAM_THRESHOLD) - SVN_ERR(expected_buffered_checksum(rev_file->file, entry, + SVN_ERR(expected_buffered_checksum(rev_file, entry, iterpool)); else - SVN_ERR(expected_streamed_checksum(rev_file->file, entry, + SVN_ERR(expected_streamed_checksum(rev_file, entry, iterpool)); } Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/verify.h Fri Sep 11 15:51:30 2015 @@ -1,4 +1,4 @@ -/* verify.h : verification interface of the native filesystem layer +/* verify.h : verification interface of the FSX filesystem * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one @@ -20,8 +20,8 @@ * ==================================================================== */ -#ifndef SVN_LIBSVN_FS__VERIFY_H -#define SVN_LIBSVN_FS__VERIFY_H +#ifndef SVN_LIBSVN_FS_X_VERIFY_H +#define SVN_LIBSVN_FS_X_VERIFY_H #include "fs.h" Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/serf.c Fri Sep 11 15:51:30 2015 @@ -355,19 +355,16 @@ load_config(svn_ra_serf__session_t *sess session->timeout = apr_time_from_sec(DEFAULT_HTTP_TIMEOUT); if (timeout_str) { - char *endstr; - const long int timeout = strtol(timeout_str, &endstr, 10); - - if (*endstr) - return svn_error_create(SVN_ERR_BAD_CONFIG_VALUE, NULL, - _("Invalid config: illegal character in " - "timeout value")); - if (timeout < 0) - return svn_error_create(SVN_ERR_BAD_CONFIG_VALUE, NULL, - _("Invalid config: negative timeout value")); + apr_int64_t timeout; + svn_error_t *err; + + err = svn_cstring_strtoi64(&timeout, timeout_str, 0, APR_INT64_MAX, 10); + if (err) + return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, err, + _("invalid config: bad value for '%s' option"), + SVN_CONFIG_OPTION_HTTP_TIMEOUT); session->timeout = apr_time_from_sec(timeout); } - SVN_ERR_ASSERT(session->timeout >= 0); /* Convert the proxy port value, if any. */ if (port_str) @@ -445,12 +442,13 @@ load_config(svn_ra_serf__session_t *sess #undef DEFAULT_HTTP_TIMEOUT static void -svn_ra_serf__progress(void *progress_baton, apr_off_t read, apr_off_t written) +svn_ra_serf__progress(void *progress_baton, apr_off_t bytes_read, + apr_off_t bytes_written) { const svn_ra_serf__session_t *serf_sess = progress_baton; if (serf_sess->progress_func) { - serf_sess->progress_func(read + written, -1, + serf_sess->progress_func(bytes_read + bytes_written, -1, serf_sess->progress_baton, serf_sess->pool); } Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/update.c Fri Sep 11 15:51:30 2015 @@ -1129,7 +1129,15 @@ handle_fetch(serf_request_t *request, /* Validate the delta base claimed by the server matches what we asked for! */ val = serf_bucket_headers_get(hdrs, SVN_DAV_DELTA_BASE_HEADER); - if (val && (strcmp(val, fetch_ctx->delta_base) != 0)) + if (val && fetch_ctx->delta_base == NULL) + { + /* We recieved response with delta base header while we didn't + requested it -- report it as error. */ + return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, + _("GET request returned unexpected " + "delta base: %s"), val); + } + else if (val && (strcmp(val, fetch_ctx->delta_base) != 0)) { return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, _("GET request returned unexpected " Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_serf/util.c Fri Sep 11 15:51:30 2015 @@ -65,7 +65,9 @@ ssl_convert_serf_failures(int failures) apr_uint32_t svn_failures = 0; apr_size_t i; - for (i = 0; i < sizeof(serf_failure_map) / (2 * sizeof(apr_uint32_t)); ++i) + for (i = 0; + i < sizeof(serf_failure_map) / (sizeof(serf_failure_map[0])); + ++i) { if (failures & serf_failure_map[i][0]) { Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/client.c Fri Sep 11 15:51:30 2015 @@ -187,7 +187,7 @@ static svn_error_t *make_connection(cons /* Set *DIFFS to an array of svn_prop_t, allocated in POOL, based on the property diffs in LIST, received from the server. */ -static svn_error_t *parse_prop_diffs(const apr_array_header_t *list, +static svn_error_t *parse_prop_diffs(const svn_ra_svn__list_t *list, apr_pool_t *pool, apr_array_header_t **diffs) { @@ -198,21 +198,22 @@ static svn_error_t *parse_prop_diffs(con for (i = 0; i < list->nelts; i++) { svn_prop_t *prop; - svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t); + svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(list, i); if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Prop diffs element not a list")); prop = apr_array_push(*diffs); - SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "c(?s)", &prop->name, - &prop->value)); + SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, pool, "c(?s)", + &prop->name, &prop->value)); } return SVN_NO_ERROR; } /* Parse a lockdesc, provided in LIST as specified by the protocol into LOCK, allocated in POOL. */ -static svn_error_t *parse_lock(const apr_array_header_t *list, apr_pool_t *pool, +static svn_error_t *parse_lock(const svn_ra_svn__list_t *list, + apr_pool_t *pool, svn_lock_t **lock) { const char *cdate, *edate; @@ -240,7 +241,7 @@ static svn_error_t *handle_auth_request( apr_pool_t *pool) { svn_ra_svn_conn_t *conn = sess->conn; - apr_array_header_t *mechlist; + svn_ra_svn__list_t *mechlist; const char *realm; SVN_ERR(svn_ra_svn__read_cmd_response(conn, pool, "lc", &mechlist, &realm)); @@ -624,7 +625,7 @@ static svn_error_t *open_session(svn_ra_ svn_ra_svn_conn_t *conn; apr_socket_t *sock; apr_uint64_t minver, maxver; - apr_array_header_t *mechlist, *server_caplist, *repos_caplist; + svn_ra_svn__list_t *mechlist, *server_caplist, *repos_caplist; const char *client_string = NULL; apr_pool_t *pool = result_pool; @@ -726,7 +727,7 @@ static svn_error_t *open_session(svn_ra_ return svn_error_createf(SVN_ERR_RA_SVN_BAD_VERSION, NULL, _("Server only supports versions up to %d"), (int) maxver); - SVN_ERR(svn_ra_svn_set_capabilities(conn, server_caplist)); + SVN_ERR(svn_ra_svn__set_capabilities(conn, server_caplist)); /* All released versions of Subversion support edit-pipeline, * so we do not support servers that do not. */ @@ -759,7 +760,7 @@ static svn_error_t *open_session(svn_ra_ SVN_ERR(svn_ra_svn__read_cmd_response(conn, pool, "c?c?l", &conn->uuid, &conn->repos_root, &repos_caplist)); if (repos_caplist) - SVN_ERR(svn_ra_svn_set_capabilities(conn, repos_caplist)); + SVN_ERR(svn_ra_svn__set_capabilities(conn, repos_caplist)); if (conn->repos_root) { @@ -1032,7 +1033,7 @@ static svn_error_t *ra_svn_rev_proplist( { svn_ra_svn__session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; - apr_array_header_t *proplist; + svn_ra_svn__list_t *proplist; SVN_ERR(svn_ra_svn__write_cmd_rev_proplist(conn, pool, rev)); SVN_ERR(handle_auth_request(sess_baton, pool)); @@ -1179,12 +1180,12 @@ static svn_error_t *ra_svn_commit(svn_ra return SVN_NO_ERROR; } -/* Parse IPROPLIST, an array of svn_ra_svn_item_t structures, as a list of +/* Parse IPROPLIST, an array of svn_ra_svn__item_t structures, as a list of const char * repos relative paths and properties for those paths, storing the result as an array of svn_prop_inherited_item_t *items. */ static svn_error_t * parse_iproplist(apr_array_header_t **inherited_props, - const apr_array_header_t *iproplist, + const svn_ra_svn__list_t *iproplist, svn_ra_session_t *session, apr_pool_t *result_pool, apr_pool_t *scratch_pool) @@ -1213,14 +1214,13 @@ parse_iproplist(apr_array_header_t **inh for (i = 0; i < iproplist->nelts; i++) { - apr_array_header_t *iprop_list; + svn_ra_svn__list_t *iprop_list; char *parent_rel_path; apr_hash_t *iprops; apr_hash_index_t *hi; svn_prop_inherited_item_t *new_iprop = apr_palloc(result_pool, sizeof(*new_iprop)); - svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(iproplist, i, - svn_ra_svn_item_t); + svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(iproplist, i); if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create( SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, @@ -1228,7 +1228,7 @@ parse_iproplist(apr_array_header_t **inh svn_pool_clear(iterpool); - SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool, "cl", + SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, iterpool, "cl", &parent_rel_path, &iprop_list)); SVN_ERR(svn_ra_svn__parse_proplist(iprop_list, iterpool, &iprops)); new_iprop->path_or_url = svn_path_url_add_component2(repos_root_url, @@ -1260,7 +1260,7 @@ static svn_error_t *ra_svn_get_file(svn_ { svn_ra_svn__session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; - apr_array_header_t *proplist; + svn_ra_svn__list_t *proplist; const char *expected_digest; svn_checksum_t *expected_checksum = NULL; svn_checksum_ctx_t *checksum_ctx; @@ -1293,22 +1293,22 @@ static svn_error_t *ra_svn_get_file(svn_ iterpool = svn_pool_create(pool); while (1) { - svn_ra_svn_item_t *item; + svn_ra_svn__item_t *item; svn_pool_clear(iterpool); SVN_ERR(svn_ra_svn__read_item(conn, iterpool, &item)); if (item->kind != SVN_RA_SVN_STRING) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Non-string as part of file contents")); - if (item->u.string->len == 0) + if (item->u.string.len == 0) break; if (expected_checksum) - SVN_ERR(svn_checksum_update(checksum_ctx, item->u.string->data, - item->u.string->len)); + SVN_ERR(svn_checksum_update(checksum_ctx, item->u.string.data, + item->u.string.len)); - SVN_ERR(svn_stream_write(stream, item->u.string->data, - &item->u.string->len)); + SVN_ERR(svn_stream_write(stream, item->u.string.data, + &item->u.string.len)); } svn_pool_destroy(iterpool); @@ -1339,7 +1339,7 @@ static svn_error_t *ra_svn_get_dir(svn_r { svn_ra_svn__session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; - apr_array_header_t *proplist, *dirlist; + svn_ra_svn__list_t *proplist, *dirlist; int i; SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(c(?r)bb(!", "get-dir", path, @@ -1384,12 +1384,12 @@ static svn_error_t *ra_svn_get_dir(svn_r svn_dirent_t *dirent; apr_uint64_t size; svn_revnum_t crev; - svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(dirlist, i, svn_ra_svn_item_t); + svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(dirlist, i); if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Dirlist element not a list")); - SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "cwnbr(?c)(?c)", + SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, pool, "cwnbr(?c)(?c)", &name, &kind, &size, &has_props, &crev, &cdate, &cauthor)); @@ -1451,8 +1451,8 @@ static svn_error_t *ra_svn_get_mergeinfo svn_ra_svn__session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; int i; - apr_array_header_t *mergeinfo_tuple; - svn_ra_svn_item_t *elt; + svn_ra_svn__list_t *mergeinfo_tuple; + svn_ra_svn__item_t *elt; const char *path; SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "get-mergeinfo")); @@ -1477,11 +1477,11 @@ static svn_error_t *ra_svn_get_mergeinfo svn_mergeinfo_t for_path; const char *to_parse; - elt = &((svn_ra_svn_item_t *) mergeinfo_tuple->elts)[i]; + elt = &SVN_RA_SVN__LIST_ITEM(mergeinfo_tuple, i); if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Mergeinfo element is not a list")); - SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "cc", + SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, pool, "cc", &path, &to_parse)); SVN_ERR(svn_mergeinfo_parse(&for_path, to_parse, pool)); /* Correct for naughty servers that send "relative" paths @@ -1684,12 +1684,12 @@ perform_ra_svn_log(svn_error_t **outer_e apr_uint64_t has_children_param, invalid_revnum_param; apr_uint64_t has_subtractive_merge_param; svn_string_t *author, *date, *message; - apr_array_header_t *cplist, *rplist; + svn_ra_svn__list_t *cplist, *rplist; svn_log_entry_t *log_entry; svn_boolean_t has_children; svn_boolean_t subtractive_merge = FALSE; apr_uint64_t revprop_count; - svn_ra_svn_item_t *item; + svn_ra_svn__item_t *item; apr_hash_t *cphash; svn_revnum_t rev; @@ -1700,7 +1700,7 @@ perform_ra_svn_log(svn_error_t **outer_e if (item->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Log entry not a list")); - SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, iterpool, + SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, iterpool, "lr(?s)(?s)(?s)?BBnl?B", &cplist, &rev, &author, &date, &message, &has_children_param, @@ -1742,13 +1742,12 @@ perform_ra_svn_log(svn_error_t **outer_e const char *copy_path, *action, *kind_str; apr_uint64_t text_mods, prop_mods; svn_revnum_t copy_rev; - svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(cplist, i, - svn_ra_svn_item_t); + svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(cplist, i); if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Changed-path entry not a list")); - SVN_ERR(svn_ra_svn__read_data_log_changed_entry(elt->u.list, + SVN_ERR(svn_ra_svn__read_data_log_changed_entry(&elt->u.list, &cpath, &action, ©_path, ©_rev, &kind_str, &text_mods, &prop_mods)); @@ -1897,7 +1896,7 @@ static svn_error_t *ra_svn_stat(svn_ra_s { svn_ra_svn__session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; - apr_array_header_t *list = NULL; + svn_ra_svn__list_t *list = NULL; svn_dirent_t *the_dirent; SVN_ERR(svn_ra_svn__write_cmd_stat(conn, pool, path, rev)); @@ -1968,7 +1967,7 @@ static svn_error_t *ra_svn_get_locations *locations = apr_hash_make(pool); while (!is_done) { - svn_ra_svn_item_t *item; + svn_ra_svn__item_t *item; const char *ret_path; SVN_ERR(svn_ra_svn__read_item(conn, pool, &item)); @@ -1979,7 +1978,7 @@ static svn_error_t *ra_svn_get_locations _("Location entry not a list")); else { - SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, pool, "rc", + SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, pool, "rc", &revision, &ret_path)); ret_path = svn_fspath__canonicalize(ret_path, pool); apr_hash_set(*locations, apr_pmemdup(pool, &revision, @@ -2024,7 +2023,7 @@ perform_get_location_segments(svn_error_ while (!is_done) { svn_revnum_t range_start, range_end; - svn_ra_svn_item_t *item; + svn_ra_svn__item_t *item; const char *ret_path; svn_pool_clear(iterpool); @@ -2038,7 +2037,7 @@ perform_get_location_segments(svn_error_ { svn_location_segment_t *segment = apr_pcalloc(iterpool, sizeof(*segment)); - SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, iterpool, "rr(?c)", + SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, iterpool, "rr(?c)", &range_start, &range_end, &ret_path)); if (! (SVN_IS_VALID_REVNUM(range_start) && SVN_IS_VALID_REVNUM(range_end))) @@ -2118,10 +2117,10 @@ static svn_error_t *ra_svn_get_file_revs while (1) { - apr_array_header_t *rev_proplist, *proplist; + svn_ra_svn__list_t *rev_proplist, *proplist; apr_uint64_t merged_rev_param; apr_array_header_t *props; - svn_ra_svn_item_t *item; + svn_ra_svn__item_t *item; apr_hash_t *rev_props; svn_revnum_t rev; const char *p; @@ -2140,7 +2139,7 @@ static svn_error_t *ra_svn_get_file_revs return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Revision entry not a list")); - SVN_ERR(svn_ra_svn__parse_tuple(item->u.list, rev_pool, + SVN_ERR(svn_ra_svn__parse_tuple(&item->u.list, rev_pool, "crll?B", &p, &rev, &rev_proplist, &proplist, &merged_rev_param)); p = svn_fspath__canonicalize(p, rev_pool); @@ -2156,7 +2155,7 @@ static svn_error_t *ra_svn_get_file_revs if (item->kind != SVN_RA_SVN_STRING) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Text delta chunk not a string")); - has_txdelta = item->u.string->len > 0; + has_txdelta = item->u.string.len > 0; SVN_ERR(handler(handler_baton, p, rev, rev_props, merged_rev, has_txdelta ? &d_handler : NULL, &d_baton, @@ -2172,13 +2171,13 @@ static svn_error_t *ra_svn_get_file_revs rev_pool); else stream = NULL; - while (item->u.string->len > 0) + while (item->u.string.len > 0) { apr_size_t size; - size = item->u.string->len; + size = item->u.string.len; if (stream) - SVN_ERR(svn_stream_write(stream, item->u.string->data, &size)); + SVN_ERR(svn_stream_write(stream, item->u.string.data, &size)); svn_pool_clear(chunk_pool); SVN_ERR(svn_ra_svn__read_item(sess_baton->conn, chunk_pool, @@ -2220,7 +2219,7 @@ static svn_error_t *ra_svn_lock_compat(s { svn_ra_svn__session_baton_t *sess = session->priv; svn_ra_svn_conn_t* conn = sess->conn; - apr_array_header_t *list; + svn_ra_svn__list_t *list; apr_hash_index_t *hi; apr_pool_t *iterpool = svn_pool_create(pool); @@ -2291,7 +2290,7 @@ static svn_error_t *ra_svn_unlock_compat const void *key; const char *path; void *val; - const char *token; + const svn_string_t *token; svn_error_t *err, *callback_err = NULL; svn_pool_clear(iterpool); @@ -2299,7 +2298,7 @@ static svn_error_t *ra_svn_unlock_compat apr_hash_this(hi, &key, NULL, &val); path = key; if (strcmp(val, "") != 0) - token = val; + token = svn_string_create(val, iterpool); else token = NULL; @@ -2383,13 +2382,13 @@ static svn_error_t *ra_svn_lock(svn_ra_s /* Loop over responses to get lock information. */ for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi)) { - svn_ra_svn_item_t *elt; + svn_ra_svn__item_t *elt; const void *key; const char *path; svn_error_t *callback_err; const char *status; svn_lock_t *lock; - apr_array_header_t *list; + svn_ra_svn__list_t *list; apr_hash_this(hi, &key, NULL, NULL); path = key; @@ -2408,7 +2407,7 @@ static svn_error_t *ra_svn_lock(svn_ra_s return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Lock response not a list")); - SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool, "wl", &status, + SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, iterpool, "wl", &status, &list)); if (strcmp(status, "failure") == 0) @@ -2439,7 +2438,7 @@ static svn_error_t *ra_svn_lock(svn_ra_s read the final "done" from the server. */ if (!hi) { - svn_ra_svn_item_t *elt; + svn_ra_svn__item_t *elt; SVN_ERR(svn_ra_svn__read_item(conn, pool, &elt)); if (elt->kind != SVN_RA_SVN_WORD || strcmp(elt->u.word, "done") != 0) @@ -2512,11 +2511,11 @@ static svn_error_t *ra_svn_unlock(svn_ra /* Loop over responses to unlock files. */ for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi)) { - svn_ra_svn_item_t *elt; + svn_ra_svn__item_t *elt; const void *key; svn_error_t *callback_err; const char *status; - apr_array_header_t *list; + svn_ra_svn__list_t *list; svn_pool_clear(iterpool); @@ -2536,7 +2535,7 @@ static svn_error_t *ra_svn_unlock(svn_ra return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Unlock response not a list")); - SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool, "wl", &status, + SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, iterpool, "wl", &status, &list)); if (strcmp(status, "failure") == 0) @@ -2566,7 +2565,7 @@ static svn_error_t *ra_svn_unlock(svn_ra read the final "done" from the server. */ if (!hi) { - svn_ra_svn_item_t *elt; + svn_ra_svn__item_t *elt; SVN_ERR(svn_ra_svn__read_item(conn, pool, &elt)); if (elt->kind != SVN_RA_SVN_WORD || strcmp(elt->u.word, "done") != 0) @@ -2589,7 +2588,7 @@ static svn_error_t *ra_svn_get_lock(svn_ { svn_ra_svn__session_baton_t *sess = session->priv; svn_ra_svn_conn_t* conn = sess->conn; - apr_array_header_t *list; + svn_ra_svn__list_t *list; SVN_ERR(svn_ra_svn__write_cmd_get_lock(conn, pool, path)); @@ -2634,7 +2633,7 @@ static svn_error_t *ra_svn_get_locks(svn { svn_ra_svn__session_baton_t *sess = session->priv; svn_ra_svn_conn_t* conn = sess->conn; - apr_array_header_t *list; + svn_ra_svn__list_t *list; const char *full_url, *abs_path; int i; @@ -2657,12 +2656,12 @@ static svn_error_t *ra_svn_get_locks(svn for (i = 0; i < list->nelts; ++i) { svn_lock_t *lock; - svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t); + svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(list, i); if (elt->kind != SVN_RA_SVN_LIST) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Lock element not a list")); - SVN_ERR(parse_lock(elt->u.list, pool, &lock)); + SVN_ERR(parse_lock(&elt->u.list, pool, &lock)); /* Filter out unwanted paths. Since Subversion only allows locks on files, we can treat depth=immediates the same as @@ -2745,7 +2744,7 @@ ra_svn_replay_range(svn_ra_session_t *se void *edit_baton; apr_hash_t *rev_props; const char *word; - apr_array_header_t *list; + svn_ra_svn__list_t *list; svn_pool_clear(iterpool); @@ -2877,7 +2876,7 @@ ra_svn_get_inherited_props(svn_ra_sessio { svn_ra_svn__session_baton_t *sess_baton = session->priv; svn_ra_svn_conn_t *conn = sess_baton->conn; - apr_array_header_t *iproplist; + svn_ra_svn__list_t *iproplist; svn_boolean_t iprop_capable; SVN_ERR(ra_svn_has_capability(session, &iprop_capable, Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cram.c Fri Sep 11 15:51:30 2015 @@ -140,7 +140,7 @@ svn_error_t *svn_ra_svn_cram_server(svn_ char hostbuf[APRMAXHOSTLEN + 1]; unsigned char cdigest[APR_MD5_DIGESTSIZE], sdigest[APR_MD5_DIGESTSIZE]; const char *challenge, *sep, *password; - svn_ra_svn_item_t *item; + svn_ra_svn__item_t *item; svn_string_t *resp; *success = FALSE; @@ -160,7 +160,7 @@ svn_error_t *svn_ra_svn_cram_server(svn_ SVN_ERR(svn_ra_svn__read_item(conn, pool, &item)); if (item->kind != SVN_RA_SVN_STRING) /* Very wrong; don't report failure */ return SVN_NO_ERROR; - resp = item->u.string; + resp = &item->u.string; sep = strrchr(resp->data, ' '); if (!sep || resp->len - (sep + 1 - resp->data) != APR_MD5_DIGESTSIZE * 2 || !hex_decode(cdigest, sep + 1)) Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/cyrus_auth.c Fri Sep 11 15:51:30 2015 @@ -828,7 +828,7 @@ svn_error_t *svn_ra_svn__get_addresses(c svn_error_t * svn_ra_svn__do_cyrus_auth(svn_ra_svn__session_baton_t *sess, - const apr_array_header_t *mechlist, + const svn_ra_svn__list_t *mechlist, const char *realm, apr_pool_t *pool) { apr_pool_t *subpool; @@ -856,7 +856,7 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__se /* Create a string containing the list of mechanisms, separated by spaces. */ for (i = 0; i < mechlist->nelts; i++) { - svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(mechlist, i, svn_ra_svn_item_t); + svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(mechlist, i); mechstring = apr_pstrcat(pool, mechstring, i == 0 ? "" : " ", Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/deprecated.c Fri Sep 11 15:51:30 2015 @@ -110,7 +110,12 @@ svn_ra_svn_read_item(svn_ra_svn_conn_t * apr_pool_t *pool, svn_ra_svn_item_t **item) { - return svn_error_trace(svn_ra_svn__read_item(conn, pool, item)); + svn_ra_svn__item_t *temp; + SVN_ERR(svn_ra_svn__read_item(conn, pool, &temp)); + *item = apr_pcalloc(pool, sizeof(**item)); + svn_ra_svn__to_public_item(*item, temp, pool); + + return SVN_NO_ERROR; } svn_error_t * @@ -127,9 +132,10 @@ svn_ra_svn_parse_tuple(const apr_array_h { va_list va; svn_error_t *err; + svn_ra_svn__list_t *internal = svn_ra_svn__to_private_array(list, pool); va_start(va, fmt); - err = svn_ra_svn__parse_tuple(list, pool, fmt, va); + err = svn_ra_svn__parse_tuple(internal, pool, fmt, va); va_end(va); return svn_error_trace(err); @@ -155,7 +161,9 @@ svn_ra_svn_parse_proplist(const apr_arra apr_pool_t *pool, apr_hash_t **props) { - return svn_error_trace(svn_ra_svn__parse_proplist(list, pool, props)); + svn_ra_svn__list_t *internal + = svn_ra_svn__to_private_array(list, pool); + return svn_error_trace(svn_ra_svn__parse_proplist(internal, pool, props)); } svn_error_t * @@ -180,8 +188,23 @@ svn_ra_svn_handle_commands2(svn_ra_svn_c void *baton, svn_boolean_t error_on_disconnect) { + apr_size_t i, count = 0; + svn_ra_svn__cmd_entry_t *internal; + + while (commands[count].cmdname) + count++; + + internal = apr_pcalloc(pool, count * sizeof(*internal)); + for (i = 0; i < count; ++i) + { + internal[i].cmdname = commands[i].cmdname; + internal[i].handler = NULL; + internal[i].deprecated_handler = commands[i].handler; + internal[i].terminate = commands[i].terminate; + } + return svn_error_trace(svn_ra_svn__handle_commands2(conn, pool, - commands, baton, + internal, baton, error_on_disconnect)); } @@ -191,9 +214,9 @@ svn_ra_svn_handle_commands(svn_ra_svn_co const svn_ra_svn_cmd_entry_t *commands, void *baton) { - return svn_error_trace(svn_ra_svn__handle_commands2(conn, pool, - commands, baton, - FALSE)); + return svn_error_trace(svn_ra_svn_handle_commands2(conn, pool, + commands, baton, + FALSE)); } svn_error_t * Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c Fri Sep 11 15:51:30 2015 @@ -39,8 +39,11 @@ #include "svn_pools.h" #include "svn_private_config.h" +#include "private/svn_atomic.h" #include "private/svn_fspath.h" #include "private/svn_editor.h" +#include "private/svn_string_private.h" +#include "private/svn_subr_private.h" #include "ra_svn.h" @@ -57,7 +60,7 @@ typedef struct ra_svn_edit_baton_t { svn_ra_svn_conn_t *conn; svn_ra_svn_edit_callback callback; /* Called on successful completion. */ void *callback_baton; - int next_token; + apr_uint64_t next_token; svn_boolean_t got_status; } ra_svn_edit_baton_t; @@ -66,13 +69,19 @@ typedef struct ra_svn_baton_t { svn_ra_svn_conn_t *conn; apr_pool_t *pool; ra_svn_edit_baton_t *eb; - const char *token; + svn_string_t *token; } ra_svn_baton_t; +/* Forward declaration. */ +typedef struct ra_svn_token_entry_t ra_svn_token_entry_t; + typedef struct ra_svn_driver_state_t { const svn_delta_editor_t *editor; void *edit_baton; apr_hash_t *tokens; + + /* Entry for the last token seen. May be NULL. */ + ra_svn_token_entry_t *last_token; svn_boolean_t *aborted; svn_boolean_t done; apr_pool_t *pool; @@ -90,26 +99,33 @@ typedef struct ra_svn_driver_state_t { field in this structure is vestigial for files, and we use it for a different purpose instead: at apply-textdelta time, we set it to a subpool of the file pool, which is destroyed in textdelta-end. */ -typedef struct ra_svn_token_entry_t { +struct ra_svn_token_entry_t { svn_string_t *token; void *baton; svn_boolean_t is_file; svn_stream_t *dstream; /* svndiff stream for apply_textdelta */ apr_pool_t *pool; -} ra_svn_token_entry_t; +}; /* --- CONSUMING AN EDITOR BY PASSING EDIT OPERATIONS OVER THE NET --- */ -static const char *make_token(char type, ra_svn_edit_baton_t *eb, - apr_pool_t *pool) -{ - return apr_psprintf(pool, "%c%d", type, eb->next_token++); +static svn_string_t * +make_token(char type, + ra_svn_edit_baton_t *eb, + apr_pool_t *pool) +{ + apr_size_t len; + char buffer[1 + SVN_INT64_BUFFER_SIZE]; + buffer[0] = type; + len = 1 + svn__ui64toa(&buffer[1], eb->next_token++); + + return svn_string_ncreate(buffer, len, pool); } static ra_svn_baton_t *ra_svn_make_baton(svn_ra_svn_conn_t *conn, apr_pool_t *pool, ra_svn_edit_baton_t *eb, - const char *token) + svn_string_t *token) { ra_svn_baton_t *b; @@ -171,7 +187,7 @@ static svn_error_t *ra_svn_open_root(voi apr_pool_t *pool, void **root_baton) { ra_svn_edit_baton_t *eb = edit_baton; - const char *token = make_token('d', eb, pool); + svn_string_t *token = make_token('d', eb, pool); SVN_ERR(check_for_error(eb, pool)); SVN_ERR(svn_ra_svn__write_cmd_open_root(eb->conn, pool, rev, token)); @@ -196,7 +212,7 @@ static svn_error_t *ra_svn_add_dir(const apr_pool_t *pool, void **child_baton) { ra_svn_baton_t *b = parent_baton; - const char *token = make_token('d', b->eb, pool); + svn_string_t *token = make_token('d', b->eb, pool); SVN_ERR_ASSERT((copy_path && SVN_IS_VALID_REVNUM(copy_rev)) || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev))); @@ -212,7 +228,7 @@ static svn_error_t *ra_svn_open_dir(cons void **child_baton) { ra_svn_baton_t *b = parent_baton; - const char *token = make_token('d', b->eb, pool); + svn_string_t *token = make_token('d', b->eb, pool); SVN_ERR(check_for_error(b->eb, pool)); SVN_ERR(svn_ra_svn__write_cmd_open_dir(b->conn, pool, path, b->token, @@ -265,7 +281,7 @@ static svn_error_t *ra_svn_add_file(cons void **file_baton) { ra_svn_baton_t *b = parent_baton; - const char *token = make_token('c', b->eb, pool); + svn_string_t *token = make_token('c', b->eb, pool); SVN_ERR_ASSERT((copy_path && SVN_IS_VALID_REVNUM(copy_rev)) || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev))); @@ -283,7 +299,7 @@ static svn_error_t *ra_svn_open_file(con void **file_baton) { ra_svn_baton_t *b = parent_baton; - const char *token = make_token('c', b->eb, pool); + svn_string_t *token = make_token('c', b->eb, pool); SVN_ERR(check_for_error(b->eb, b->pool)); SVN_ERR(svn_ra_svn__write_cmd_open_file(b->conn, pool, path, b->token, @@ -480,6 +496,7 @@ static ra_svn_token_entry_t *store_token entry->pool = pool; apr_hash_set(ds->tokens, entry->token->data, entry->token->len, entry); + ds->last_token = entry; return entry; } @@ -489,17 +506,39 @@ static svn_error_t *lookup_token(ra_svn_ svn_boolean_t is_file, ra_svn_token_entry_t **entry) { - *entry = apr_hash_get(ds->tokens, token->data, token->len); + if (ds->last_token && svn_string_compare(ds->last_token->token, token)) + { + *entry = ds->last_token; + } + else + { + *entry = apr_hash_get(ds->tokens, token->data, token->len); + ds->last_token = *entry; + } + if (!*entry || (*entry)->is_file != is_file) return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, _("Invalid file or dir token during edit")); return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_target_rev(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +/* Remove a TOKEN entry from DS. */ +static void remove_token(ra_svn_driver_state_t *ds, + svn_string_t *token) +{ + apr_hash_set(ds->tokens, token->data, token->len, NULL); + + /* Reset this unconditionally. In most cases, LAST_TOKEN->TOKEN will + match TOKEN anyway and if it doesn't, lookup_token() will suffer only + a minor performance hit. */ + ds->last_token = NULL; +} + +static svn_error_t * +ra_svn_handle_target_rev(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_revnum_t rev; @@ -508,10 +547,11 @@ static svn_error_t *ra_svn_handle_target return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_open_root(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_open_root(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_revnum_t rev; apr_pool_t *subpool; @@ -526,10 +566,11 @@ static svn_error_t *ra_svn_handle_open_r return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_delete_entry(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_delete_entry(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *path; svn_string_t *token; @@ -544,10 +585,11 @@ static svn_error_t *ra_svn_handle_delete return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_add_dir(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_add_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *path, *copy_path; svn_string_t *token, *child_token; @@ -578,10 +620,11 @@ static svn_error_t *ra_svn_handle_add_di return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_open_dir(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_open_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *path; svn_string_t *token, *child_token; @@ -601,10 +644,11 @@ static svn_error_t *ra_svn_handle_open_d return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_change_dir_prop(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_change_dir_prop(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_string_t *token; const char *name; @@ -619,10 +663,11 @@ static svn_error_t *ra_svn_handle_change return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_close_dir(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_close_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_string_t *token; ra_svn_token_entry_t *entry; @@ -633,15 +678,16 @@ static svn_error_t *ra_svn_handle_close_ /* Close the directory and destroy the baton. */ SVN_CMD_ERR(ds->editor->close_directory(entry->baton, pool)); - apr_hash_set(ds->tokens, token->data, token->len, NULL); + remove_token(ds, token); svn_pool_destroy(entry->pool); return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_absent_dir(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_absent_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *path; svn_string_t *token; @@ -656,10 +702,11 @@ static svn_error_t *ra_svn_handle_absent return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_add_file(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_add_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *path, *copy_path; svn_string_t *token, *file_token; @@ -691,10 +738,11 @@ static svn_error_t *ra_svn_handle_add_fi return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_open_file(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_open_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *path; svn_string_t *token, *file_token; @@ -716,10 +764,11 @@ static svn_error_t *ra_svn_handle_open_f return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_apply_textdelta(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_apply_textdelta(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_string_t *token; ra_svn_token_entry_t *entry; @@ -741,10 +790,11 @@ static svn_error_t *ra_svn_handle_apply_ return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_textdelta_chunk(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_textdelta_chunk(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_string_t *token; ra_svn_token_entry_t *entry; @@ -760,10 +810,11 @@ static svn_error_t *ra_svn_handle_textde return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_textdelta_end(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_textdelta_end(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_string_t *token; ra_svn_token_entry_t *entry; @@ -780,10 +831,11 @@ static svn_error_t *ra_svn_handle_textde return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_change_file_prop(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_change_file_prop(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *name; svn_string_t *token, *value; @@ -796,10 +848,11 @@ static svn_error_t *ra_svn_handle_change return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_close_file(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_close_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { svn_string_t *token; ra_svn_token_entry_t *entry; @@ -812,16 +865,17 @@ static svn_error_t *ra_svn_handle_close_ /* Close the file and destroy the baton. */ SVN_CMD_ERR(ds->editor->close_file(entry->baton, text_checksum, pool)); - apr_hash_set(ds->tokens, token->data, token->len, NULL); + remove_token(ds, token); if (--ds->file_refs == 0) svn_pool_clear(ds->file_pool); return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_absent_file(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_absent_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { const char *path; svn_string_t *token; @@ -836,10 +890,11 @@ static svn_error_t *ra_svn_handle_absent return SVN_NO_ERROR; } -static svn_error_t *ra_svn_handle_close_edit(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_close_edit(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { SVN_CMD_ERR(ds->editor->close_edit(ds->edit_baton, pool)); ds->done = TRUE; @@ -856,10 +911,11 @@ static svn_error_t *ra_svn_handle_close_ return svn_ra_svn__write_cmd_response(conn, pool, ""); } -static svn_error_t *ra_svn_handle_abort_edit(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_abort_edit(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { ds->done = TRUE; if (ds->aborted) @@ -868,10 +924,11 @@ static svn_error_t *ra_svn_handle_abort_ return svn_ra_svn__write_cmd_response(conn, pool, ""); } -static svn_error_t *ra_svn_handle_finish_replay(svn_ra_svn_conn_t *conn, - apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds) +static svn_error_t * +ra_svn_handle_finish_replay(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds) { if (!ds->for_replay) return svn_error_createf @@ -883,11 +940,15 @@ static svn_error_t *ra_svn_handle_finish return SVN_NO_ERROR; } +/* Common function signature for all editor command handlers. */ +typedef svn_error_t *(*cmd_handler_t)(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn__list_t *params, + ra_svn_driver_state_t *ds); + static const struct { const char *cmd; - svn_error_t *(*handler)(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - const apr_array_header_t *params, - ra_svn_driver_state_t *ds); + cmd_handler_t handler; } ra_svn_edit_cmds[] = { { "change-file-prop", ra_svn_handle_change_file_prop }, { "open-file", ra_svn_handle_open_file }, @@ -911,12 +972,98 @@ static const struct { { NULL } }; +/* All editor commands are kept in a collision-free hash table. */ + +/* Hash table entry. + It is similar to ra_svn_edit_cmds but uses our SVN string type. */ +typedef struct cmd_t { + svn_string_t cmd; + cmd_handler_t handler; +} cmd_t; + +/* The actual hash table. It will be filled once before first usage. + + If you add more commands, you may have to tweak the table size to + eliminate collisions. Alternatively, you may modify the hash function. + + Be sure to initialize all elements with 0 as the has conflict detection + will rely on it (see init_cmd_hash). + */ +#define CMD_HASH_SIZE 67 +static cmd_t cmd_hash[CMD_HASH_SIZE] = { { { NULL } } }; + +/* Init flag that controls CMD_HASH's atomic initialization. */ +static volatile svn_atomic_t cmd_hash_initialized = FALSE; + +/* Super-fast hash function that works very well with the structure of our + command words. It produces no conflicts for them. + + Return the index within CMD_HASH that a command NAME of LEN chars would + be found. LEN > 0. + */ +static apr_size_t +cmd_hash_func(const char *name, + apr_size_t len) +{ + apr_size_t value = (apr_byte_t)(name[0] - 'a') % 8 + + 1 * (apr_byte_t)(name[len - 1] - 'a') % 8 + + 10 * (len - 7); + return value % CMD_HASH_SIZE; +} + +/* svn_atomic__init_once callback that fills the CMD_HASH table. It will + error out on hash collisions. BATON and POOL are not used. */ +static svn_error_t * +init_cmd_hash(void *baton, + apr_pool_t *pool) +{ + int i; + for (i = 0; ra_svn_edit_cmds[i].cmd; i++) + { + apr_size_t len = strlen(ra_svn_edit_cmds[i].cmd); + apr_size_t value = cmd_hash_func(ra_svn_edit_cmds[i].cmd, len); + SVN_ERR_ASSERT(cmd_hash[value].cmd.data == NULL); + + cmd_hash[value].cmd.data = ra_svn_edit_cmds[i].cmd; + cmd_hash[value].cmd.len = len; + cmd_hash[value].handler = ra_svn_edit_cmds[i].handler; + } + + return SVN_NO_ERROR; +} + +/* Return the command handler function for the command name CMD. + Return NULL if no such handler exists */ +static cmd_handler_t +cmd_lookup(const char *cmd) +{ + apr_size_t value; + apr_size_t len = strlen(cmd); + + /* Malicious data that our hash function may not like? */ + if (len == 0) + return NULL; + + /* Hash lookup. */ + value = cmd_hash_func(cmd, len); + + /* Hit? */ + if (cmd_hash[value].cmd.len != len) + return NULL; + + if (memcmp(cmd_hash[value].cmd.data, cmd, len)) + return NULL; + + /* Yes! */ + return cmd_hash[value].handler; +} + static svn_error_t *blocked_write(svn_ra_svn_conn_t *conn, apr_pool_t *pool, void *baton) { ra_svn_driver_state_t *ds = baton; const char *cmd; - apr_array_header_t *params; + svn_ra_svn__list_t *params; /* We blocked trying to send an error. Read and discard an editing * command in order to avoid deadlock. */ @@ -939,13 +1086,16 @@ svn_error_t *svn_ra_svn_drive_editor2(sv ra_svn_driver_state_t state; apr_pool_t *subpool = svn_pool_create(pool); const char *cmd; - int i; svn_error_t *err, *write_err; - apr_array_header_t *params; + svn_ra_svn__list_t *params; + + SVN_ERR(svn_atomic__init_once(&cmd_hash_initialized, init_cmd_hash, NULL, + pool)); state.editor = editor; state.edit_baton = edit_baton; - state.tokens = apr_hash_make(pool); + state.tokens = svn_hash__make(pool); + state.last_token = NULL; state.aborted = aborted; state.done = FALSE; state.pool = pool; @@ -958,13 +1108,12 @@ svn_error_t *svn_ra_svn_drive_editor2(sv svn_pool_clear(subpool); if (editor) { + cmd_handler_t handler; SVN_ERR(svn_ra_svn__read_tuple(conn, subpool, "wl", &cmd, ¶ms)); - for (i = 0; ra_svn_edit_cmds[i].cmd; i++) - if (strcmp(cmd, ra_svn_edit_cmds[i].cmd) == 0) - break; + handler = cmd_lookup(cmd); - if (ra_svn_edit_cmds[i].cmd) - err = (*ra_svn_edit_cmds[i].handler)(conn, subpool, params, &state); + if (handler) + err = (*handler)(conn, subpool, params, &state); else if (strcmp(cmd, "failure") == 0) { /* While not really an editor command this can occur when Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c?rev=1702504&r1=1702503&r2=1702504&view=diff ============================================================================== --- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c (original) +++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/internal_auth.c Fri Sep 11 15:51:30 2015 @@ -37,15 +37,15 @@ #include "ra_svn.h" -svn_boolean_t svn_ra_svn__find_mech(const apr_array_header_t *mechlist, +svn_boolean_t svn_ra_svn__find_mech(const svn_ra_svn__list_t *mechlist, const char *mech) { int i; - svn_ra_svn_item_t *elt; + svn_ra_svn__item_t *elt; for (i = 0; i < mechlist->nelts; i++) { - elt = &APR_ARRAY_IDX(mechlist, i, svn_ra_svn_item_t); + elt = &SVN_RA_SVN__LIST_ITEM(mechlist, i); if (elt->kind == SVN_RA_SVN_WORD && strcmp(elt->u.word, mech) == 0) return TRUE; } @@ -69,7 +69,7 @@ static svn_error_t *read_success(svn_ra_ svn_error_t * svn_ra_svn__do_internal_auth(svn_ra_svn__session_baton_t *sess, - const apr_array_header_t *mechlist, + const svn_ra_svn__list_t *mechlist, const char *realm, apr_pool_t *pool) { svn_ra_svn_conn_t *conn = sess->conn;
