blob: 2c43bb1751a806f463aaf903e505acb2209a3c16 [file] [log] [blame]
/* fs.h : interface to Subversion filesystem, private to libsvn_fs
*
* ====================================================================
* Copyright (c) 2000-2007 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
*/
#ifndef SVN_LIBSVN_FS_FS_H
#define SVN_LIBSVN_FS_FS_H
#include <apr_pools.h>
#include <apr_hash.h>
#include <apr_md5.h>
#include <apr_thread_mutex.h>
#include <apr_network_io.h>
#include "svn_fs.h"
#include "private/svn_fs_private.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*** The filesystem structure. ***/
/* Following are defines that specify the textual elements of the
native filesystem directories and revision files. */
/* Names of special files in the fs_fs filesystem. */
#define PATH_FORMAT "format" /* Contains format number */
#define PATH_UUID "uuid" /* Contains UUID */
#define PATH_CURRENT "current" /* Youngest revision */
#define PATH_LOCK_FILE "write-lock" /* Revision lock file */
#define PATH_REVS_DIR "revs" /* Directory of revisions */
#define PATH_REVPROPS_DIR "revprops" /* Directory of revprops */
#define PATH_TXNS_DIR "transactions" /* Directory of transactions */
#define PATH_TXN_CURRENT "transaction-current" /* File with next txn key */
#define PATH_TXN_CURRENT_LOCK "txn-current-lock" /* Lock for txn-current */
#define PATH_LOCKS_DIR "locks" /* Directory of locks */
/* Names of special files and file extensions for transactions */
#define PATH_CHANGES "changes" /* Records changes made so far */
#define PATH_TXN_PROPS "props" /* Transaction properties */
#define PATH_NEXT_IDS "next-ids" /* Next temporary ID assignments */
#define PATH_REV "rev" /* Proto rev file */
#define PATH_REV_LOCK "rev-lock" /* Proto rev (write) lock file */
#define PATH_TXN_MERGEINFO "mergeinfo" /* Transaction mergeinfo props */
#define PATH_PREFIX_NODE "node." /* Prefix for node filename */
#define PATH_EXT_TXN ".txn" /* Extension of txn dir */
#define PATH_EXT_CHILDREN ".children" /* Extension for dir contents */
#define PATH_EXT_PROPS ".props" /* Extension for node props */
/* The format number of this filesystem.
This is independent of the repository format number, and
independent of any other FS back ends. */
#define SVN_FS_FS__FORMAT_NUMBER 3
/* The minimum format number that supports svndiff version 1. */
#define SVN_FS_FS__MIN_SVNDIFF1_FORMAT 2
/* The minimum format number that supports transaction ID generation
using a transaction sequence in the transaction-current file. */
#define SVN_FS_FS__MIN_TXN_CURRENT_FORMAT 3
/* The minimum format number that supports the "layout" filesystem
format option. */
#define SVN_FS_FS__MIN_LAYOUT_FORMAT_OPTION_FORMAT 3
/* Maximum number of directories to cache dirents for.
This *must* be a power of 2 for DIR_CACHE_ENTRIES_MASK
to work. */
#define NUM_DIR_CACHE_ENTRIES 128
#define DIR_CACHE_ENTRIES_MASK(x) ((x) & (NUM_DIR_CACHE_ENTRIES - 1))
/* Maximum number of revroot ids to cache dirents for at a time. */
#define NUM_RRI_CACHE_ENTRIES 4096
/* Private FSFS-specific data shared between all svn_txn_t objects that
relate to a particular transaction in a filesystem (as identified
by transaction id and filesystem UUID). Objects of this type are
allocated in their own subpool of the common pool. */
struct fs_fs_shared_txn_data_t;
typedef struct fs_fs_shared_txn_data_t
{
/* The next transaction in the list, or NULL if there is no following
transaction. */
struct fs_fs_shared_txn_data_t *next;
/* This transaction's ID. For repositories whose format is less
than SVN_FS_FS__MIN_TXN_CURRENT_FORMAT, the ID is in the form
<rev>-<uniqueifier>, where <uniqueifier> runs from 0-99999 (see
create_txn_dir_pre_1_5() in fs_fs.c). For newer repositories,
the form is <rev>-<200 digit base 36 number> (see
create_txn_dir() in fs_fs.c). */
char txn_id[SVN_FS__TXN_MAX_LEN+1];
/* Whether the transaction's prototype revision file is locked for
writing by any thread in this process (including the current
thread; recursive locks are not permitted). This is effectively
a non-recursive mutex. */
svn_boolean_t being_written;
/* The pool in which this object has been allocated; a subpool of the
common pool. */
apr_pool_t *pool;
} fs_fs_shared_txn_data_t;
/* Private FSFS-specific data shared between all svn_fs_t objects that
relate to a particular filesystem, as identified by filesystem UUID.
Objects of this type are allocated in the common pool. */
typedef struct
{
/* A list of shared transaction objects for each transaction that is
currently active, or NULL if none are. All access to this list,
including the contents of the objects stored in it, is synchronised
under TXN_LIST_LOCK. */
fs_fs_shared_txn_data_t *txns;
/* A free transaction object, or NULL if there is no free object.
Access to this object is synchronised under TXN_LIST_LOCK. */
fs_fs_shared_txn_data_t *free_txn;
#if APR_HAS_THREADS
/* A lock for intra-process synchronization when accessing the TXNS list. */
apr_thread_mutex_t *txn_list_lock;
/* A lock for intra-process synchronization when grabbing the
repository write lock. */
apr_thread_mutex_t *fs_write_lock;
/* A lock for intra-process synchronization when locking the
transaction-current file. */
apr_thread_mutex_t *txn_current_lock;
#endif
/* The common pool, under which this object is allocated, subpools
of which are used to allocate the transaction objects. */
apr_pool_t *common_pool;
} fs_fs_shared_data_t;
typedef struct dag_node_t dag_node_t;
/* Structure for DAG-node cache. Cache items are arranged in a
circular LRU list with a dummy entry, and also indexed with a hash
table. Transaction nodes are cached within the individual txn
roots; revision nodes are cached together within the FS object. */
typedef struct dag_node_cache_t
{
const char *key; /* Lookup key for cached node: path
for txns; rev catenated with path
for revs */
dag_node_t *node; /* Cached node */
struct dag_node_cache_t *prev; /* Next node in LRU list */
struct dag_node_cache_t *next; /* Previous node in LRU list */
apr_pool_t *pool; /* Pool in which node is allocated */
} dag_node_cache_t;
/* Private (non-shared) FSFS-specific data for each svn_fs_t object. */
typedef struct
{
/* A cache of the last directory opened within the filesystem. */
svn_fs_id_t *dir_cache_id[NUM_DIR_CACHE_ENTRIES];
apr_hash_t *dir_cache[NUM_DIR_CACHE_ENTRIES];
apr_pool_t *dir_cache_pool[NUM_DIR_CACHE_ENTRIES];
/* The format number of this FS. */
int format;
/* The maximum number of files to store per directory (for sharded
layouts) or zero (for linear layouts). */
int max_files_per_dir;
/* The uuid of this FS. */
const char *uuid;
/* Caches of immutable data.
Both of these could be moved to fs_fs_shared_data_t to make them
last longer; on the other hand, this would require adding mutexes
for threaded builds.
*/
/* A cache of revision root IDs, allocated in this subpool. (IDs
are so small that one pool per ID would be overkill;
unfortunately, this means the only way we expire cache entries is
by wiping the whole cache.) */
apr_hash_t *rev_root_id_cache;
apr_pool_t *rev_root_id_cache_pool;
/* DAG node cache for immutable nodes */
dag_node_cache_t rev_node_list;
apr_hash_t *rev_node_cache;
/* Data shared between all svn_fs_t objects for a given filesystem. */
fs_fs_shared_data_t *shared;
} fs_fs_data_t;
/*** Filesystem Transaction ***/
typedef struct
{
/* property list (const char * name, svn_string_t * value).
may be NULL if there are no properties. */
apr_hash_t *proplist;
/* node revision id of the root node. */
const svn_fs_id_t *root_id;
/* node revision id of the node which is the root of the revision
upon which this txn is base. (unfinished only) */
const svn_fs_id_t *base_id;
/* copies list (const char * copy_ids), or NULL if there have been
no copies in this transaction. */
apr_array_header_t *copies;
} transaction_t;
/*** Representation ***/
/* If you add fields to this, check to see if you need to change
* svn_fs_fs__rep_copy. */
typedef struct
{
/* MD5 checksum for the contents produced by this representation.
This checksum is for the contents the rep shows to consumers,
regardless of how the rep stores the data under the hood. It is
independent of the storage (fulltext, delta, whatever).
If all the bytes are 0, then for compatibility behave as though
this checksum matches the expected checksum. */
unsigned char checksum[APR_MD5_DIGESTSIZE];
/* Revision where this representation is located. */
svn_revnum_t revision;
/* Offset into the revision file where it is located. */
apr_off_t offset;
/* The size of the representation in bytes as seen in the revision
file. */
svn_filesize_t size;
/* The size of the fulltext of the representation. */
svn_filesize_t expanded_size;
/* Is this representation a transaction? */
const char *txn_id;
} representation_t;
/*** Node-Revision ***/
/* If you add fields to this, check to see if you need to change
* copy_node_revision in dag.c. */
typedef struct
{
/* node kind */
svn_node_kind_t kind;
/* The node-id for this node-rev. */
const svn_fs_id_t *id;
/* predecessor node revision id, or NULL if there is no predecessor
for this node revision */
const svn_fs_id_t *predecessor_id;
/* If this node-rev is a copy, where was it copied from? */
const char *copyfrom_path;
svn_revnum_t copyfrom_rev;
/* Helper for history tracing, root of the parent tree from whence
this node-rev was copied. */
svn_revnum_t copyroot_rev;
const char *copyroot_path;
/* number of predecessors this node revision has (recursively), or
-1 if not known (for backward compatibility). */
int predecessor_count;
/* representation key for this node's properties. may be NULL if
there are no properties. */
representation_t *prop_rep;
/* representation for this node's data. may be NULL if there is
no data. */
representation_t *data_rep;
/* path at which this node first came into existence. */
const char *created_path;
/* is this the unmodified root of a transaction? */
svn_boolean_t is_fresh_txn_root;
} node_revision_t;
/*** Change ***/
typedef struct
{
/* Path of the change. */
const char *path;
/* Node revision ID of the change. */
const svn_fs_id_t *noderev_id;
/* The kind of change. */
svn_fs_path_change_kind_t kind;
/* Text or property mods? */
svn_boolean_t text_mod;
svn_boolean_t prop_mod;
/* Copyfrom revision and path. */
svn_revnum_t copyfrom_rev;
const char * copyfrom_path;
} change_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SVN_LIBSVN_FS_FS_H */