summaryrefslogtreecommitdiff
path: root/subversion/libsvn_fs_fs/fs.h
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_fs_fs/fs.h')
-rw-r--r--subversion/libsvn_fs_fs/fs.h261
1 files changed, 176 insertions, 85 deletions
diff --git a/subversion/libsvn_fs_fs/fs.h b/subversion/libsvn_fs_fs/fs.h
index 5cdc270..c75eafb 100644
--- a/subversion/libsvn_fs_fs/fs.h
+++ b/subversion/libsvn_fs_fs/fs.h
@@ -26,6 +26,8 @@
#include <apr_pools.h>
#include <apr_hash.h>
#include <apr_network_io.h>
+#include <apr_md5.h>
+#include <apr_sha1.h>
#include "svn_fs.h"
#include "svn_config.h"
@@ -34,7 +36,8 @@
#include "private/svn_fs_private.h"
#include "private/svn_sqlite.h"
#include "private/svn_mutex.h"
-#include "private/svn_named_atomic.h"
+
+#include "id.h"
#ifdef __cplusplus
extern "C" {
@@ -51,9 +54,11 @@ extern "C" {
#define PATH_UUID "uuid" /* Contains UUID */
#define PATH_CURRENT "current" /* Youngest revision */
#define PATH_LOCK_FILE "write-lock" /* Revision lock file */
+#define PATH_PACK_LOCK_FILE "pack-lock" /* Pack 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_TXNS_DIR "transactions" /* Directory of transactions in
+ repos w/o log addressing */
#define PATH_NODE_ORIGINS_DIR "node-origins" /* Lazy node-origin cache */
#define PATH_TXN_PROTOS_DIR "txn-protorevs" /* Directory of proto-revs */
#define PATH_TXN_CURRENT "txn-current" /* File with next txn key */
@@ -67,12 +72,18 @@ extern "C" {
#define PATH_PACKED "pack" /* Packed revision data file */
#define PATH_EXT_PACKED_SHARD ".pack" /* Extension for packed
shards */
+#define PATH_EXT_L2P_INDEX ".l2p" /* extension of the log-
+ to-phys index */
+#define PATH_EXT_P2L_INDEX ".p2l" /* extension of the phys-
+ to-log index */
/* If you change this, look at tests/svn_test_fs.c(maybe_install_fsfs_conf) */
#define PATH_CONFIG "fsfs.conf" /* Configuration */
/* 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_TXN_PROPS_FINAL "props-final" /* Final transaction properties
+ before moving to revprops */
#define PATH_NEXT_IDS "next-ids" /* Next temporary ID assignments */
#define PATH_PREFIX_NODE "node." /* Prefix for node filename */
#define PATH_EXT_TXN ".txn" /* Extension of txn dir */
@@ -80,6 +91,10 @@ extern "C" {
#define PATH_EXT_PROPS ".props" /* Extension for node props */
#define PATH_EXT_REV ".rev" /* Extension of protorev file */
#define PATH_EXT_REV_LOCK ".rev-lock" /* Extension of protorev lock file */
+#define PATH_TXN_ITEM_INDEX "itemidx" /* File containing the current item
+ index number */
+#define PATH_INDEX "index" /* name of index files w/o ext */
+
/* Names of files in legacy FS formats */
#define PATH_REV "rev" /* Proto rev file */
#define PATH_REV_LOCK "rev-lock" /* Proto rev (write) lock file */
@@ -94,14 +109,25 @@ extern "C" {
#define CONFIG_OPTION_ENABLE_PROPS_DELTIFICATION "enable-props-deltification"
#define CONFIG_OPTION_MAX_DELTIFICATION_WALK "max-deltification-walk"
#define CONFIG_OPTION_MAX_LINEAR_DELTIFICATION "max-linear-deltification"
+#define CONFIG_OPTION_COMPRESSION_LEVEL "compression-level"
#define CONFIG_SECTION_PACKED_REVPROPS "packed-revprops"
#define CONFIG_OPTION_REVPROP_PACK_SIZE "revprop-pack-size"
#define CONFIG_OPTION_COMPRESS_PACKED_REVPROPS "compress-packed-revprops"
+#define CONFIG_SECTION_IO "io"
+#define CONFIG_OPTION_BLOCK_SIZE "block-size"
+#define CONFIG_OPTION_L2P_PAGE_SIZE "l2p-page-size"
+#define CONFIG_OPTION_P2L_PAGE_SIZE "p2l-page-size"
+#define CONFIG_SECTION_DEBUG "debug"
+#define CONFIG_OPTION_PACK_AFTER_COMMIT "pack-after-commit"
/* 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 6
+ independent of any other FS back ends.
+
+ Note: If you bump this, please update the switch statement in
+ svn_fs_fs__create() as well.
+ */
+#define SVN_FS_FS__FORMAT_NUMBER 7
/* The minimum format number that supports svndiff version 1. */
#define SVN_FS_FS__MIN_SVNDIFF1_FORMAT 2
@@ -144,9 +170,31 @@ extern "C" {
/* The minimum format number that supports packed revprops. */
#define SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT 6
+/* The minimum format number that supports packed revprops. */
+#define SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT 7
+
+/* Minimum format number that providing a separate lock file for pack ops */
+#define SVN_FS_FS__MIN_PACK_LOCK_FORMAT 7
+
+/* Minimum format number that stores mergeinfo-mode flag in changed paths */
+#define SVN_FS_FS__MIN_MERGEINFO_IN_CHANGED_FORMAT 7
+
+/* Minimum format number that supports per-instance filesystem IDs. */
+#define SVN_FS_FS__MIN_INSTANCE_ID_FORMAT 7
+
/* The minimum format number that supports a configuration file (fsfs.conf) */
#define SVN_FS_FS__MIN_CONFIG_FILE 4
+/* On most operating systems apr implements file locks per process, not
+ per file. On Windows apr implements the locking as per file handle
+ locks, so we don't have to add our own mutex for just in-process
+ synchronization. */
+#if APR_HAS_THREADS && !defined(WIN32)
+#define SVN_FS_FS__USE_LOCK_MUTEX 1
+#else
+#define SVN_FS_FS__USE_LOCK_MUTEX 0
+#endif
+
/* 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
@@ -157,13 +205,8 @@ typedef struct fs_fs_shared_txn_data_t
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];
+ /* ID of this transaction. */
+ svn_fs_fs__id_part_t txn_id;
/* Whether the transaction's prototype revision file is locked for
writing by any thread in this process (including the current
@@ -176,17 +219,6 @@ typedef struct fs_fs_shared_txn_data_t
apr_pool_t *pool;
} fs_fs_shared_txn_data_t;
-/* On most operating systems apr implements file locks per process, not
- per file. On Windows apr implements the locking as per file handle
- locks, so we don't have to add our own mutex for just in-process
- synchronization. */
-/* Compare ../libsvn_subr/named_atomic.c:USE_THREAD_MUTEX */
-#if APR_HAS_THREADS && !defined(WIN32)
-#define SVN_FS_FS__USE_LOCK_MUTEX 1
-#else
-#define SVN_FS_FS__USE_LOCK_MUTEX 0
-#endif
-
/* 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. */
@@ -202,6 +234,12 @@ typedef struct fs_fs_shared_data_t
Access to this object is synchronised under TXN_LIST_LOCK. */
fs_fs_shared_txn_data_t *free_txn;
+ /* The following lock must be taken out in reverse order of their
+ declaration here. Any subset may be acquired and held at any given
+ time but their relative acquisition order must not change.
+
+ (lock 'txn-current' before 'pack' before 'write' before 'txn-list') */
+
/* A lock for intra-process synchronization when accessing the TXNS list. */
svn_mutex__t *txn_list_lock;
@@ -209,6 +247,10 @@ typedef struct fs_fs_shared_data_t
repository write lock. */
svn_mutex__t *fs_write_lock;
+ /* A lock for intra-process synchronization when grabbing the
+ repository pack operation lock. */
+ svn_mutex__t *fs_pack_lock;
+
/* A lock for intra-process synchronization when locking the
txn-current file. */
svn_mutex__t *txn_current_lock;
@@ -221,34 +263,76 @@ typedef struct fs_fs_shared_data_t
/* Data structure for the 1st level DAG node cache. */
typedef struct fs_fs_dag_cache_t fs_fs_dag_cache_t;
-/* Key type for all caches that use revision + offset / counter as key. */
+/* Key type for all caches that use revision + offset / counter as key.
+
+ Note: Cache keys should be 16 bytes for best performance and there
+ should be no padding. */
typedef struct pair_cache_key_t
{
- svn_revnum_t revision;
+ /* The object's revision. Use the 64 data type to prevent padding. */
+ apr_int64_t revision;
+ /* Sub-address: item index, revprop generation, packed flag, etc. */
apr_int64_t second;
} pair_cache_key_t;
+/* Key type that identifies a txdelta window.
+
+ Note: Cache keys should require no padding. */
+typedef struct window_cache_key_t
+{
+ /* The object's revision. Use the 64 data type to prevent padding. */
+ apr_int64_t revision;
+
+ /* Window number within that representation. */
+ apr_int64_t chunk_index;
+
+ /* Item index of the representation */
+ apr_uint64_t item_index;
+} window_cache_key_t;
+
/* Private (non-shared) FSFS-specific data for each svn_fs_t object.
Any caches in here may be NULL. */
typedef struct fs_fs_data_t
{
/* 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;
+ /* If set, this FS is using logical addressing. Otherwise, it is using
+ physical addressing. */
+ svn_boolean_t use_log_addressing;
+
+ /* Rev / pack file read granularity in bytes. */
+ apr_int64_t block_size;
+
+ /* Capacity in entries of log-to-phys index pages */
+ apr_int64_t l2p_page_size;
+
+ /* Rev / pack file granularity (in bytes) covered by a single phys-to-log
+ * index page. */
+ apr_int64_t p2l_page_size;
+
+ /* If set, parse and cache *all* data of each block that we read
+ * (not just the one bit that we need, atm). */
+ svn_boolean_t use_block_read;
+
/* The revision that was youngest, last time we checked. */
svn_revnum_t youngest_rev_cache;
- /* The fsfs.conf file, parsed. Allocated in FS->pool. */
- svn_config_t *config;
-
- /* Caches of immutable data. (Note that if these are created with
- svn_cache__create_memcache, the data can be shared between
+ /* Caches of immutable data. (Note that these may be shared between
multiple svn_fs_t's for the same filesystem.) */
+ /* Access to the configured memcached instances. May be NULL. */
+ svn_memcache_t *memcache;
+
+ /* If TRUE, don't ignore any cache-related errors. If FALSE, errors from
+ e.g. memcached may be ignored as caching is an optional feature. */
+ svn_boolean_t fail_stop;
+
/* A cache of revision root IDs, mapping from (svn_revnum_t *) to
(svn_fs_id_t *). (Not threadsafe.) */
svn_cache__t *rev_root_id_cache;
@@ -269,21 +353,6 @@ typedef struct fs_fs_data_t
rep key (revision/offset) to svn_stringbuf_t. */
svn_cache__t *fulltext_cache;
- /* Access object to the atomics namespace used by revprop caching.
- Will be NULL until the first access. */
- svn_atomic_namespace__t *revprop_namespace;
-
- /* Access object to the revprop "generation". Will be NULL until
- the first access. */
- svn_named_atomic__t *revprop_generation;
-
- /* Access object to the revprop update timeout. Will be NULL until
- the first access. */
- svn_named_atomic__t *revprop_timeout;
-
- /* Revision property cache. Maps from (rev,generation) to apr_hash_t. */
- svn_cache__t *revprop_cache;
-
/* Node properties cache. Maps from rep key to apr_hash_t. */
svn_cache__t *properties_cache;
@@ -293,20 +362,28 @@ typedef struct fs_fs_data_t
respective pack file. */
svn_cache__t *packed_offset_cache;
- /* Cache for txdelta_window_t objects; the key is (revFilePath, offset) */
+ /* Cache for svn_fs_fs__raw_cached_window_t objects; the key is
+ window_cache_key_t. */
+ svn_cache__t *raw_window_cache;
+
+ /* Cache for txdelta_window_t objects; the key is window_cache_key_t */
svn_cache__t *txdelta_window_cache;
/* Cache for combined windows as svn_stringbuf_t objects;
- the key is (revFilePath, offset) */
+ the key is window_cache_key_t */
svn_cache__t *combined_window_cache;
- /* Cache for node_revision_t objects; the key is (revision, id offset) */
+ /* Cache for node_revision_t objects; the key is (revision, item_index) */
svn_cache__t *node_revision_cache;
/* Cache for change lists as APR arrays of change_t * objects; the key
is the revision */
svn_cache__t *changes_cache;
+ /* Cache for svn_fs_fs__rep_header_t objects; the key is a
+ (revision, item index) pair */
+ svn_cache__t *rep_header_cache;
+
/* Cache for svn_mergeinfo_t objects; the key is a combination of
revision, inheritance flags and path. */
svn_cache__t *mergeinfo_cache;
@@ -316,6 +393,23 @@ typedef struct fs_fs_data_t
if the node has mergeinfo, "0" if it doesn't. */
svn_cache__t *mergeinfo_existence_cache;
+ /* Cache for l2p_header_t objects; the key is (revision, is-packed).
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *l2p_header_cache;
+
+ /* Cache for l2p_page_t objects; the key is svn_fs_fs__page_cache_key_t.
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *l2p_page_cache;
+
+ /* Cache for p2l_header_t objects; the key is (revision, is-packed).
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *p2l_header_cache;
+
+ /* Cache for apr_array_header_t objects containing svn_fs_fs__p2l_entry_t
+ elements; the key is svn_fs_fs__page_cache_key_t.
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *p2l_page_cache;
+
/* TRUE while the we hold a lock on the write lock file. */
svn_boolean_t has_write_lock;
@@ -363,19 +457,27 @@ typedef struct fs_fs_data_t
* deltification history after which skip deltas will be used. */
apr_int64_t max_linear_deltification;
+ /* Compression level to use with txdelta storage format in new revs. */
+ int delta_compression_level;
+
+ /* Pack after every commit. */
+ svn_boolean_t pack_after_commit;
+
+ /* Per-instance filesystem ID, which provides an additional level of
+ uniqueness for filesystems that share the same UUID, but should
+ still be distinguishable (e.g. backups produced by svn_fs_hotcopy()
+ or dump / load cycles). */
+ const char *instance_id;
+
/* Pointer to svn_fs_open. */
svn_error_t *(*svn_fs_open_)(svn_fs_t **, const char *, apr_hash_t *,
- apr_pool_t *);
+ apr_pool_t *, apr_pool_t *);
} fs_fs_data_t;
/*** Filesystem Transaction ***/
typedef struct transaction_t
{
- /* 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;
@@ -395,26 +497,26 @@ typedef struct transaction_t
* svn_fs_fs__rep_copy. */
typedef struct representation_t
{
- /* Checksums for the contents produced by this representation.
+ /* Checksums digests 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 checksum is NULL, then for compatibility behave as though this
+ If has_sha1 is FALSE, then for compatibility behave as though this
checksum matches the expected checksum.
The md5 checksum is always filled, unless this is rep which was
retrieved from the rep-cache. The sha1 checksum is only computed on
- a write, for use with rep-sharing; it may be read from an existing
- representation, but otherwise it is NULL. */
- svn_checksum_t *md5_checksum;
- svn_checksum_t *sha1_checksum;
+ a write, for use with rep-sharing. */
+ svn_boolean_t has_sha1;
+ unsigned char sha1_digest[APR_SHA1_DIGESTSIZE];
+ unsigned char md5_digest[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;
+ /* Item index with the the revision. */
+ apr_uint64_t item_index;
/* The size of the representation in bytes as seen in the revision
file. */
@@ -424,17 +526,21 @@ typedef struct representation_t
* the fulltext size is equal to representation size in the rev file, */
svn_filesize_t expanded_size;
- /* Is this representation a transaction? */
- const char *txn_id;
+ /* Is this a representation (still) within a transaction? */
+ svn_fs_fs__id_part_t txn_id;
/* For rep-sharing, we need a way of uniquifying node-revs which share the
same representation (see svn_fs_fs__noderev_same_rep_key() ). So, we
store the original txn of the node rev (not the rep!), along with some
- intra-node uniqification content.
-
- May be NULL, in which case, it is considered to match other NULL
- values.*/
- const char *uniquifier;
+ intra-node uniqification content. */
+ struct
+ {
+ /* unique context, i.e. txn ID, in which the noderev (!) got created */
+ svn_fs_fs__id_part_t noderev_txn_id;
+
+ /* unique value within that txn */
+ apr_uint64_t number;
+ } uniquifier;
} representation_t;
@@ -494,25 +600,10 @@ typedef struct node_revision_t
typedef struct change_t
{
/* 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;
-
- /* Node kind (possibly svn_node_unknown). */
- svn_node_kind_t node_kind;
-
- /* Copyfrom revision and path. */
- svn_revnum_t copyfrom_rev;
- const char * copyfrom_path;
+ svn_string_t path;
+ /* API compatible change description */
+ svn_fs_path_change2_t info;
} change_t;