From 207992a71d5d9c9ee5d09c90f30a9dd35991691d Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Wed, 11 May 2022 13:38:47 +0200 Subject: [PATCH] introduce store and store objects without file system details this leaves open implementation details, especially about store paths and file system objects, and allows explaining them together were it is more appropriate. also leaves room to carefully introduce the key insight behind Nix: applying results from programming language theory to the operating system paradigm of files and processes. --- doc/manual/src/architecture/store/store.md | 57 ++++++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/doc/manual/src/architecture/store/store.md b/doc/manual/src/architecture/store/store.md index 808e87581..f421a9ec3 100644 --- a/doc/manual/src/architecture/store/store.md +++ b/doc/manual/src/architecture/store/store.md @@ -1,12 +1,59 @@ # Store -A Nix store is a collection of [store objects](objects.md) with associated operations. +A Nix store is a collection of *store objects*. -These store objects can hold arbitrary data, and Nix makes no distinction if they are used as build inputs, build results, or build tasks. +Store objects can hold arbitrary *data* and *references* to one another. +Nix makes no distinction if they are used as build inputs, build results, or build tasks. -A Nix store allows adding, retrieving, and deleting store objects. -It can perform builds, that is, transform build inputs using instructions from the build tasks into build outputs. -It also keeps track of *references* between data and can therefore garbage-collect unused store objects. +```haskell +data Store = Set StoreObject + +data StoreObject = StoreObject { + data :: Data +, references :: Set Reference +} +``` + +A Nix store can *add*, *retrieve*, and *delete* store objects. + +It can *perform builds*, that is, create new store objects by transforming build inputs, using instructions from the build tasks, into build outputs. + +As it keeps track of references, it can [garbage-collect](https://en.m.wikipedia.org/wiki/Garbage_collection_(computer_science)) unused store objects. + +```haskell +add :: Store -> Data -> (Store, Reference) +get :: Store -> Reference -> StoreObject +delete :: Store -> Reference -> Store + +build :: Store -> Reference -> Maybe (Store, Reference) + +collectGarbage :: Store -> Store +``` + +Store objects are [immutable](https://en.m.wikipedia.org/wiki/Immutable_object): once created, they do not change until they are deleted. + +References are [opaque](https://en.m.wikipedia.org/wiki/Opaque_data_type), [unique identifiers](https://en.m.wikipedia.org/wiki/Unique_identifier): +The only way to obtain references is by adding or building store objects. +A reference will always point to exactly one store object. + +An added store object cannot have references, unless it is a build task. + +Building a store object will add appropriate references, according to provided build instructions. +These references can only come from declared build inputs, and are not known by build instructions a priori. + +```haskell +data Data = Data | Task BuildTask + +data BuildTask = BuildTask { + instructions :: Reference +, inputs :: [Reference] +} +``` + +A store object cannot be deleted as long as it is reachable from a reference still in use. +Garbage collection will delete all store objects that cannot be reached from any reference in use. + + There exist different types of stores, which all follow this model. Examples: