From commits-return-49776-archive-asf-public=cust-asf.ponee.io@subversion.apache.org Wed Nov 7 13:30:24 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id E96BF1807A5 for ; Wed, 7 Nov 2018 13:30:20 +0100 (CET) Received: (qmail 19287 invoked by uid 500); 7 Nov 2018 12:30:19 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 19006 invoked by uid 99); 7 Nov 2018 12:30:19 -0000 Received: from Unknown (HELO svn01-us-west.apache.org) (209.188.14.144) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Nov 2018 12:30:19 +0000 Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 817B73A2579 for ; Wed, 7 Nov 2018 12:30:18 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1846002 [10/44] - in /subversion/branches/ra-git: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ build/generator/util/ build/win32/ contrib/client-side/ contrib/client-side/svn_load_dirs/ contr... Date: Wed, 07 Nov 2018 12:30:11 -0000 To: commits@subversion.apache.org From: rhuijben@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20181107123018.817B73A2579@svn01-us-west.apache.org> Modified: subversion/branches/ra-git/subversion/libsvn_delta/cancel.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_delta/cancel.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_delta/cancel.c (original) +++ subversion/branches/ra-git/subversion/libsvn_delta/cancel.c Wed Nov 7 12:30:06 2018 @@ -222,6 +222,26 @@ apply_textdelta(void *file_baton, } static svn_error_t * +apply_textdelta_stream(const svn_delta_editor_t *editor, + void *file_baton, + const char *base_checksum, + svn_txdelta_stream_open_func_t open_func, + void *open_baton, + apr_pool_t *scratch_pool) +{ + struct file_baton *fb = file_baton; + struct edit_baton *eb = fb->edit_baton; + + SVN_ERR(eb->cancel_func(eb->cancel_baton)); + + return eb->wrapped_editor->apply_textdelta_stream(eb->wrapped_editor, + fb->wrapped_file_baton, + base_checksum, + open_func, open_baton, + scratch_pool); +} + +static svn_error_t * close_file(void *file_baton, const char *text_checksum, apr_pool_t *pool) @@ -354,6 +374,7 @@ svn_delta_get_cancellation_editor(svn_ca tree_editor->add_file = add_file; tree_editor->open_file = open_file; tree_editor->apply_textdelta = apply_textdelta; + tree_editor->apply_textdelta_stream = apply_textdelta_stream; tree_editor->change_file_prop = change_file_prop; tree_editor->close_file = close_file; tree_editor->absent_file = absent_file; Modified: subversion/branches/ra-git/subversion/libsvn_delta/debug_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_delta/debug_editor.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_delta/debug_editor.c (original) +++ subversion/branches/ra-git/subversion/libsvn_delta/debug_editor.c Wed Nov 7 12:30:06 2018 @@ -71,9 +71,11 @@ set_target_revision(void *edit_baton, SVN_ERR(svn_stream_printf(eb->out, pool, "set_target_revision : %ld\n", target_revision)); - return eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton, - target_revision, - pool); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton, + target_revision, + pool)); + return SVN_NO_ERROR; } static svn_error_t * @@ -90,10 +92,11 @@ open_root(void *edit_baton, base_revision)); eb->indent_level++; - SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton, - base_revision, - pool, - &dir_baton->wrapped_dir_baton)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton, + base_revision, + pool, + &dir_baton->wrapped_dir_baton)); dir_baton->edit_baton = edit_baton; @@ -115,10 +118,12 @@ delete_entry(const char *path, SVN_ERR(svn_stream_printf(eb->out, pool, "delete_entry : %s:%ld\n", path, base_revision)); - return eb->wrapped_editor->delete_entry(path, - base_revision, - pb->wrapped_dir_baton, - pool); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->delete_entry(path, + base_revision, + pb->wrapped_dir_baton, + pool)); + return SVN_NO_ERROR; } static svn_error_t * @@ -139,12 +144,13 @@ add_directory(const char *path, path, copyfrom_path, copyfrom_revision)); eb->indent_level++; - SVN_ERR(eb->wrapped_editor->add_directory(path, - pb->wrapped_dir_baton, - copyfrom_path, - copyfrom_revision, - pool, - &b->wrapped_dir_baton)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->add_directory(path, + pb->wrapped_dir_baton, + copyfrom_path, + copyfrom_revision, + pool, + &b->wrapped_dir_baton)); b->edit_baton = eb; *child_baton = b; @@ -168,11 +174,12 @@ open_directory(const char *path, path, base_revision)); eb->indent_level++; - SVN_ERR(eb->wrapped_editor->open_directory(path, - pb->wrapped_dir_baton, - base_revision, - pool, - &db->wrapped_dir_baton)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->open_directory(path, + pb->wrapped_dir_baton, + base_revision, + pool, + &db->wrapped_dir_baton)); db->edit_baton = eb; *child_baton = db; @@ -199,12 +206,13 @@ add_file(const char *path, eb->indent_level++; - SVN_ERR(eb->wrapped_editor->add_file(path, - pb->wrapped_dir_baton, - copyfrom_path, - copyfrom_revision, - pool, - &fb->wrapped_file_baton)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->add_file(path, + pb->wrapped_dir_baton, + copyfrom_path, + copyfrom_revision, + pool, + &fb->wrapped_file_baton)); fb->edit_baton = eb; *file_baton = fb; @@ -229,11 +237,12 @@ open_file(const char *path, eb->indent_level++; - SVN_ERR(eb->wrapped_editor->open_file(path, - pb->wrapped_dir_baton, - base_revision, - pool, - &fb->wrapped_file_baton)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->open_file(path, + pb->wrapped_dir_baton, + base_revision, + pool, + &fb->wrapped_file_baton)); fb->edit_baton = eb; *file_baton = fb; @@ -255,11 +264,38 @@ apply_textdelta(void *file_baton, SVN_ERR(svn_stream_printf(eb->out, pool, "apply_textdelta : %s\n", base_checksum)); - SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton, - base_checksum, - pool, - handler, - handler_baton)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton, + base_checksum, + pool, + handler, + handler_baton)); + + return SVN_NO_ERROR; +} + +static svn_error_t * +apply_textdelta_stream(const struct svn_delta_editor_t *editor, + void *file_baton, + const char *base_checksum, + svn_txdelta_stream_open_func_t open_func, + void *open_baton, + apr_pool_t *scratch_pool) +{ + struct file_baton *fb = file_baton; + struct edit_baton *eb = fb->edit_baton; + + SVN_ERR(write_indent(eb, scratch_pool)); + SVN_ERR(svn_stream_printf(eb->out, scratch_pool, + "apply_textdelta_stream : %s\n", + base_checksum)); + + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->apply_textdelta_stream(eb->wrapped_editor, + fb->wrapped_file_baton, + base_checksum, + open_func, open_baton, + scratch_pool)); return SVN_NO_ERROR; } @@ -278,8 +314,9 @@ close_file(void *file_baton, SVN_ERR(svn_stream_printf(eb->out, pool, "close_file : %s\n", text_checksum)); - SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton, - text_checksum, pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton, + text_checksum, pool)); return SVN_NO_ERROR; } @@ -295,8 +332,9 @@ absent_file(const char *path, SVN_ERR(write_indent(eb, pool)); SVN_ERR(svn_stream_printf(eb->out, pool, "absent_file : %s\n", path)); - SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton, - pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton, + pool)); return SVN_NO_ERROR; } @@ -312,8 +350,9 @@ close_directory(void *dir_baton, SVN_ERR(write_indent(eb, pool)); SVN_ERR(svn_stream_printf(eb->out, pool, "close_directory\n")); - SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton, - pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton, + pool)); return SVN_NO_ERROR; } @@ -330,8 +369,9 @@ absent_directory(const char *path, SVN_ERR(svn_stream_printf(eb->out, pool, "absent_directory : %s\n", path)); - SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton, - pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton, + pool)); return SVN_NO_ERROR; } @@ -349,10 +389,11 @@ change_file_prop(void *file_baton, SVN_ERR(svn_stream_printf(eb->out, pool, "change_file_prop : %s -> %s\n", name, value ? value->data : "")); - SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton, - name, - value, - pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton, + name, + value, + pool)); return SVN_NO_ERROR; } @@ -370,10 +411,11 @@ change_dir_prop(void *dir_baton, SVN_ERR(svn_stream_printf(eb->out, pool, "change_dir_prop : %s -> %s\n", name, value ? value->data : "")); - SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton, - name, - value, - pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton, + name, + value, + pool)); return SVN_NO_ERROR; } @@ -387,7 +429,8 @@ close_edit(void *edit_baton, SVN_ERR(write_indent(eb, pool)); SVN_ERR(svn_stream_printf(eb->out, pool, "close_edit\n")); - SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool)); return SVN_NO_ERROR; } @@ -401,7 +444,8 @@ abort_edit(void *edit_baton, SVN_ERR(write_indent(eb, pool)); SVN_ERR(svn_stream_printf(eb->out, pool, "abort_edit\n")); - SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool)); + if (eb->wrapped_editor) + SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool)); return SVN_NO_ERROR; } @@ -414,7 +458,7 @@ svn_delta__get_debug_editor(const svn_de const char *prefix, apr_pool_t *pool) { - svn_delta_editor_t *tree_editor = apr_palloc(pool, sizeof(*tree_editor)); + svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool); struct edit_baton *eb = apr_palloc(pool, sizeof(*eb)); apr_file_t *errfp; svn_stream_t *out; @@ -436,6 +480,7 @@ svn_delta__get_debug_editor(const svn_de tree_editor->add_file = add_file; tree_editor->open_file = open_file; tree_editor->apply_textdelta = apply_textdelta; + tree_editor->apply_textdelta_stream = apply_textdelta_stream; tree_editor->change_file_prop = change_file_prop; tree_editor->close_file = close_file; tree_editor->absent_file = absent_file; Modified: subversion/branches/ra-git/subversion/libsvn_delta/default_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_delta/default_editor.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_delta/default_editor.c (original) +++ subversion/branches/ra-git/subversion/libsvn_delta/default_editor.c Wed Nov 7 12:30:06 2018 @@ -133,6 +133,33 @@ close_file(void *file_baton, } +static svn_error_t * +apply_textdelta_stream(const svn_delta_editor_t *editor, + void *file_baton, + const char *base_checksum, + svn_txdelta_stream_open_func_t open_func, + void *open_baton, + apr_pool_t *scratch_pool) +{ + svn_txdelta_window_handler_t handler; + void *handler_baton; + + SVN_ERR(editor->apply_textdelta(file_baton, base_checksum, + scratch_pool, &handler, + &handler_baton)); + if (handler != svn_delta_noop_window_handler) + { + svn_txdelta_stream_t *txdelta_stream; + + SVN_ERR(open_func(&txdelta_stream, open_baton, scratch_pool, + scratch_pool)); + SVN_ERR(svn_txdelta_send_txstream(txdelta_stream, handler, + handler_baton, scratch_pool)); + } + + return SVN_NO_ERROR; +} + static const svn_delta_editor_t default_editor = { @@ -151,7 +178,8 @@ static const svn_delta_editor_t default_ close_file, absent_xxx_func, single_baton_func, - single_baton_func + single_baton_func, + apply_textdelta_stream }; svn_delta_editor_t * Modified: subversion/branches/ra-git/subversion/libsvn_delta/element.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_delta/element.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_delta/element.c (original) +++ subversion/branches/ra-git/subversion/libsvn_delta/element.c Wed Nov 7 12:30:06 2018 @@ -375,14 +375,12 @@ svn_element__tree_get(const svn_element_ return svn_eid__hash_get(tree->e_map, eid); } -svn_error_t * +void svn_element__tree_set(svn_element__tree_t *tree, int eid, const svn_element__content_t *element) { svn_eid__hash_set(tree->e_map, eid, element); - - return SVN_NO_ERROR; } void Modified: subversion/branches/ra-git/subversion/libsvn_delta/svndiff.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_delta/svndiff.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_delta/svndiff.c (original) +++ subversion/branches/ra-git/subversion/libsvn_delta/svndiff.c Wed Nov 7 12:30:06 2018 @@ -38,13 +38,16 @@ static const char SVNDIFF_V0[] = { 'S', 'V', 'N', 0 }; static const char SVNDIFF_V1[] = { 'S', 'V', 'N', 1 }; +static const char SVNDIFF_V2[] = { 'S', 'V', 'N', 2 }; #define SVNDIFF_HEADER_SIZE (sizeof(SVNDIFF_V0)) static const char * get_svndiff_header(int version) { - if (version == 1) + if (version == 2) + return SVNDIFF_V2; + else if (version == 1) return SVNDIFF_V1; else return SVNDIFF_V0; @@ -148,7 +151,7 @@ send_simple_insertion_window(svn_txdelta } /* Encodes delta window WINDOW to svndiff-format. - The svndiff version is VERSION. COMPRESSION_LEVEL is the zlib + The svndiff version is VERSION. COMPRESSION_LEVEL is the compression level to use. Returned values will be allocated in POOL or refer to *WINDOW fields. */ @@ -195,21 +198,39 @@ encode_window(svn_stringbuf_t **instruct append_encoded_int(header, window->sview_offset); append_encoded_int(header, window->sview_len); append_encoded_int(header, window->tview_len); - if (version == 1) + if (version == 2) { svn_stringbuf_t *compressed_instructions; compressed_instructions = svn_stringbuf_create_empty(pool); - SVN_ERR(svn__compress(instructions->data, instructions->len, - compressed_instructions, compression_level)); + SVN_ERR(svn__compress_lz4(instructions->data, instructions->len, + compressed_instructions)); + instructions = compressed_instructions; + } + else if (version == 1) + { + svn_stringbuf_t *compressed_instructions; + compressed_instructions = svn_stringbuf_create_empty(pool); + SVN_ERR(svn__compress_zlib(instructions->data, instructions->len, + compressed_instructions, compression_level)); instructions = compressed_instructions; } append_encoded_int(header, instructions->len); - if (version == 1) + + /* Encode the data. */ + if (version == 2) + { + svn_stringbuf_t *compressed = svn_stringbuf_create_empty(pool); + + SVN_ERR(svn__compress_lz4(window->new_data->data, window->new_data->len, + compressed)); + newdata = svn_stringbuf__morph_into_string(compressed); + } + else if (version == 1) { svn_stringbuf_t *compressed = svn_stringbuf_create_empty(pool); - SVN_ERR(svn__compress(window->new_data->data, window->new_data->len, - compressed, compression_level)); + SVN_ERR(svn__compress_zlib(window->new_data->data, window->new_data->len, + compressed, compression_level)); newdata = svn_stringbuf__morph_into_string(compressed); } else @@ -224,6 +245,8 @@ encode_window(svn_stringbuf_t **instruct return SVN_NO_ERROR; } +/* Note: When changing things here, check the related comment in + the svn_txdelta_to_svndiff_stream() function. */ static svn_error_t * window_handler(svn_txdelta_window_t *window, void *baton) { @@ -542,15 +565,31 @@ decode_window(svn_txdelta_window_t *wind insend = data + inslen; - if (version == 1) + if (version == 2) + { + svn_stringbuf_t *instout = svn_stringbuf_create_empty(pool); + svn_stringbuf_t *ndout = svn_stringbuf_create_empty(pool); + + SVN_ERR(svn__decompress_lz4(insend, newlen, ndout, + SVN_DELTA_WINDOW_SIZE)); + SVN_ERR(svn__decompress_lz4(data, insend - data, instout, + MAX_INSTRUCTION_SECTION_LEN)); + + newlen = ndout->len; + data = (unsigned char *)instout->data; + insend = (unsigned char *)instout->data + instout->len; + + new_data = svn_stringbuf__morph_into_string(ndout); + } + else if (version == 1) { svn_stringbuf_t *instout = svn_stringbuf_create_empty(pool); svn_stringbuf_t *ndout = svn_stringbuf_create_empty(pool); - SVN_ERR(svn__decompress(insend, newlen, ndout, - SVN_DELTA_WINDOW_SIZE)); - SVN_ERR(svn__decompress(data, insend - data, instout, - MAX_INSTRUCTION_SECTION_LEN)); + SVN_ERR(svn__decompress_zlib(insend, newlen, ndout, + SVN_DELTA_WINDOW_SIZE)); + SVN_ERR(svn__decompress_zlib(data, insend - data, instout, + MAX_INSTRUCTION_SECTION_LEN)); newlen = ndout->len; data = (unsigned char *)instout->data; @@ -612,6 +651,8 @@ write_handler(void *baton, db->version = 0; else if (memcmp(buffer, SVNDIFF_V1 + db->header_bytes, nheader) == 0) db->version = 1; + else if (memcmp(buffer, SVNDIFF_V2 + db->header_bytes, nheader) == 0) + db->version = 2; else return svn_error_create(SVN_ERR_SVNDIFF_INVALID_HEADER, NULL, _("Svndiff has invalid header")); @@ -954,3 +995,107 @@ svn_txdelta__read_raw_window_len(apr_siz return SVN_NO_ERROR; } +typedef struct svndiff_stream_baton_t +{ + apr_pool_t *scratch_pool; + svn_txdelta_stream_t *txstream; + svn_txdelta_window_handler_t handler; + void *handler_baton; + svn_stringbuf_t *window_buffer; + apr_size_t read_pos; + svn_boolean_t hit_eof; +} svndiff_stream_baton_t; + +static svn_error_t * +svndiff_stream_write_fn(void *baton, const char *data, apr_size_t *len) +{ + svndiff_stream_baton_t *b = baton; + + /* The memory usage here is limited, as this buffer doesn't grow + beyond the (header size + max window size in svndiff format). + See the comment in svn_txdelta_to_svndiff_stream(). */ + svn_stringbuf_appendbytes(b->window_buffer, data, *len); + + return SVN_NO_ERROR; +} + +static svn_error_t * +svndiff_stream_read_fn(void *baton, char *buffer, apr_size_t *len) +{ + svndiff_stream_baton_t *b = baton; + apr_size_t left = *len; + apr_size_t read = 0; + + while (left) + { + apr_size_t chunk_size; + + if (b->read_pos == b->window_buffer->len && !b->hit_eof) + { + svn_txdelta_window_t *window; + + svn_pool_clear(b->scratch_pool); + svn_stringbuf_setempty(b->window_buffer); + SVN_ERR(svn_txdelta_next_window(&window, b->txstream, + b->scratch_pool)); + SVN_ERR(b->handler(window, b->handler_baton)); + b->read_pos = 0; + + if (!window) + b->hit_eof = TRUE; + } + + if (left > b->window_buffer->len - b->read_pos) + chunk_size = b->window_buffer->len - b->read_pos; + else + chunk_size = left; + + if (!chunk_size) + break; + + memcpy(buffer, b->window_buffer->data + b->read_pos, chunk_size); + b->read_pos += chunk_size; + buffer += chunk_size; + read += chunk_size; + left -= chunk_size; + } + + *len = read; + return SVN_NO_ERROR; +} + +svn_stream_t * +svn_txdelta_to_svndiff_stream(svn_txdelta_stream_t *txstream, + int svndiff_version, + int compression_level, + apr_pool_t *pool) +{ + svndiff_stream_baton_t *baton; + svn_stream_t *push_stream; + svn_stream_t *pull_stream; + + baton = apr_pcalloc(pool, sizeof(*baton)); + baton->scratch_pool = svn_pool_create(pool); + baton->txstream = txstream; + baton->window_buffer = svn_stringbuf_create_empty(pool); + baton->hit_eof = FALSE; + baton->read_pos = 0; + + push_stream = svn_stream_create(baton, pool); + svn_stream_set_write(push_stream, svndiff_stream_write_fn); + + /* We rely on the implementation detail of the svn_txdelta_to_svndiff3() + function, namely, on how the window_handler() function behaves. + As long as it writes one svndiff window at a time to the target + stream, the memory usage of this function (in other words, how + much data can be accumulated in the internal 'window_buffer') + is limited. */ + svn_txdelta_to_svndiff3(&baton->handler, &baton->handler_baton, + push_stream, svndiff_version, + compression_level, pool); + + pull_stream = svn_stream_create(baton, pool); + svn_stream_set_read2(pull_stream, NULL, svndiff_stream_read_fn); + + return pull_stream; +} Modified: subversion/branches/ra-git/subversion/libsvn_delta/text_delta.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_delta/text_delta.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_delta/text_delta.c (original) +++ subversion/branches/ra-git/subversion/libsvn_delta/text_delta.c Wed Nov 7 12:30:06 2018 @@ -102,7 +102,7 @@ struct apply_baton { char *tbuf; /* Target buffer */ apr_size_t tbuf_size; /* Allocated target buffer space */ - apr_md5_ctx_t md5_context; /* Leads to result_digest below. */ + svn_checksum_ctx_t *md5_context; /* Leads to result_digest below. */ unsigned char *result_digest; /* MD5 digest of resultant fulltext; must point to at least APR_MD5_DIGESTSIZE bytes of storage. */ @@ -720,15 +720,23 @@ apply_window(svn_txdelta_window_t *windo { struct apply_baton *ab = (struct apply_baton *) baton; apr_size_t len; - svn_error_t *err; if (window == NULL) { + svn_error_t *err = SVN_NO_ERROR; + /* We're done; just clean up. */ if (ab->result_digest) - apr_md5_final(ab->result_digest, &(ab->md5_context)); + { + svn_checksum_t *md5_checksum; + + err = svn_checksum_final(&md5_checksum, ab->md5_context, ab->pool); + if (!err) + memcpy(ab->result_digest, md5_checksum->digest, + svn_checksum_size(md5_checksum)); + } - err = svn_stream_close(ab->target); + err = svn_error_compose_create(err, svn_stream_close(ab->target)); svn_pool_destroy(ab->pool); return err; @@ -772,12 +780,10 @@ apply_window(svn_txdelta_window_t *windo if (ab->sbuf_len < window->sview_len) { len = window->sview_len - ab->sbuf_len; - err = svn_stream_read_full(ab->source, ab->sbuf + ab->sbuf_len, &len); - if (err == SVN_NO_ERROR && len != window->sview_len - ab->sbuf_len) - err = svn_error_create(SVN_ERR_INCOMPLETE_DATA, NULL, - "Delta source ended unexpectedly"); - if (err != SVN_NO_ERROR) - return err; + SVN_ERR(svn_stream_read_full(ab->source, ab->sbuf + ab->sbuf_len, &len)); + if (len != window->sview_len - ab->sbuf_len) + return svn_error_create(SVN_ERR_INCOMPLETE_DATA, NULL, + "Delta source ended unexpectedly"); ab->sbuf_len = window->sview_len; } @@ -791,7 +797,7 @@ apply_window(svn_txdelta_window_t *windo /* Just update the context here. */ if (ab->result_digest) - apr_md5_update(&(ab->md5_context), ab->tbuf, len); + SVN_ERR(svn_checksum_update(ab->md5_context, ab->tbuf, len)); return svn_stream_write(ab->target, ab->tbuf, &len); } @@ -822,7 +828,7 @@ svn_txdelta_apply(svn_stream_t *source, ab->result_digest = result_digest; if (result_digest) - apr_md5_init(&(ab->md5_context)); + ab->md5_context = svn_checksum_ctx_create(svn_checksum_md5, subpool); if (error_info) ab->error_info = apr_pstrdup(subpool, error_info); Modified: subversion/branches/ra-git/subversion/libsvn_diff/diff3.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_diff/diff3.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_diff/diff3.c (original) +++ subversion/branches/ra-git/subversion/libsvn_diff/diff3.c Wed Nov 7 12:30:06 2018 @@ -325,7 +325,6 @@ svn_diff_diff3_2(svn_diff_t **diff, /* Produce a merged diff */ { svn_diff_t **diff_ref = diff; - svn_diff_t *diff_last = NULL; apr_off_t original_start = 1; apr_off_t modified_start = 1; @@ -435,7 +434,6 @@ svn_diff_diff3_2(svn_diff_t **diff, if (is_modified || is_latest) { - svn_boolean_t add_diff = TRUE; modified_length = modified_sync - modified_start; latest_length = latest_sync - latest_start; @@ -456,41 +454,17 @@ svn_diff_diff3_2(svn_diff_t **diff, &position_list[2], num_tokens, pool); - /* add_diff = TRUE */ } - else if (is_modified - && (!diff_last - || diff_last->type != svn_diff__type_diff_latest)) + else if (is_modified) { (*diff_ref)->type = svn_diff__type_diff_modified; - /* add_diff = TRUE */ - } - else if (is_latest - && (!diff_last - || diff_last->type != svn_diff__type_diff_modified)) - { - (*diff_ref)->type = svn_diff__type_diff_latest; - /* add_diff = TRUE */ } else { - /* We have a latest and a modified region that touch each other, - but not directly change the same location. Create a single - conflict region to properly mark a conflict, and to ease - resolving. */ - diff_last->type = svn_diff__type_conflict; - diff_last->original_length += (*diff_ref)->original_length; - diff_last->modified_length += (*diff_ref)->modified_length; - diff_last->latest_length += (*diff_ref)->latest_length; - - add_diff = FALSE; + (*diff_ref)->type = svn_diff__type_diff_latest; } - if (add_diff) - { - diff_last = *diff_ref; - diff_ref = &(*diff_ref)->next; - } + diff_ref = &(*diff_ref)->next; } /* Detect EOF */ @@ -516,7 +490,6 @@ svn_diff_diff3_2(svn_diff_t **diff, (*diff_ref)->latest_length = common_length; (*diff_ref)->resolved_diff = NULL; - diff_last = *diff_ref; diff_ref = &(*diff_ref)->next; } Modified: subversion/branches/ra-git/subversion/libsvn_diff/diff_tree.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_diff/diff_tree.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_diff/diff_tree.c (original) +++ subversion/branches/ra-git/subversion/libsvn_diff/diff_tree.c Wed Nov 7 12:30:06 2018 @@ -37,14 +37,6 @@ #include "private/svn_diff_tree.h" #include "svn_private_config.h" -typedef struct tree_processor_t -{ - svn_diff_tree_processor_t tp; - - /* void *future_extension */ -} tree_processor_t; - - static svn_error_t * default_dir_opened(void **new_dir_baton, svn_boolean_t *skip, @@ -215,33 +207,30 @@ svn_diff_tree_processor_t * svn_diff__tree_processor_create(void *baton, apr_pool_t *result_pool) { - tree_processor_t *wrapper; - wrapper = apr_pcalloc(result_pool, sizeof(*wrapper)); + svn_diff_tree_processor_t *tp = apr_pcalloc(result_pool, sizeof(*tp)); - wrapper->tp.baton = baton; + tp->baton = baton; - wrapper->tp.dir_opened = default_dir_opened; - wrapper->tp.dir_added = default_dir_added; - wrapper->tp.dir_deleted = default_dir_deleted; - wrapper->tp.dir_changed = default_dir_changed; - wrapper->tp.dir_closed = default_dir_closed; + tp->dir_opened = default_dir_opened; + tp->dir_added = default_dir_added; + tp->dir_deleted = default_dir_deleted; + tp->dir_changed = default_dir_changed; + tp->dir_closed = default_dir_closed; - wrapper->tp.file_opened = default_file_opened; - wrapper->tp.file_added = default_file_added; - wrapper->tp.file_deleted = default_file_deleted; - wrapper->tp.file_changed = default_file_changed; - wrapper->tp.file_closed = default_file_closed; + tp->file_opened = default_file_opened; + tp->file_added = default_file_added; + tp->file_deleted = default_file_deleted; + tp->file_changed = default_file_changed; + tp->file_closed = default_file_closed; - wrapper->tp.node_absent = default_node_absent; + tp->node_absent = default_node_absent; - - return &wrapper->tp; + return tp; } struct reverse_tree_baton_t { const svn_diff_tree_processor_t *processor; - const char *prefix_relpath; }; static svn_error_t * @@ -259,9 +248,6 @@ reverse_dir_opened(void **new_dir_baton, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_opened(new_dir_baton, skip, skip_children, relpath, right_source, left_source, @@ -284,9 +270,6 @@ reverse_dir_added(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_deleted(relpath, right_source, right_props, @@ -307,9 +290,6 @@ reverse_dir_deleted(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_added(relpath, NULL, left_source, @@ -335,9 +315,6 @@ reverse_dir_changed(const char *relpath, struct reverse_tree_baton_t *rb = processor->baton; apr_array_header_t *reversed_prop_changes = NULL; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - if (prop_changes) { SVN_ERR_ASSERT(left_props != NULL && right_props != NULL); @@ -367,9 +344,6 @@ reverse_dir_closed(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_closed(relpath, right_source, left_source, @@ -393,9 +367,6 @@ reverse_file_opened(void **new_file_bato { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_opened(new_file_baton, skip, relpath, @@ -423,9 +394,6 @@ reverse_file_added(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_deleted(relpath, right_source, right_file, @@ -447,9 +415,6 @@ reverse_file_deleted(const char *relpath { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_added(relpath, NULL /* copyfrom src */, left_source, @@ -480,9 +445,6 @@ reverse_file_changed(const char *relpath struct reverse_tree_baton_t *rb = processor->baton; apr_array_header_t *reversed_prop_changes = NULL; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - if (prop_changes) { SVN_ERR_ASSERT(left_props != NULL && right_props != NULL); @@ -515,9 +477,6 @@ reverse_file_closed(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_closed(relpath, right_source, left_source, @@ -536,9 +495,6 @@ reverse_node_absent(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->node_absent(relpath, dir_baton, rb->processor, @@ -549,7 +505,6 @@ reverse_node_absent(const char *relpath, const svn_diff_tree_processor_t * svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * processor, - const char *prefix_relpath, apr_pool_t *result_pool) { struct reverse_tree_baton_t *rb; @@ -557,8 +512,6 @@ svn_diff__tree_processor_reverse_create( rb = apr_pcalloc(result_pool, sizeof(*rb)); rb->processor = processor; - if (prefix_relpath) - rb->prefix_relpath = apr_pstrdup(result_pool, prefix_relpath); reverse = svn_diff__tree_processor_create(rb, result_pool); Modified: subversion/branches/ra-git/subversion/libsvn_diff/parse-diff.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_diff/parse-diff.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_diff/parse-diff.c (original) +++ subversion/branches/ra-git/subversion/libsvn_diff/parse-diff.c Wed Nov 7 12:30:06 2018 @@ -69,6 +69,11 @@ struct svn_diff_hunk_t { /* APR file handle to the patch file this hunk came from. */ apr_file_t *apr_file; + /* Whether the hunk was interpreted as pretty-print mergeinfo. If so, + the hunk content is in PATCH and the rest of this hunk object is + mostly uninitialized. */ + svn_boolean_t is_pretty_print_mergeinfo; + /* Ranges used to keep track of this hunk's texts positions within * the patch file. */ struct svn_diff__hunk_range diff_text_range; @@ -899,10 +904,6 @@ parse_prop_name(const char **prop_name, * The hunk header has the following format: * ## -0,NUMBER_OF_REVERSE_MERGES +0,NUMBER_OF_FORWARD_MERGES ## * - * At this point, the number of reverse merges has already been - * parsed into HUNK->ORIGINAL_LENGTH, and the number of forward - * merges has been parsed into HUNK->MODIFIED_LENGTH. - * * The header is followed by a list of mergeinfo, one path per line. * This function parses such lines. Lines describing reverse merges * appear first, and then all lines describing forward merges appear. @@ -914,18 +915,27 @@ parse_prop_name(const char **prop_name, * ":r", which in turn is followed by a mergeinfo revision range, * which is terminated by whitespace or end-of-string. * - * If the current line meets the above criteria and we're able - * to parse valid mergeinfo from it, the resulting mergeinfo - * is added to patch->mergeinfo or patch->reverse_mergeinfo, - * and we proceed to the next line. + * *NUMBER_OF_REVERSE_MERGES and *NUMBER_OF_FORWARD_MERGES are the + * numbers of reverse and forward merges remaining to be read. This + * function decrements *NUMBER_OF_REVERSE_MERGES for each LINE + * parsed until that is zero, then *NUMBER_OF_FORWARD_MERGES for + * each LINE parsed until that is zero. If both are zero, it parses + * and discards LINE. + * + * If LINE is successfully parsed, *FOUND_MERGEINFO is set to TRUE, + * otherwise to FALSE. + * + * If LINE is successfully parsed and counted, the resulting mergeinfo + * is added to PATCH->mergeinfo or PATCH->reverse_mergeinfo. */ static svn_error_t * -parse_mergeinfo(svn_boolean_t *found_mergeinfo, - svn_stringbuf_t *line, - svn_diff_hunk_t *hunk, - svn_patch_t *patch, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +parse_pretty_mergeinfo_line(svn_boolean_t *found_mergeinfo, + svn_linenum_t *number_of_reverse_merges, + svn_linenum_t *number_of_forward_merges, + svn_stringbuf_t *line, + svn_patch_t *patch, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { char *slash = strchr(line->data, '/'); char *colon = strrchr(line->data, ':'); @@ -972,7 +982,7 @@ parse_mergeinfo(svn_boolean_t *found_mer if (mergeinfo) { - if (hunk->original_length > 0) /* reverse merges */ + if (*number_of_reverse_merges > 0) /* reverse merges */ { if (patch->reverse) { @@ -994,9 +1004,9 @@ parse_mergeinfo(svn_boolean_t *found_mer result_pool, scratch_pool)); } - hunk->original_length--; + (*number_of_reverse_merges)--; } - else if (hunk->modified_length > 0) /* forward merges */ + else if (number_of_forward_merges > 0) /* forward merges */ { if (patch->reverse) { @@ -1018,7 +1028,7 @@ parse_mergeinfo(svn_boolean_t *found_mer result_pool, scratch_pool)); } - hunk->modified_length--; + (*number_of_forward_merges)--; } *found_mergeinfo = TRUE; @@ -1165,18 +1175,48 @@ parse_next_hunk(svn_diff_hunk_t **hunk, if (in_hunk && *is_property && *prop_name && strcmp(*prop_name, SVN_PROP_MERGEINFO) == 0) { - svn_boolean_t found_mergeinfo; + svn_boolean_t found_pretty_mergeinfo_line; - SVN_ERR(parse_mergeinfo(&found_mergeinfo, line, *hunk, patch, - result_pool, iterpool)); - if (found_mergeinfo) - continue; /* Proceed to the next line in the svn:mergeinfo hunk. */ - else + if (! hunk_seen) + { + /* We're reading the first line of the hunk, so the start + * of the line just read is the hunk text's byte offset. */ + start = last_line; + } + + SVN_ERR(parse_pretty_mergeinfo_line(&found_pretty_mergeinfo_line, + &original_lines, &modified_lines, + line, patch, + result_pool, iterpool)); + if (found_pretty_mergeinfo_line) { - /* Perhaps we can also use original_lines/modified_lines here */ + hunk_seen = TRUE; + (*hunk)->is_pretty_print_mergeinfo = TRUE; + continue; /* Proceed to the next line in the svn:mergeinfo hunk. */ + } - in_hunk = FALSE; /* On to next property */ + if ((*hunk)->is_pretty_print_mergeinfo) + { + /* We have reached the end of the pretty-print-mergeinfo hunk. + (This format uses only one hunk.) */ + if (eof) + { + /* The hunk ends at EOF. */ + end = pos; + } + else + { + /* The start of the current line marks the first byte + * after the hunk text. */ + end = last_line; + } + original_end = end; + modified_end = end; + break; } + + /* Otherwise, this is a property diff in the + regular format so fall through to normal processing. */ } if (in_hunk) @@ -1971,10 +2011,10 @@ parse_hunks(svn_patch_t *patch, apr_file else last_prop_name = prop_name; - /* Skip svn:mergeinfo properties. - * Mergeinfo data cannot be represented as a hunk and + /* Skip pretty-printed svn:mergeinfo property hunks. + * Pretty-printed mergeinfo data cannot be represented as a hunk and * is therefore stored in PATCH itself. */ - if (strcmp(prop_name, SVN_PROP_MERGEINFO) == 0) + if (hunk->is_pretty_print_mergeinfo) continue; SVN_ERR(add_property_hunk(patch, prop_name, hunk, prop_operation, Modified: subversion/branches/ra-git/subversion/libsvn_fs/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs/deprecated.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs/deprecated.c (original) +++ subversion/branches/ra-git/subversion/libsvn_fs/deprecated.c Wed Nov 7 12:30:06 2018 @@ -28,6 +28,7 @@ #include #include "svn_fs.h" +#include "private/svn_subr_private.h" /*** From fs-loader.c ***/ @@ -130,6 +131,45 @@ svn_fs_node_history(svn_fs_history_t **h pool, pool)); } +static svn_error_t * +mergeinfo_receiver(const char *path, + svn_mergeinfo_t mergeinfo, + void *baton, + apr_pool_t *scratch_pool) +{ + svn_mergeinfo_catalog_t catalog = baton; + apr_pool_t *result_pool = apr_hash_pool_get(catalog); + apr_size_t len = strlen(path); + + apr_hash_set(catalog, + apr_pstrmemdup(result_pool, path, len), + len, + svn_mergeinfo_dup(mergeinfo, result_pool)); + + return SVN_NO_ERROR; +} + +svn_error_t * +svn_fs_get_mergeinfo2(svn_mergeinfo_catalog_t *catalog, + svn_fs_root_t *root, + const apr_array_header_t *paths, + svn_mergeinfo_inheritance_t inherit, + svn_boolean_t include_descendants, + svn_boolean_t adjust_inherited_mergeinfo, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_mergeinfo_catalog_t result_catalog = svn_hash__make(result_pool); + SVN_ERR(svn_fs_get_mergeinfo3(root, paths, inherit, + include_descendants, + adjust_inherited_mergeinfo, + mergeinfo_receiver, result_catalog, + scratch_pool)); + *catalog = result_catalog; + + return SVN_NO_ERROR; +} + svn_error_t * svn_fs_get_mergeinfo(svn_mergeinfo_catalog_t *catalog, svn_fs_root_t *root, Modified: subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.c (original) +++ subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.c Wed Nov 7 12:30:06 2018 @@ -89,7 +89,7 @@ struct fs_type_defn { const char *fs_type; const char *fsap_name; fs_init_func_t initfunc; - fs_library_vtable_t *vtable; + void * volatile vtable; /* fs_library_vtable_t */ struct fs_type_defn *next; }; @@ -202,7 +202,7 @@ get_library_vtable_direct(fs_library_vta const svn_version_t *fs_version; /* most times, we get lucky */ - *vtable = apr_atomic_casptr((volatile void **)&fst->vtable, NULL, NULL); + *vtable = svn_atomic_casptr(&fst->vtable, NULL, NULL); if (*vtable) return SVN_NO_ERROR; @@ -245,7 +245,7 @@ get_library_vtable_direct(fs_library_vta fs_version->patch, fs_version->tag); /* the vtable will not change. Remember it */ - apr_atomic_casptr((volatile void **)&fst->vtable, *vtable, NULL); + svn_atomic_casptr(&fst->vtable, *vtable, NULL); return SVN_NO_ERROR; } @@ -1391,18 +1391,38 @@ svn_fs_closest_copy(svn_fs_root_t **root } svn_error_t * -svn_fs_get_mergeinfo2(svn_mergeinfo_catalog_t *catalog, - svn_fs_root_t *root, +svn_fs_get_mergeinfo3(svn_fs_root_t *root, const apr_array_header_t *paths, svn_mergeinfo_inheritance_t inherit, svn_boolean_t include_descendants, svn_boolean_t adjust_inherited_mergeinfo, - apr_pool_t *result_pool, + svn_fs_mergeinfo_receiver_t receiver, + void *baton, apr_pool_t *scratch_pool) { return svn_error_trace(root->vtable->get_mergeinfo( - catalog, root, paths, inherit, include_descendants, - adjust_inherited_mergeinfo, result_pool, scratch_pool)); + root, paths, inherit, include_descendants, adjust_inherited_mergeinfo, + receiver, baton, scratch_pool)); +} + +/* Baton type to be used with mergeinfo_receiver(). It provides some of + * the parameters passed to svn_fs__get_mergeinfo_for_path. */ +typedef struct mergeinfo_receiver_baton_t +{ + svn_mergeinfo_t *mergeinfo; + apr_pool_t *result_pool; +} mergeinfo_receiver_baton_t; + +static svn_error_t * +mergeinfo_receiver(const char *path, + svn_mergeinfo_t mergeinfo, + void *baton, + apr_pool_t *scratch_pool) +{ + mergeinfo_receiver_baton_t *b = baton; + *b->mergeinfo = svn_mergeinfo_dup(mergeinfo, b->result_pool); + + return SVN_NO_ERROR; } svn_error_t * @@ -1416,15 +1436,19 @@ svn_fs__get_mergeinfo_for_path(svn_merge { apr_array_header_t *paths = apr_array_make(scratch_pool, 1, sizeof(const char *)); - svn_mergeinfo_catalog_t catalog; + + mergeinfo_receiver_baton_t baton; + baton.mergeinfo = mergeinfo; + baton.result_pool = result_pool; APR_ARRAY_PUSH(paths, const char *) = path; - SVN_ERR(svn_fs_get_mergeinfo2(&catalog, root, paths, + *mergeinfo = NULL; + SVN_ERR(svn_fs_get_mergeinfo3(root, paths, inherit, FALSE /*include_descendants*/, adjust_inherited_mergeinfo, - result_pool, scratch_pool)); - *mergeinfo = svn_hash_gets(catalog, path); + mergeinfo_receiver, &baton, + scratch_pool)); return SVN_NO_ERROR; } Modified: subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.h URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.h?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.h (original) +++ subversion/branches/ra-git/subversion/libsvn_fs/fs-loader.h Wed Nov 7 12:30:06 2018 @@ -420,13 +420,13 @@ typedef struct root_vtable_t const char *ancestor_path, apr_pool_t *pool); /* Mergeinfo. */ - svn_error_t *(*get_mergeinfo)(svn_mergeinfo_catalog_t *catalog, - svn_fs_root_t *root, + svn_error_t *(*get_mergeinfo)(svn_fs_root_t *root, const apr_array_header_t *paths, svn_mergeinfo_inheritance_t inherit, svn_boolean_t include_descendants, svn_boolean_t adjust_inherited_mergeinfo, - apr_pool_t *result_pool, + svn_fs_mergeinfo_receiver_t receiver, + void *baton, apr_pool_t *scratch_pool); } root_vtable_t; Modified: subversion/branches/ra-git/subversion/libsvn_fs_base/fs.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_base/fs.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs_base/fs.c (original) +++ subversion/branches/ra-git/subversion/libsvn_fs_base/fs.c Wed Nov 7 12:30:06 2018 @@ -957,6 +957,7 @@ base_upgrade(svn_fs_t *fs, err = SVN_NO_ERROR; } SVN_ERR(err); + SVN_ERR(check_format(old_format_number)); /* Bump the format file's stored version number. */ SVN_ERR(svn_io_write_version_file(version_file_path, Modified: subversion/branches/ra-git/subversion/libsvn_fs_base/tree.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_base/tree.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs_base/tree.c (original) +++ subversion/branches/ra-git/subversion/libsvn_fs_base/tree.c Wed Nov 7 12:30:06 2018 @@ -5074,8 +5074,8 @@ base_node_origin_rev(svn_revnum_t *revis /* Examine directory NODE's immediately children for mergeinfo. - For those which have explicit mergeinfo, add their mergeinfo to - RESULT_CATALOG (allocated in RESULT_CATALOG's pool). + For those which have explicit mergeinfo, invoke RECEIVER with + RECEIVER_BATON. For those which don't, but sit atop trees which contain mergeinfo somewhere deeper, add them to *CHILDREN_ATOP_MERGEINFO_TREES, a @@ -5089,10 +5089,11 @@ base_node_origin_rev(svn_revnum_t *revis struct get_mergeinfo_data_and_entries_baton { - svn_mergeinfo_catalog_t result_catalog; apr_hash_t *children_atop_mergeinfo_trees; dag_node_t *node; const char *node_path; + svn_fs_mergeinfo_receiver_t receiver; + void *receiver_baton; }; static svn_error_t * @@ -5103,7 +5104,6 @@ txn_body_get_mergeinfo_data_and_entries( apr_hash_t *entries; apr_hash_index_t *hi; apr_pool_t *iterpool = svn_pool_create(trail->pool); - apr_pool_t *result_pool = apr_hash_pool_get(args->result_catalog); apr_pool_t *children_pool = apr_hash_pool_get(args->children_atop_mergeinfo_trees); @@ -5157,7 +5157,7 @@ txn_body_get_mergeinfo_data_and_entries( CHILD_NODE then treat it as if no mergeinfo is present rather than raising a parse error. */ err = svn_mergeinfo_parse(&child_mergeinfo, pval->data, - result_pool); + iterpool); if (err) { if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR) @@ -5167,10 +5167,12 @@ txn_body_get_mergeinfo_data_and_entries( } else { - svn_hash_sets(args->result_catalog, - svn_fspath__join(args->node_path, dirent->name, - result_pool), - child_mergeinfo); + SVN_ERR(args->receiver(svn_fspath__join(args->node_path, + dirent->name, + iterpool), + child_mergeinfo, + args->receiver_baton, + iterpool)); } } @@ -5204,7 +5206,8 @@ static svn_error_t * crawl_directory_for_mergeinfo(svn_fs_t *fs, dag_node_t *node, const char *node_path, - svn_mergeinfo_catalog_t result_catalog, + svn_fs_mergeinfo_receiver_t receiver, + void *baton, apr_pool_t *pool) { struct get_mergeinfo_data_and_entries_baton gmdae_args; @@ -5214,10 +5217,11 @@ crawl_directory_for_mergeinfo(svn_fs_t * /* Add mergeinfo for immediate children that have it, and fetch immediate children that *don't* have it but sit atop trees that do. */ - gmdae_args.result_catalog = result_catalog; gmdae_args.children_atop_mergeinfo_trees = children_atop_mergeinfo_trees; gmdae_args.node = node; gmdae_args.node_path = node_path; + gmdae_args.receiver = receiver; + gmdae_args.receiver_baton = baton; SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_get_mergeinfo_data_and_entries, &gmdae_args, FALSE, pool)); @@ -5239,7 +5243,7 @@ crawl_directory_for_mergeinfo(svn_fs_t * SVN_ERR(crawl_directory_for_mergeinfo(fs, val, svn_fspath__join(node_path, key, iterpool), - result_catalog, iterpool)); + receiver, baton, iterpool)); } svn_pool_destroy(iterpool); return SVN_NO_ERROR; @@ -5397,20 +5401,21 @@ txn_body_get_node_mergeinfo_stats(void * } -/* Get the mergeinfo for a set of paths, returned in - *MERGEINFO_CATALOG. Returned values are allocated in POOL, while - temporary values are allocated in a sub-pool. */ +/* Find all the mergeinfo for a set of PATHS under ROOT and report it + through RECEIVER with BATON. INHERITED, INCLUDE_DESCENDANTS and + ADJUST_INHERITED_MERGEINFO are the same as in the FS API. + + Allocate temporary values are allocated in SCRATCH_POOL. */ static svn_error_t * get_mergeinfos_for_paths(svn_fs_root_t *root, - svn_mergeinfo_catalog_t *mergeinfo_catalog, const apr_array_header_t *paths, svn_mergeinfo_inheritance_t inherit, svn_boolean_t include_descendants, svn_boolean_t adjust_inherited_mergeinfo, - apr_pool_t *result_pool, + svn_fs_mergeinfo_receiver_t receiver, + void *baton, apr_pool_t *scratch_pool) { - svn_mergeinfo_catalog_t result_catalog = apr_hash_make(result_pool); apr_pool_t *iterpool = svn_pool_create(scratch_pool); int i; @@ -5429,14 +5434,13 @@ get_mergeinfos_for_paths(svn_fs_root_t * gmfp_args.root = root; gmfp_args.path = path; gmfp_args.inherit = inherit; - gmfp_args.pool = result_pool; + gmfp_args.pool = iterpool; gmfp_args.adjust_inherited_mergeinfo = adjust_inherited_mergeinfo; SVN_ERR(svn_fs_base__retry_txn(root->fs, txn_body_get_mergeinfo_for_path, &gmfp_args, FALSE, iterpool)); if (path_mergeinfo) - svn_hash_sets(result_catalog, apr_pstrdup(result_pool, path), - path_mergeinfo); + SVN_ERR(receiver(path, path_mergeinfo, baton, iterpool)); /* If we're including descendants, do so. */ if (include_descendants) @@ -5462,26 +5466,25 @@ get_mergeinfos_for_paths(svn_fs_root_t * /* If it's worth crawling, crawl. */ if (do_crawl) SVN_ERR(crawl_directory_for_mergeinfo(root->fs, gnms_args.node, - path, result_catalog, + path, receiver, baton, iterpool)); } } svn_pool_destroy(iterpool); - *mergeinfo_catalog = result_catalog; return SVN_NO_ERROR; } /* Implements svn_fs_get_mergeinfo. */ static svn_error_t * -base_get_mergeinfo(svn_mergeinfo_catalog_t *catalog, - svn_fs_root_t *root, +base_get_mergeinfo(svn_fs_root_t *root, const apr_array_header_t *paths, svn_mergeinfo_inheritance_t inherit, svn_boolean_t include_descendants, svn_boolean_t adjust_inherited_mergeinfo, - apr_pool_t *result_pool, + svn_fs_mergeinfo_receiver_t receiver, + void *baton, apr_pool_t *scratch_pool) { /* Verify that our filesystem version supports mergeinfo stuff. */ @@ -5493,10 +5496,11 @@ base_get_mergeinfo(svn_mergeinfo_catalog return svn_error_create(SVN_ERR_FS_NOT_REVISION_ROOT, NULL, NULL); /* Retrieve a path -> mergeinfo mapping. */ - return get_mergeinfos_for_paths(root, catalog, paths, + return get_mergeinfos_for_paths(root, paths, inherit, include_descendants, adjust_inherited_mergeinfo, - result_pool, scratch_pool); + receiver, baton, + scratch_pool); } Modified: subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.c (original) +++ subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.c Wed Nov 7 12:30:06 2018 @@ -866,7 +866,7 @@ create_rep_state_body(rep_state_t **rep_ rs->size = rep->size; rs->revision = rep->revision; rs->item_index = rep->item_index; - rs->raw_window_cache = ffd->raw_window_cache; + rs->raw_window_cache = use_block_read(fs) ? ffd->raw_window_cache : NULL; rs->ver = -1; rs->start = -1; @@ -1268,7 +1268,7 @@ parse_raw_window(void **out, stream = svn_stream_from_string(&raw_window, result_pool); /* parse it */ - SVN_ERR(svn_txdelta_read_svndiff_window(&result->window, stream, 1, + SVN_ERR(svn_txdelta_read_svndiff_window(&result->window, stream, window->ver, result_pool)); /* complete the window and return it */ @@ -1462,7 +1462,8 @@ build_rep_list(apr_array_header_t **list &rep, fs, pool, iterpool)); /* for txn reps, there won't be a cached combined window */ - if (!svn_fs_fs__id_txn_used(&rep.txn_id)) + if ( !svn_fs_fs__id_txn_used(&rep.txn_id) + && rep.expanded_size < SVN_DELTA_WINDOW_SIZE) SVN_ERR(get_cached_combined_window(window_p, rs, &is_cached, pool)); if (is_cached) @@ -2058,6 +2059,16 @@ skip_contents(struct rep_read_baton *bat len -= to_read; buffer += to_read; } + + /* Make the MD5 calculation catch up with the data delivered + * (we did not run MD5 on the data that we took from the cache). */ + if (!err) + { + SVN_ERR(svn_checksum_update(baton->md5_checksum_ctx, + baton->current_fulltext->data, + baton->current_fulltext->len)); + baton->off += baton->current_fulltext->len; + } } else if (len > 0) { @@ -2073,6 +2084,15 @@ skip_contents(struct rep_read_baton *bat err = get_contents_from_windows(baton, buffer, &to_read); len -= to_read; + + /* Make the MD5 calculation catch up with the data delivered + * (we did not run MD5 on the data that we took from the cache). */ + if (!err) + { + SVN_ERR(svn_checksum_update(baton->md5_checksum_ctx, + buffer, to_read)); + baton->off += to_read; + } } svn_pool_destroy(subpool); @@ -2083,13 +2103,14 @@ skip_contents(struct rep_read_baton *bat /* BATON is of type `rep_read_baton'; read the next *LEN bytes of the representation and store them in *BUF. Sum as we read and verify - the MD5 sum at the end. */ + the MD5 sum at the end. This is a READ_FULL_FN for svn_stream_t. */ static svn_error_t * rep_read_contents(void *baton, char *buf, apr_size_t *len) { struct rep_read_baton *rb = baton; + apr_size_t len_requested = *len; /* Get data from the fulltext cache for as long as we can. */ if (rb->fulltext_cache) @@ -2119,12 +2140,39 @@ rep_read_contents(void *baton, SVN_ERR(skip_contents(rb, rb->fulltext_delivered)); } - /* Get the next block of data. */ - SVN_ERR(get_contents_from_windows(rb, buf, len)); + /* Get the next block of data. + * Keep in mind that the representation might be empty and leave us + * already positioned at the end of the rep. */ + if (rb->off == rb->len) + *len = 0; + else + SVN_ERR(get_contents_from_windows(rb, buf, len)); if (rb->current_fulltext) svn_stringbuf_appendbytes(rb->current_fulltext, buf, *len); + /* This is a FULL_READ_FN so a short read implies EOF and we can + verify the length. */ + rb->off += *len; + if (*len < len_requested && rb->off != rb->len) + { + /* A warning rather than an error to allow the data to be + retrieved when the length is wrong but the data is + present, i.e. if repository corruption has stored the wrong + expanded length. */ + svn_error_t *err = svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, + _("Length mismatch while reading representation:" + " expected %s," + " got %s"), + apr_psprintf(rb->pool, "%" SVN_FILESIZE_T_FMT, + rb->len), + apr_psprintf(rb->pool, "%" SVN_FILESIZE_T_FMT, + rb->off)); + + rb->fs->warning(rb->fs->warning_baton, err); + svn_error_clear(err); + } + /* Perform checksumming. We want to check the checksum as soon as the last byte of data is read, in case the caller never performs a short read, but we don't want to finalize the MD5 context @@ -2132,7 +2180,6 @@ rep_read_contents(void *baton, if (!rb->checksum_finalized) { SVN_ERR(svn_checksum_update(rb->md5_checksum_ctx, buf, *len)); - rb->off += *len; if (rb->off == rb->len) { svn_checksum_t *md5_checksum; @@ -2212,6 +2259,96 @@ svn_fs_fs__get_contents(svn_stream_t **c return SVN_NO_ERROR; } +svn_error_t * +svn_fs_fs__get_contents_from_file(svn_stream_t **contents_p, + svn_fs_t *fs, + representation_t *rep, + apr_file_t *file, + apr_off_t offset, + apr_pool_t *pool) +{ + struct rep_read_baton *rb; + pair_cache_key_t fulltext_cache_key = { SVN_INVALID_REVNUM, 0 }; + rep_state_t *rs = apr_pcalloc(pool, sizeof(*rs)); + svn_fs_fs__rep_header_t *rh; + + /* Initialize the reader baton. Some members may added lazily + * while reading from the stream. */ + SVN_ERR(rep_read_get_baton(&rb, fs, rep, fulltext_cache_key, pool)); + + /* Continue constructing RS. Leave caches as NULL. */ + rs->size = rep->size; + rs->revision = SVN_INVALID_REVNUM; + rs->item_index = 0; + rs->ver = -1; + rs->start = -1; + + /* Provide just enough file access info to allow for a basic read from + * FILE but leave all index / footer info with empty values b/c FILE + * probably is not a complete revision file. */ + rs->sfile = apr_pcalloc(pool, sizeof(*rs->sfile)); + rs->sfile->revision = rep->revision; + rs->sfile->pool = pool; + rs->sfile->fs = fs; + rs->sfile->rfile = apr_pcalloc(pool, sizeof(*rs->sfile->rfile)); + rs->sfile->rfile->start_revision = SVN_INVALID_REVNUM; + rs->sfile->rfile->file = file; + rs->sfile->rfile->stream = svn_stream_from_aprfile2(file, TRUE, pool); + + /* Read the rep header. */ + SVN_ERR(aligned_seek(fs, file, NULL, offset, pool)); + SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->sfile->rfile->stream, + pool, pool)); + SVN_ERR(get_file_offset(&rs->start, rs, pool)); + rs->header_size = rh->header_size; + + /* Log the access. */ + SVN_ERR(dbg_log_access(fs, SVN_INVALID_REVNUM, 0, rh, + SVN_FS_FS__ITEM_TYPE_ANY_REP, pool)); + + /* Build the representation list (delta chain). */ + if (rh->type == svn_fs_fs__rep_plain) + { + rb->rs_list = apr_array_make(pool, 0, sizeof(rep_state_t *)); + rb->src_state = rs; + } + else if (rh->type == svn_fs_fs__rep_self_delta) + { + rb->rs_list = apr_array_make(pool, 1, sizeof(rep_state_t *)); + APR_ARRAY_PUSH(rb->rs_list, rep_state_t *) = rs; + rb->src_state = NULL; + } + else + { + representation_t next_rep = { 0 }; + + /* skip "SVNx" diff marker */ + rs->current = 4; + + /* REP's base rep is inside a proper revision. + * It can be reconstructed in the usual way. */ + next_rep.revision = rh->base_revision; + next_rep.item_index = rh->base_item_index; + next_rep.size = rh->base_length; + svn_fs_fs__id_txn_reset(&next_rep.txn_id); + + SVN_ERR(build_rep_list(&rb->rs_list, &rb->base_window, + &rb->src_state, rb->fs, &next_rep, + rb->filehandle_pool)); + + /* Insert the access to REP as the first element of the delta chain. */ + svn_sort__array_insert(rb->rs_list, &rs, 0); + } + + /* Now, the baton is complete and we can assemble the stream around it. */ + *contents_p = svn_stream_create(rb, pool); + svn_stream_set_read2(*contents_p, NULL /* only full read support */, + rep_read_contents); + svn_stream_set_close(*contents_p, rep_read_contents_close); + + return SVN_NO_ERROR; +} + /* Baton for cache_access_wrapper. Wraps the original parameters of * svn_fs_fs__try_process_file_content(). */ @@ -3091,7 +3228,7 @@ init_rep_state(rep_state_t *rs, rs->start = entry->offset + rs->header_size; rs->current = rep_header->type == svn_fs_fs__rep_plain ? 0 : 4; rs->size = entry->size - rep_header->header_size - 7; - rs->ver = 1; + rs->ver = -1; rs->chunk_index = 0; rs->raw_window_cache = ffd->raw_window_cache; rs->window_cache = ffd->txdelta_window_cache; @@ -3149,6 +3286,9 @@ cache_windows(svn_fs_t *fs, apr_pool_t *pool) { apr_pool_t *iterpool = svn_pool_create(pool); + + SVN_ERR(auto_read_diff_version(rs, iterpool)); + while (rs->current < rs->size) { apr_off_t end_offset; @@ -3209,6 +3349,7 @@ cache_windows(svn_fs_t *fs, window.end_offset = rs->current; window.window.len = window_len; window.window.data = buf; + window.ver = rs->ver; /* cache the window now */ SVN_ERR(svn_cache__set(rs->raw_window_cache, &key, &window, Modified: subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.h URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.h?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.h (original) +++ subversion/branches/ra-git/subversion/libsvn_fs_fs/cached_data.h Wed Nov 7 12:30:06 2018 @@ -81,7 +81,7 @@ svn_fs_fs__rep_chain_length(int *chain_l svn_fs_t *fs, apr_pool_t *scratch_pool); -/* Set *CONTENTS to be a readable svn_stream_t that receives the text +/* Set *CONTENTS_P to be a readable svn_stream_t that receives the text representation REP as seen in filesystem FS. If CACHE_FULLTEXT is not set, bypass fulltext cache lookup for this rep and don't put the reconstructed fulltext into cache. @@ -93,6 +93,18 @@ svn_fs_fs__get_contents(svn_stream_t **c svn_boolean_t cache_fulltext, apr_pool_t *pool); +/* Set *CONTENTS_P to be a readable svn_stream_t that receives the text + representation REP as seen in filesystem FS. Read the latest element + of the delta chain from FILE at offset OFFSET. + Use POOL for allocations. */ +svn_error_t * +svn_fs_fs__get_contents_from_file(svn_stream_t **contents_p, + svn_fs_t *fs, + representation_t *rep, + apr_file_t *file, + apr_off_t offset, + apr_pool_t *pool); + /* Attempt to fetch the text representation of node-revision NODEREV as seen in filesystem FS and pass it along with the BATON to the PROCESSOR. Set *SUCCESS only of the data could be provided and the processing @@ -159,7 +171,7 @@ svn_fs_fs__get_proplist(apr_hash_t **pro apr_pool_t *pool); /* Create a changes retrieval context object in *RESULT_POOL and return it - * in *CONTEXT. It will allow svn_fs_x__get_changes to fetch consecutive + * in *CONTEXT. It will allow svn_fs_fs__get_changes to fetch consecutive * blocks (one per invocation) from REV's changed paths list in FS. */ svn_error_t * svn_fs_fs__create_changes_context(svn_fs_fs__changes_context_t **context, Modified: subversion/branches/ra-git/subversion/libsvn_fs_fs/caching.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_fs/caching.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs_fs/caching.c (original) +++ subversion/branches/ra-git/subversion/libsvn_fs_fs/caching.c Wed Nov 7 12:30:06 2018 @@ -96,11 +96,8 @@ read_config(const char **cache_namespace ""), pool); - /* don't cache text deltas by default. - * Once we reconstructed the fulltexts from the deltas, - * these deltas are rarely re-used. Therefore, only tools - * like svnadmin will activate this to speed up operations - * dump and verify. + /* Cache text deltas by default. + * They tend to be smaller and have finer granularity than fulltexts. */ *cache_txdeltas = svn_hash__get_bool(fs->config, @@ -119,9 +116,9 @@ read_config(const char **cache_namespace SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS, TRUE); - /* by default, cache nodeprops: this will match pre-1.10 - * behavior where node properties caching was controlled - * by SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS configuration option. + /* by default, cache nodeprops. + * Pre-1.10, this was controlled by the SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS + * configuration option which defaulted to TRUE. */ *cache_nodeprops = svn_hash__get_bool(fs->config, @@ -386,7 +383,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f * (e.g. fulltexts etc.) * - Index data required to find any of the other data has high prio * (e.g. noderevs, L2P and P2L index pages) - * - everthing else should use default prio + * - everything else should use default prio */ #ifdef SVN_DEBUG_CACHE_DUMP_STATS @@ -522,7 +519,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f SVN_ERR(create_cache(&(ffd->revprop_cache), NULL, membuffer, - 0, 0, /* Do not use inprocess cache */ + 8, 20, /* ~400 bytes / entry, capa for ~2 packs */ svn_fs_fs__serialize_revprops, svn_fs_fs__deserialize_revprops, sizeof(pair_cache_key_t), Modified: subversion/branches/ra-git/subversion/libsvn_fs_fs/dag.c URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_fs/dag.c?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs_fs/dag.c (original) +++ subversion/branches/ra-git/subversion/libsvn_fs_fs/dag.c Wed Nov 7 12:30:06 2018 @@ -1166,7 +1166,7 @@ svn_fs_fs__dag_serialize(void **data, (const void * const *)&node->node_pool); /* serialize other sub-structures */ - svn_fs_fs__id_serialize(context, (const svn_fs_id_t **)&node->id); + svn_fs_fs__id_serialize(context, (const svn_fs_id_t *const *)&node->id); svn_fs_fs__id_serialize(context, &node->fresh_root_predecessor_id); svn_temp_serializer__add_string(context, &node->created_path); Modified: subversion/branches/ra-git/subversion/libsvn_fs_fs/fs.h URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_fs/fs.h?rev=1846002&r1=1846001&r2=1846002&view=diff ============================================================================== --- subversion/branches/ra-git/subversion/libsvn_fs_fs/fs.h (original) +++ subversion/branches/ra-git/subversion/libsvn_fs_fs/fs.h Wed Nov 7 12:30:06 2018 @@ -117,6 +117,8 @@ extern "C" { #define CONFIG_OPTION_P2L_PAGE_SIZE "p2l-page-size" #define CONFIG_SECTION_DEBUG "debug" #define CONFIG_OPTION_PACK_AFTER_COMMIT "pack-after-commit" +#define CONFIG_OPTION_VERIFY_BEFORE_COMMIT "verify-before-commit" +#define CONFIG_OPTION_COMPRESSION "compression" /* The format number of this filesystem. This is independent of the repository format number, and @@ -125,7 +127,7 @@ extern "C" { Note: If you bump this, please update the switch statement in svn_fs_fs__create() as well. */ -#define SVN_FS_FS__FORMAT_NUMBER 7 +#define SVN_FS_FS__FORMAT_NUMBER 8 /* The minimum format number that supports svndiff version 1. */ #define SVN_FS_FS__MIN_SVNDIFF1_FORMAT 2 @@ -161,6 +163,9 @@ extern "C" { * issues with very old servers, restrict those options to the 1.6+ format*/ #define SVN_FS_FS__MIN_DELTIFICATION_FORMAT 4 +/* The minimum format number that supports a configuration file (fsfs.conf) */ +#define SVN_FS_FS__MIN_CONFIG_FILE 4 + /* The 1.7-dev format, never released, that packed revprops into SQLite revprops.db . */ #define SVN_FS_FS__PACKED_REVPROP_SQLITE_DEV_FORMAT 5 @@ -180,8 +185,20 @@ extern "C" { /* Minimum format number that supports per-instance filesystem IDs. */ #define SVN_FS_FS__MIN_INSTANCE_ID_FORMAT 7 -/* The minimum format number that supports a configuration file (fsfs.conf) */ -#define SVN_FS_FS__MIN_CONFIG_FILE 4 +/* The minimum format number that supports svndiff version 2. */ +#define SVN_FS_FS__MIN_SVNDIFF2_FORMAT 8 + +/* The minimum format number that supports the special notation ("-") + for optional values that are not present in the representation strings, + such as SHA1 or the uniquifier. For example: + + 15 0 563 7809 28ef320a82e7bd11eebdf3502d69e608 - 14-g/_5 + */ +#define SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT 8 + + /* The minimum format number that supports V2 schema of the rep-cache.db + database. */ +#define SVN_FS_FS__MIN_REP_CACHE_SCHEMA_V2_FORMAT 8 /* On most operating systems apr implements file locks per process, not per file. On Windows apr implements the locking as per file handle @@ -294,6 +311,13 @@ typedef struct window_cache_key_t apr_uint64_t item_index; } window_cache_key_t; +typedef enum compression_type_t +{ + compression_type_none, + compression_type_zlib, + compression_type_lz4 +} compression_type_t; + /* Private (non-shared) FSFS-specific data for each svn_fs_t object. Any caches in here may be NULL. */ typedef struct fs_fs_data_t @@ -469,12 +493,18 @@ typedef struct fs_fs_data_t * deltification history after which skip deltas will be used. */ apr_int64_t max_linear_deltification; - /* Compression level to use with txdelta storage format in new revs. */ + /* Compression type to use with txdelta storage format in new revs. */ + compression_type_t delta_compression_type; + + /* Compression level (currently, only used with compression_type_zlib). */ int delta_compression_level; /* Pack after every commit. */ svn_boolean_t pack_after_commit; + /* Verify each new revision before commit. */ + svn_boolean_t verify_before_commit; + /* Per-instance filesystem ID, which provides an additional level of uniqueness for filesystems that share the same UUID, but should still be distinguishable (e.g. backups produced by svn_fs_hotcopy()