~ubuntu-branches/ubuntu/trusty/subversion/trusty-proposed

« back to all changes in this revision

Viewing changes to subversion/libsvn_delta/text_delta.c

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft
  • Date: 2012-06-21 15:36:36 UTC
  • mfrom: (0.4.13 sid)
  • Revision ID: package-import@ubuntu.com-20120621153636-amqqmuidgwgxz1ly
Tags: 1.7.5-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Create pot file on build.
  - Build a python-subversion-dbg package.
  - Build-depend on python-dbg.
  - Build-depend on default-jre-headless/-jdk.
  - Do not apply java-build patch.
  - debian/rules: Manually create the doxygen output directory, otherwise
    we get weird build failures when running parallel builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * text-delta.c -- Internal text delta representation
3
3
 *
4
4
 * ====================================================================
5
 
 * Copyright (c) 2000-2006 CollabNet.  All rights reserved.
6
 
 *
7
 
 * This software is licensed as described in the file COPYING, which
8
 
 * you should have received as part of this distribution.  The terms
9
 
 * are also available at http://subversion.tigris.org/license-1.html.
10
 
 * If newer versions of this license are posted there, you may use a
11
 
 * newer version instead, at your option.
12
 
 *
13
 
 * This software consists of voluntary contributions made by many
14
 
 * individuals.  For exact contribution history, see the revision
15
 
 * history and logs, available at http://subversion.tigris.org/.
 
5
 *    Licensed to the Apache Software Foundation (ASF) under one
 
6
 *    or more contributor license agreements.  See the NOTICE file
 
7
 *    distributed with this work for additional information
 
8
 *    regarding copyright ownership.  The ASF licenses this file
 
9
 *    to you under the Apache License, Version 2.0 (the
 
10
 *    "License"); you may not use this file except in compliance
 
11
 *    with the License.  You may obtain a copy of the License at
 
12
 *
 
13
 *      http://www.apache.org/licenses/LICENSE-2.0
 
14
 *
 
15
 *    Unless required by applicable law or agreed to in writing,
 
16
 *    software distributed under the License is distributed on an
 
17
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
18
 *    KIND, either express or implied.  See the License for the
 
19
 *    specific language governing permissions and limitations
 
20
 *    under the License.
16
21
 * ====================================================================
17
22
 */
18
23
 
559
564
  return SVN_NO_ERROR;
560
565
}
561
566
 
 
567
/* Copy LEN bytes from SOURCE to TARGET, optimizing for the case where LEN
 
568
 * is often very small.  Return a pointer to the first byte after the copied
 
569
 * target range, unlike standard memcpy(), as a potential further
 
570
 * optimization for the caller.
 
571
 *
 
572
 * memcpy() is hard to tune for a wide range of buffer lengths.  Therefore,
 
573
 * it is often tuned for high throughput on large buffers and relatively
 
574
 * low latency for mid-sized buffers (tens of bytes).  However, the overhead
 
575
 * for very small buffers (<10 bytes) is still high.  Even passing the
 
576
 * parameters, for instance, may take as long as copying 3 bytes.
 
577
 *
 
578
 * Because short copy sequences seem to be a common case, at least in
 
579
 * "format 2" FSFS repositories, we copy them directly.  Larger buffer sizes
 
580
 * aren't hurt measurably by the exta 'if' clause.  */
 
581
static APR_INLINE char *
 
582
fast_memcpy(char *target, const char *source, apr_size_t len)
 
583
{
 
584
  if (len > 7)
 
585
    {
 
586
      memcpy(target, source, len);
 
587
      target += len;
 
588
    }
 
589
  else
 
590
    {
 
591
      /* memcpy is not exactly fast for small block sizes.
 
592
       * Since they are common, let's run optimized code for them. */
 
593
      const char *end = source + len;
 
594
      for (; source != end; source++)
 
595
        *(target++) = *source;
 
596
    }
 
597
 
 
598
  return target;
 
599
}
 
600
 
 
601
/* Copy LEN bytes from SOURCE to TARGET.  Unlike memmove() or memcpy(),
 
602
 * create repeating patterns if the source and target ranges overlap.
 
603
 * Return a pointer to the first byte after the copied target range.  */
 
604
static APR_INLINE char *
 
605
patterning_copy(char *target, const char *source, apr_size_t len)
 
606
{
 
607
  const char *end = source + len;
 
608
 
 
609
  /* On many machines, we can do "chunky" copies. */
 
610
 
 
611
#if SVN_UNALIGNED_ACCESS_IS_OK
 
612
 
 
613
  if (end + sizeof(apr_uint32_t) <= target)
 
614
    {
 
615
      /* Source and target are at least 4 bytes apart, so we can copy in
 
616
       * 4-byte chunks.  */
 
617
      for (; source + sizeof(apr_uint32_t) <= end;
 
618
           source += sizeof(apr_uint32_t),
 
619
           target += sizeof(apr_uint32_t))
 
620
      *(apr_uint32_t *)(target) = *(apr_uint32_t *)(source);
 
621
    }
 
622
 
 
623
#endif
 
624
 
 
625
  /* fall through to byte-wise copy (either for the below-chunk-size tail
 
626
   * or the whole copy) */
 
627
  for (; source != end; source++)
 
628
    *(target++) = *source;
 
629
 
 
630
  return target;
 
631
}
562
632
 
563
633
void
564
634
svn_txdelta_apply_instructions(svn_txdelta_window_t *window,
566
636
                               apr_size_t *tlen)
567
637
{
568
638
  const svn_txdelta_op_t *op;
569
 
  apr_size_t i, j, tpos = 0;
 
639
  apr_size_t tpos = 0;
570
640
 
571
641
  for (op = window->ops; op < window->ops + window->num_ops; op++)
572
642
    {
581
651
        case svn_txdelta_source:
582
652
          /* Copy from source area.  */
583
653
          assert(op->offset + op->length <= window->sview_len);
584
 
          memcpy(tbuf + tpos, sbuf + op->offset, buf_len);
 
654
          fast_memcpy(tbuf + tpos, sbuf + op->offset, buf_len);
585
655
          break;
586
656
 
587
657
        case svn_txdelta_target:
588
 
          /* Copy from target area.  Don't use memcpy() since its
589
 
             semantics aren't guaranteed for overlapping memory areas,
590
 
             and target copies are allowed to overlap to generate
591
 
             repeated data.  */
 
658
          /* Copy from target area.  We can't use memcpy() or the like
 
659
           * since we need a specific semantics for overlapping copies:
 
660
           * they must result in repeating patterns.
 
661
           * Note that most copies won't have overlapping source and
 
662
           * target ranges (they are just a result of self-compressed
 
663
           * data) but a small percentage will.  */
592
664
          assert(op->offset < tpos);
593
 
          for (i = op->offset, j = tpos; i < op->offset + buf_len; i++)
594
 
            tbuf[j++] = tbuf[i];
 
665
          patterning_copy(tbuf + tpos, tbuf + op->offset, buf_len);
595
666
          break;
596
667
 
597
668
        case svn_txdelta_new:
598
669
          /* Copy from window new area.  */
599
670
          assert(op->offset + op->length <= window->new_data->len);
600
 
          memcpy(tbuf + tpos,
601
 
                 window->new_data->data + op->offset,
602
 
                 buf_len);
 
671
          fast_memcpy(tbuf + tpos,
 
672
                      window->new_data->data + op->offset,
 
673
                      buf_len);
603
674
          break;
604
675
 
605
676
        default: