You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/09/20 21:02:59 UTC
svn commit: r1388163 - in /subversion/branches/10Gb/subversion:
include/svn_delta.h libsvn_delta/svndiff.c
Author: stefan2
Date: Thu Sep 20 19:02:58 2012
New Revision: 1388163
URL: http://svn.apache.org/viewvc?rev=1388163&view=rev
Log:
On the 10Gb branch: Provide a variant of svn_txdelta_send_txstream
that takes a data buffer, diffs it against an empty stream and sends
the result to some output stream.
The key is that we don't create a copy of the input buffer but hand
it directly over to the output stream - plus some svndiff and window
header data. Compression is supported as well but is of curse much
slower.
* subversion/include/svn_delta.h
(svn_txdelta_send_content): declare new API
* subversion/libsvn_delta/svndiff.c
(svn_txdelta_send_content): implement new API
Modified:
subversion/branches/10Gb/subversion/include/svn_delta.h
subversion/branches/10Gb/subversion/libsvn_delta/svndiff.c
Modified: subversion/branches/10Gb/subversion/include/svn_delta.h
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/subversion/include/svn_delta.h?rev=1388163&r1=1388162&r2=1388163&view=diff
==============================================================================
--- subversion/branches/10Gb/subversion/include/svn_delta.h (original)
+++ subversion/branches/10Gb/subversion/include/svn_delta.h Thu Sep 20 19:02:58 2012
@@ -452,6 +452,20 @@ svn_txdelta_send_txstream(svn_txdelta_st
apr_pool_t *pool);
+/** Send the @a contents of length @a len as a txdelta against an empty
+ * source directly to the stream inside @a baton. That baton is the one
+ * returned by svn_txdelta_to_svndiff3.
+ *
+ * All temporary allocation is performed in @a pool.
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_txdelta_send_contents(const unsigned char *contents,
+ apr_size_t len,
+ void *diff_baton,
+ apr_pool_t *pool);
+
/** Prepare to apply a text delta. @a source is a readable generic stream
* yielding the source data, @a target is a writable generic stream to
* write target data to, and allocation takes place in a sub-pool of
@@ -483,6 +497,7 @@ svn_txdelta_apply(svn_stream_t *source,
+
/*** Producing and consuming svndiff-format text deltas. ***/
/** Prepare to produce an svndiff-format diff from text delta windows.
Modified: subversion/branches/10Gb/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/subversion/libsvn_delta/svndiff.c?rev=1388163&r1=1388162&r2=1388163&view=diff
==============================================================================
--- subversion/branches/10Gb/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/10Gb/subversion/libsvn_delta/svndiff.c Thu Sep 20 19:02:58 2012
@@ -293,6 +293,89 @@ window_handler(svn_txdelta_window_t *win
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_txdelta_send_contents(const unsigned char *contents,
+ apr_size_t len,
+ void *diff_baton,
+ apr_pool_t *pool)
+{
+ struct encoder_baton *eb = diff_baton;
+
+ /* frequently reused buffers */
+ svn_stringbuf_t *header = svn_stringbuf_create_empty(eb->pool);
+ svn_stringbuf_t *compressed_temp = svn_stringbuf_create_empty(eb->pool);
+ unsigned char ibuf[MAX_INSTRUCTION_LEN];
+
+ /* Write the stream header. */
+ char svnver[4] = {'S','V','N','\0'};
+ apr_size_t ver_len = 4;
+ svnver[3] = eb->version;
+ SVN_ERR(svn_stream_write(eb->output, svnver, &ver_len));
+
+ /* send CONTENT as a series of max-sized windows */
+ while (len > 0)
+ {
+ const char *processed_chunk;
+ apr_size_t processed_size;
+
+ apr_size_t ip_len;
+ apr_size_t chunk_size = len < SVN_DELTA_WINDOW_SIZE
+ ? len
+ : SVN_DELTA_WINDOW_SIZE;
+
+ /* Encode the action code (svn_txdelta_new) and length. */
+ if (chunk_size < (1 << 6))
+ {
+ ibuf[0] = chunk_size + (0x2 << 6);
+ ip_len = 1;
+ }
+ else
+ {
+ ibuf[0] = (0x2 << 6);
+ ip_len = encode_int(ibuf + 1, chunk_size) - ibuf;
+ }
+
+ /* Encode the delta window header (empty source view). */
+ header->len = 0;
+ svn_stringbuf_appendbyte(header, '\0'); /* source view offset */
+ svn_stringbuf_appendbyte(header, '\0'); /* source view length */
+ append_encoded_int(header, chunk_size); /* target view length */
+ svn_stringbuf_appendbyte(header, (char)ip_len);
+
+ /* compress the window content if required */
+ if (eb->version == 1)
+ {
+ compressed_temp->len = 0;
+ SVN_ERR(zlib_encode((const char*)contents, chunk_size,
+ compressed_temp, eb->compression_level));
+ processed_chunk = compressed_temp->data;
+ processed_size = compressed_temp->len;
+ }
+ else
+ {
+ processed_chunk = (const char*)contents;
+ processed_size = chunk_size;
+ }
+ append_encoded_int(header, processed_size);
+
+ /* Write out the window. */
+ SVN_ERR(svn_stream_write(eb->output, header->data, &header->len));
+ if (ip_len)
+ SVN_ERR(svn_stream_write(eb->output, (const char *)ibuf, &ip_len));
+ if (processed_size)
+ SVN_ERR(svn_stream_write(eb->output, processed_chunk, &processed_size));
+
+ /* next chunk */
+ contents += chunk_size;
+ len -= chunk_size;
+ }
+
+ /* We're done; clean up.
+ */
+ svn_pool_destroy(eb->pool);
+ return svn_stream_close(eb->output);
+}
+
void
svn_txdelta_to_svndiff3(svn_txdelta_window_handler_t *handler,
void **handler_baton,