Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/libsvn_fs_fs/structure  view on Meta::CPAN

Packing revision properties (format 6+)
---------------------------

Similarly to the revision data, packing will concatenate multiple
revprops into a single file.  Since they are mutable data, we put an
upper limit to the size of these files:  We will concatenate the data
up to the limit and then use a new file for the following revisions.

The limit can be set and changed at will in the configuration file. 
It is 64kB by default.  Because a pack file must contain at least one
complete property list, files containing just one revision may exceed
that limit.

Furthermore, pack files can be compressed which saves about 75% of
disk space.  A configuration file flag enables the compression; it is
off by default and may be switched on and off at will.  The pack size
limit is always applied to the uncompressed data.  For this reason,
the default is 256kB while compression has been enabled.

Files are named after their start revision as "<rev>.<counter>" where
counter will be increased whenever we rewrite a pack file due to a
revprop change.  The manifest file contains the list of pack file
names, one line for each revision.

Many tools track repository global data in revision properties at 
revision 0.  To minimize I/O overhead for those applications,  we
will never pack that revision, i.e. its data is always being kept
in revprops/0/0.

Pack file format

  Top level: <packed container>

  We always apply data compression to the pack file - using the
  SVN_DELTA_COMPRESSION_LEVEL_NONE level if compression is disabled.
  (Note that compression at SVN_DELTA_COMPRESSION_LEVEL_NONE is not
  a no-op stream transformation although most of the data will remain
  human readable.)

  container := header '\n' (revprops)+
  header    := start_rev '\n' rev_count '\n' (size '\n')+

  All numbers in the header are given as ASCII decimals.  rev_count
  is the number of revisions packed into this container.  There must
  be exactly as many "size" and serialized "revprops".  The "size"
  values in the list are the length in bytes of the serialized
  revprops of the respective revision.

Writing to packed revprops

  The old pack file is being read and the new revprops serialized.
  If they fit into the same pack file, a temp file with the new
  content gets written and moved into place just like an non-packed
  revprop file would. No name change or manifest update required.

  If they don't fit into the same pack file,  i.e. exceed the pack
  size limit,  the pack will be split into 2 or 3 new packs just
  before and / or after the modified revision.

  In the current implementation, they will never be merged again.
  To minimize fragmentation, the initial packing process will only
  use about 90% of the limit, i.e. leave some room for growth.

  When a pack file gets split, its counter is being increased
  creating a new file and leaving the old content in place and
  available for concurrent readers.  Only after the new manifest
  file got moved into place, will the old pack files be deleted. 

  Write access to revprops is being serialized by the global
  filesystem write lock.  We only need to build a few retries into
  the reader code to gracefully handle manifest changes and pack
  file deletions.


Node-revision IDs
-----------------

A node-rev ID consists of the following three fields:

    node_revision_id ::= node_id '.' copy_id '.' txn_id

At this level, the form of the ID is the same as for BDB - see the
section called "ID's" in <../libsvn_fs_base/notes/structure>.

In order to support efficient lookup of node-revisions by their IDs
and to simplify the allocation of fresh node-IDs during a transaction,
we treat the fields of a node-rev ID in new and interesting ways.

Within a new transaction:

  New node-revision IDs assigned within a transaction have a txn-id
  field of the form "t<txnid>".

  When a new node-id or copy-id is assigned in a transaction, the ID
  used is a "_" followed by a base36 number unique to the transaction.

Within a revision:

  Within a revision file, node-revs have a txn-id field of the form
  "r<rev>/<offset>", to support easy lookup. The <offset> is the (ASCII
  decimal) number of bytes from the start of the revision file to the
  start of the node-rev.

  During the final phase of a commit, node-revision IDs are rewritten
  to have repository-wide unique node-ID and copy-ID fields, and to have
  "r<rev>/<offset>" txn-id fields.

  In Format 3 and above, this uniqueness is done by changing a temporary
  id of "_<base36>" to "<base36>-<rev>".  Note that this means that the
  originating revision of a line of history or a copy can be determined
  by looking at the node ID.

  In Format 2 and below, the "current" file contains global base36
  node-ID and copy-ID counters; during the commit, the counter value is
  added to the transaction-specific base36 ID, and the value in
  "current" is adjusted.

  (It is legal for Format 3 repositories to contain Format 2-style IDs;
  this just prevents I/O-less node-origin-rev lookup for those nodes.)

The temporary assignment of node-ID and copy-ID fields has



( run in 0.739 second using v1.01-cache-2.11-cpan-b16cb0d3907 )