summaryrefslogtreecommitdiffstats
path: root/vendor/gix-odb/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-odb/src/lib.rs')
-rw-r--r--vendor/gix-odb/src/lib.rs152
1 files changed, 152 insertions, 0 deletions
diff --git a/vendor/gix-odb/src/lib.rs b/vendor/gix-odb/src/lib.rs
new file mode 100644
index 000000000..a63ea544f
--- /dev/null
+++ b/vendor/gix-odb/src/lib.rs
@@ -0,0 +1,152 @@
+//! Git stores all of its data as _Objects_, which are data along with a hash over all data. Thus it's an
+//! object store indexed by the signature of data itself with inherent deduplication: the same data will have the same hash,
+//! and thus occupy the same space within the store.
+//!
+//! There is only one all-round object store, also known as the [`Store`], as it supports ~~everything~~ most of what git has to offer.
+//!
+//! * loose object reading and writing
+//! * access to packed objects
+//! * multiple loose objects and pack locations as gathered from `alternates` files.
+//! ## Feature Flags
+#![cfg_attr(
+ feature = "document-features",
+ cfg_attr(doc, doc = ::document_features::document_features!())
+)]
+#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
+#![deny(missing_docs, rust_2018_idioms, unsafe_code)]
+
+use std::{
+ cell::RefCell,
+ path::PathBuf,
+ sync::{atomic::AtomicUsize, Arc},
+};
+
+use arc_swap::ArcSwap;
+use gix_features::{threading::OwnShared, zlib::stream::deflate};
+pub use gix_pack as pack;
+
+mod store_impls;
+pub use store_impls::{dynamic as store, loose};
+
+pub mod alternate;
+
+/// A way to access objects along with pre-configured thread-local caches for packed base objects as well as objects themselves.
+///
+/// By default, no cache will be used.
+pub struct Cache<S> {
+ /// The inner provider of trait implementations we use in conjunction with our caches.
+ ///
+ /// For calling methods on `inner`, prefer to make use of auto-dereferencing, i.e. `cache.inner_method()` instead of `cache.inner.inner_method()`.
+ inner: S,
+ // TODO: have single-threaded code-paths also for pack-creation (entries from counts) so that we can use OwnShared here
+ // instead of Arc. However, it's probably not that important as these aren't called often.
+ new_pack_cache: Option<Arc<cache::NewPackCacheFn>>,
+ new_object_cache: Option<Arc<cache::NewObjectCacheFn>>,
+ pack_cache: Option<RefCell<Box<cache::PackCache>>>,
+ object_cache: Option<RefCell<Box<cache::ObjectCache>>>,
+}
+
+///
+pub mod cache;
+
+///
+/// It can optionally compress the content, similarly to what would happen when using a [`loose::Store`][crate::loose::Store].
+///
+pub struct Sink {
+ compressor: Option<RefCell<deflate::Write<std::io::Sink>>>,
+ object_hash: gix_hash::Kind,
+}
+
+/// Create a new [`Sink`] with compression disabled.
+pub fn sink(object_hash: gix_hash::Kind) -> Sink {
+ Sink {
+ compressor: None,
+ object_hash,
+ }
+}
+
+///
+pub mod sink;
+
+///
+pub mod find;
+
+/// An object database equivalent to `/dev/null`, dropping all objects stored into it.
+mod traits;
+
+pub use traits::{Find, FindExt, Header, HeaderExt, Write};
+
+/// A thread-local handle to access any object.
+pub type Handle = Cache<store::Handle<OwnShared<Store>>>;
+/// A thread-local handle to access any object, but thread-safe and independent of the actual type of `OwnShared` or feature toggles in `gix-features`.
+pub type HandleArc = Cache<store::Handle<Arc<Store>>>;
+
+use store::types;
+
+/// The object store for use in any applications with support for auto-updates in the light of changes to the object database.
+///
+/// ### Features
+///
+/// - entirely lazy, creating an instance does no disk IO at all if [`Slots::Given`][store::init::Slots::Given] is used.
+/// - multi-threaded lazy-loading of indices and packs
+/// - per-thread pack and object caching avoiding cache trashing.
+/// - most-recently-used packs are always first for speedups if objects are stored in the same pack, typical for packs organized by
+/// commit graph and object age.
+/// - lock-free reading for perfect scaling across all cores, and changes to it don't affect readers as long as these don't want to
+/// enter the same branch.
+/// - sync with the state on disk if objects aren't found to catch up with changes if an object seems to be missing.
+/// - turn off the behaviour above for all handles if objects are expected to be missing due to spare checkouts.
+pub struct Store {
+ /// The central write lock without which the slotmap index can't be changed.
+ write: parking_lot::Mutex<()>,
+
+ /// The source directory from which all content is loaded, and the central write lock for use when a directory refresh is needed.
+ pub(crate) path: PathBuf,
+
+ /// The current working directory at the time this store was instantiated. It becomes relevant when resolving alternate paths
+ /// when re-reading the store configuration on updates when an object was missed.
+ /// Keeping it here helps to assure consistency even while a process changes its CWD.
+ pub(crate) current_dir: PathBuf,
+
+ /// A set of replacements that given a source OID return a destination OID. The vector is sorted.
+ pub(crate) replacements: Vec<(gix_hash::ObjectId, gix_hash::ObjectId)>,
+
+ /// A list of indices keeping track of which slots are filled with data. These are usually, but not always, consecutive.
+ pub(crate) index: ArcSwap<types::SlotMapIndex>,
+
+ /// The below state acts like a slot-map with each slot is mutable when the write lock is held, but readable independently of it.
+ /// This allows multiple file to be loaded concurrently if there is multiple handles requesting to load packs or additional indices.
+ /// The map is static and cannot typically change.
+ /// It's read often and changed rarely.
+ pub(crate) files: Vec<types::MutableIndexAndPack>,
+
+ /// The amount of handles that would prevent us from unloading packs or indices
+ pub(crate) num_handles_stable: AtomicUsize,
+ /// The amount of handles that don't affect our ability to compact our internal data structures or unload packs or indices.
+ pub(crate) num_handles_unstable: AtomicUsize,
+
+ /// The amount of times we re-read the disk state to consolidate our in-memory representation.
+ pub(crate) num_disk_state_consolidation: AtomicUsize,
+ /// If true, we are allowed to use multi-pack indices and they must have the `object_hash` or be ignored.
+ use_multi_pack_index: bool,
+ /// The hash kind to use for some operations
+ object_hash: gix_hash::Kind,
+}
+
+/// Create a new cached handle to the object store with support for additional options.
+///
+/// `replacements` is an iterator over pairs of old and new object ids for replacement support.
+/// This means that when asking for object `X`, one will receive object `X-replaced` given an iterator like `Some((X, X-replaced))`.
+pub fn at_opts(
+ objects_dir: impl Into<PathBuf>,
+ replacements: impl IntoIterator<Item = (gix_hash::ObjectId, gix_hash::ObjectId)>,
+ options: store::init::Options,
+) -> std::io::Result<Handle> {
+ let handle = OwnShared::new(Store::at_opts(objects_dir, replacements, options)?).to_handle();
+ Ok(Cache::from(handle))
+}
+
+/// Create a new cached handle to the object store.
+pub fn at(objects_dir: impl Into<PathBuf>) -> std::io::Result<Handle> {
+ at_opts(objects_dir, Vec::new().into_iter(), Default::default())
+}