Index: subversion/libsvn_diff/diff_file.c =================================================================== --- subversion/libsvn_diff/diff_file.c (revision 1050737) +++ subversion/libsvn_diff/diff_file.c (working copy) @@ -247,46 +247,84 @@ datasource_open(void *baton, svn_diff_datasource_e } +static svn_error_t * +increment_chunk(struct file_info *file, apr_pool_t *pool) +{ + apr_off_t length; + apr_off_t last_chunk = offset_to_chunk(file->size); + + /* Unless this was the last chunk, we need to read a new chunk. */ + if (file->chunk == last_chunk) + { + file->curp++; /* curp == endp signals end of file */ + } + else + { + file->chunk++; + length = file->chunk == last_chunk ? + offset_in_chunk(file->size) : CHUNK_SIZE; + SVN_ERR(read_chunk(file->file, file->path, file->buffer, + length, chunk_to_offset(file->chunk), + pool)); + file->endp = file->buffer + length; + file->curp = file->buffer; + } + + return SVN_NO_ERROR; +} + + +static svn_error_t * +decrement_chunk(struct file_info *file, apr_pool_t *pool) +{ + /* Unless this was the very first chunk, we need to read a new chunk. */ + if (file->chunk == 0) + file->chunk--; /* chunk == -1 signals beginning of file */ + else + { + file->chunk--; + SVN_ERR(read_chunk(file->file, file->path, file->buffer, + CHUNK_SIZE, chunk_to_offset(file->chunk), + pool)); + file->endp = file->buffer + CHUNK_SIZE; + file->curp = file->endp - 1; + } + + return SVN_NO_ERROR; +} + + /* For all files in the FILE array, increment the curp pointer. If a file * points before the beginning of file, let it point at the first byte again. * If the end of the current chunk is reached, read the next chunk in the * buffer and point curp to the start of the chunk. If EOF is reached, set * curp equal to endp to indicate EOF. */ -static svn_error_t * +static APR_INLINE svn_error_t * increment_pointers(struct file_info *file[], int file_len, apr_pool_t *pool) { + struct file_info *curFile; int i; for (i = 0; i < file_len; i++) - if (file[i]->chunk == -1) /* indicates before beginning of file */ - { - file[i]->chunk = 0; /* point to beginning of file again */ - } - else if (file[i]->curp == file[i]->endp - 1) - { - apr_off_t last_chunk = offset_to_chunk(file[i]->size); - if (file[i]->chunk == last_chunk) - { - file[i]->curp++; /* curp == endp signals end of file */ - } - else - { - apr_off_t length; - file[i]->chunk++; - length = file[i]->chunk == last_chunk ? - offset_in_chunk(file[i]->size) : CHUNK_SIZE; - SVN_ERR(read_chunk(file[i]->file, file[i]->path, file[i]->buffer, - length, chunk_to_offset(file[i]->chunk), - pool)); - file[i]->endp = file[i]->buffer + length; - file[i]->curp = file[i]->buffer; - } - } - else - { - file[i]->curp++; - } + { + /* hot spot: */ + for(; i < file_len; i++) + { + curFile = file[i]; + if (curFile->chunk == -1) /* indicates before beginning of file */ + curFile->chunk = 0; /* point to beginning of file again */ + else if (curFile->curp != curFile->endp - 1) + curFile->curp++; + else + break; + } + if (i < file_len) + { + SVN_ERR(increment_chunk(curFile, pool)); + } + } + return SVN_NO_ERROR; } @@ -294,31 +332,30 @@ increment_pointers(struct file_info *file[], int f * start of a chunk is reached, read the previous chunk in the buffer and * point curp to the last byte of the chunk. If the beginning of a FILE is * reached, set chunk to -1 to indicate BOF. */ -static svn_error_t * +static APR_INLINE svn_error_t * decrement_pointers(struct file_info *file[], int file_len, apr_pool_t *pool) { + struct file_info *curFile; int i; for (i = 0; i < file_len; i++) - if (file[i]->curp == file[i]->buffer) - { - if (file[i]->chunk == 0) - file[i]->chunk--; /* chunk == -1 signals beginning of file */ - else - { - file[i]->chunk--; - SVN_ERR(read_chunk(file[i]->file, file[i]->path, file[i]->buffer, - CHUNK_SIZE, chunk_to_offset(file[i]->chunk), - pool)); - file[i]->endp = file[i]->buffer + CHUNK_SIZE; - file[i]->curp = file[i]->endp - 1; - } - } - else - { - file[i]->curp--; - } + { + /* hot spot: */ + for(; i < file_len; i++) + { + curFile = file[i]; + if (curFile->curp > curFile->buffer) + curFile->curp--; + else + break; + } + if (i < file_len) + { + SVN_ERR(decrement_chunk(curFile, pool)); + } + } + return SVN_NO_ERROR; }