FreeBSD/contrib/subversion/subversion/libsvn_fs_fs/transaction.c
/* Write out the COLLECTION pertaining to the NODEREV in FS as a deltified
   text representation to file FILE using WRITER.  In the process, record the
   total size and the md5 digest in REP and add the representation of type
   ITEM_TYPE to the indexes if necessary.  If rep sharing has been enabled and
   REPS_HASH is not NULL, it will be used in addition to the on-disk cache to
   find earlier reps with the same content.  When such existing reps can be
   found, we will truncate the one just written from the file and return the
   existing rep.

   If ITEM_TYPE is IS_PROPS equals SVN_FS_FS__ITEM_TYPE_*_PROPS, assume
   that we want to a props representation as the base for our delta.
   Perform temporary allocations in SCRATCH_POOL.
 */
Write out the COLLECTION pertaining to the NODEREV in FS as a deltified
text representation to file FILE using WRITER.  In the process, record the
total size and the md5 digest in REP and add the representation of type
ITEM_TYPE to the indexes if necessary.  If rep sharing has been enabled and
REPS_HASH is not NULL, it will be used in addition to the on-disk cache to
find earlier reps with the same content.  When such existing reps can be
found, we will truncate the one just written from the file and return the
existing rep.

If ITEM_TYPE is IS_PROPS equals SVN_FS_FS__ITEM_TYPE_*_PROPS, assume
that we want to a props representation as the base for our delta.
Perform temporary allocations in SCRATCH_POOL.
Write out the COLLECTION pertaining to the NODEREV in FS as a deltified text representation to file FILE using WRITER . In the process record the total size and the md5 digest in REP and add the representation of type ITEM_TYPE to the indexes if necessary . If rep sharing has been enabled and REPS_HASH is not NULL it will be used in addition to the on - disk cache to find earlier reps with the same content . When such existing reps can be found we will truncate the one just written from the file and return the existing rep . If ITEM_TYPE is IS_PROPS equals SVN_FS_FS__ITEM_TYPE_ * _PROPS assume that we want to a props representation as the base for our delta . Perform temporary allocations in SCRATCH_POOL .
static svn_error_t *
write_container_delta_rep(representation_t *rep,
                          apr_file_t *file,
                          void *collection,
                          collection_writer_t writer,
                          svn_fs_t *fs,
                          node_revision_t *noderev,
                          apr_hash_t *reps_hash,
                          apr_uint32_t item_type,
                          apr_pool_t *scratch_pool)
{
  svn_txdelta_window_handler_t diff_wh;
  void *diff_whb;
  svn_stream_t *file_stream;
  svn_stream_t *stream;
  representation_t *base_rep;
  representation_t *old_rep;
  svn_checksum_ctx_t *fnv1a_checksum_ctx;
  svn_stream_t *source;
  svn_fs_fs__rep_header_t header = { 0 };
  apr_off_t rep_end = 0;
  apr_off_t delta_start = 0;
  apr_off_t offset = 0;
  struct write_container_baton *whb;
  fs_fs_data_t *ffd = fs->fsap_data;
  int diff_version = ffd->format >= SVN_FS_FS__MIN_SVNDIFF1_FORMAT ? 1 : 0;
  svn_boolean_t is_props = (item_type == SVN_FS_FS__ITEM_TYPE_FILE_PROPS)
                        || (item_type == SVN_FS_FS__ITEM_TYPE_DIR_PROPS);
  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, is_props, scratch_pool));
  SVN_ERR(svn_fs_fs__get_contents(&source, fs, base_rep, FALSE, scratch_pool));
  SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, scratch_pool));
  if (base_rep)
    {
      header.base_revision = base_rep->revision;
      header.base_item_index = base_rep->item_index;
      header.base_length = base_rep->size;
      header.type = svn_fs_fs__rep_delta;
    }
  else
    {
      header.type = svn_fs_fs__rep_self_delta;
    }
  file_stream = fnv1a_wrap_stream(&fnv1a_checksum_ctx,
                                  svn_stream_from_aprfile2(file, TRUE,
                                                           scratch_pool),
                                  scratch_pool);
  SVN_ERR(svn_fs_fs__write_rep_header(&header, file_stream, scratch_pool));
  SVN_ERR(svn_fs_fs__get_file_offset(&delta_start, file, scratch_pool));
  svn_txdelta_to_svndiff3(&diff_wh,
                          &diff_whb,
                          file_stream,
                          diff_version,
                          ffd->delta_compression_level,
                          scratch_pool);
  whb = apr_pcalloc(scratch_pool, sizeof(*whb));
  whb->stream = svn_txdelta_target_push(diff_wh, diff_whb, source,
                                        scratch_pool);
  whb->size = 0;
  whb->md5_ctx = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
  whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, scratch_pool);
  stream = svn_stream_create(whb, scratch_pool);
  svn_stream_set_write(stream, write_container_handler);
  SVN_ERR(writer(stream, collection, scratch_pool));
  SVN_ERR(svn_stream_close(whb->stream));
  SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, scratch_pool));
  SVN_ERR(get_shared_rep(&old_rep, fs, rep, reps_hash, scratch_pool,
                         scratch_pool));
  if (old_rep)
    {
      SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));
      memcpy(rep, old_rep, sizeof (*rep));
    }
  else
    {
      svn_fs_fs__p2l_entry_t entry;
      SVN_ERR(svn_fs_fs__get_file_offset(&rep_end, file, scratch_pool));
      SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
      SVN_ERR(allocate_item_index(&rep->item_index, fs, &rep->txn_id,
                                  offset, scratch_pool));
      entry.offset = offset;
      SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, scratch_pool));
      entry.size = offset - entry.offset;
      entry.type = item_type;
      entry.item.revision = SVN_INVALID_REVNUM;
      entry.item.number = rep->item_index;
      SVN_ERR(fnv1a_checksum_finalize(&entry.fnv1_checksum,
                                      fnv1a_checksum_ctx,
                                      scratch_pool));
      SVN_ERR(store_p2l_index_entry(fs, &rep->txn_id, &entry, scratch_pool));
      rep->expanded_size = whb->size;
      rep->size = rep_end - delta_start;
    }
  return SVN_NO_ERROR;
}
static svn_error_t * write_container_delta_rep ( representation_t * rep , apr_file_t * file , void * collection , collection_writer_t writer , svn_fs_t * fs , node_revision_t * noderev , apr_hash_t * reps_hash , apr_uint32_t item_type , apr_pool_t * scratch_pool ) { svn_txdelta_window_handler_t diff_wh ; void * diff_whb ; svn_stream_t * file_stream ; svn_stream_t * stream ; representation_t * base_rep ; representation_t * old_rep ; svn_checksum_ctx_t * fnv1a_checksum_ctx ; svn_stream_t * source ; svn_fs_fs__rep_header_t header = { 0 } ; apr_off_t rep_end = 0 ; apr_off_t delta_start = 0 ; apr_off_t offset = 0 ; struct write_container_baton * whb ; fs_fs_data_t * ffd = fs -> fsap_data ; int diff_version = ffd -> format >= SVN_FS_FS__MIN_SVNDIFF1_FORMAT ? 1 : 0 ; svn_boolean_t is_props = ( item_type == SVN_FS_FS__ITEM_TYPE_FILE_PROPS ) || ( item_type == SVN_FS_FS__ITEM_TYPE_DIR_PROPS ) ; SVN_ERR ( choose_delta_base ( & base_rep , fs , noderev , is_props , scratch_pool ) ) ; SVN_ERR ( svn_fs_fs__get_contents ( & source , fs , base_rep , FALSE , scratch_pool ) ) ; SVN_ERR ( svn_fs_fs__get_file_offset ( & offset , file , scratch_pool ) ) ; if ( base_rep ) { header . base_revision = base_rep -> revision ; header . base_item_index = base_rep -> item_index ; header . base_length = base_rep -> size ; header . type = svn_fs_fs__rep_delta ; } else { header . type = svn_fs_fs__rep_self_delta ; } file_stream = fnv1a_wrap_stream ( & fnv1a_checksum_ctx , svn_stream_from_aprfile2 ( file , TRUE , scratch_pool ) , scratch_pool ) ; SVN_ERR ( svn_fs_fs__write_rep_header ( & header , file_stream , scratch_pool ) ) ; SVN_ERR ( svn_fs_fs__get_file_offset ( & delta_start , file , scratch_pool ) ) ; svn_txdelta_to_svndiff3 ( & diff_wh , & diff_whb , file_stream , diff_version , ffd -> delta_compression_level , scratch_pool ) ; whb = apr_pcalloc ( scratch_pool , sizeof ( * whb ) ) ; whb -> stream = svn_txdelta_target_push ( diff_wh , diff_whb , source , scratch_pool ) ; whb -> size = 0 ; whb -> md5_ctx = svn_checksum_ctx_create ( svn_checksum_md5 , scratch_pool ) ; whb -> sha1_ctx = svn_checksum_ctx_create ( svn_checksum_sha1 , scratch_pool ) ; stream = svn_stream_create ( whb , scratch_pool ) ; svn_stream_set_write ( stream , write_container_handler ) ; SVN_ERR ( writer ( stream , collection , scratch_pool ) ) ; SVN_ERR ( svn_stream_close ( whb -> stream ) ) ; SVN_ERR ( digests_final ( rep , whb -> md5_ctx , whb -> sha1_ctx , scratch_pool ) ) ; SVN_ERR ( get_shared_rep ( & old_rep , fs , rep , reps_hash , scratch_pool , scratch_pool ) ) ; if ( old_rep ) { SVN_ERR ( svn_io_file_trunc ( file , offset , scratch_pool ) ) ; memcpy ( rep , old_rep , sizeof ( * rep ) ) ; } else { svn_fs_fs__p2l_entry_t entry ; SVN_ERR ( svn_fs_fs__get_file_offset ( & rep_end , file , scratch_pool ) ) ; SVN_ERR ( svn_stream_puts ( file_stream , " \n " ) ) ; SVN_ERR ( allocate_item_index ( & rep -> item_index , fs , & rep -> txn_id , offset , scratch_pool ) ) ; entry . offset = offset ; SVN_ERR ( svn_fs_fs__get_file_offset ( & offset , file , scratch_pool ) ) ; entry . size = offset - entry . offset ; entry . type = item_type ; entry . item . revision = SVN_INVALID_REVNUM ; entry . item . number = rep -> item_index ; SVN_ERR ( fnv1a_checksum_finalize ( & entry . fnv1_checksum , fnv1a_checksum_ctx , scratch_pool ) ) ; SVN_ERR ( store_p2l_index_entry ( fs , & rep -> txn_id , & entry , scratch_pool ) ) ; rep -> expanded_size = whb -> size ; rep -> size = rep_end - delta_start ; } return SVN_NO_ERROR ; }
Write out the COLLECTION pertaining to the NODEREV in FS as a deltified
text representation to file FILE using WRITER.
Write out the COLLECTION pertaining to the NODEREV in FS as a deltified text representation to file FILE using WRITER .
/* Get the base for this delta. */ /* Write out the rep header. */ /* Prepare to write the svndiff data. */ /* serialize the hash */ /* Store the results. */ /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out. */ /* We need to erase from the protorev the data we just wrote. */ /* Use the old rep for this content. */ /* Write out our cosmetic end marker. */ /* update the representation */