The program storage
The storage service: it keeps the private store of each program on the data disk, through a block service. No program sees a shared tree of names.
The root service decides who has a store: it names the store of each connection, and its limit of blocks. A program reaches its own store only: the exports take the name of an object, never the name of a store. The root service names a program that it starts again with the same name, and the program finds its data.
A change is one commit, on the disk when the call returns: the system has no save action. The state of an object before a change is a version: a program reads, compares, restores and clones versions with no code of its own. The disk always has the state of the last commit, or of the one before: a stop of the machine during a commit never shows a part of it. The checks of the blocks show each change that the service did not make.
The person sees all the stores with stores(), from a program that acts for the person: the console.
| Fact | Value |
|---|---|
| Source | programs/storage |
| Boot image | in the boot image; the image is not built, so its size is not known |
| Imports | none |
| Imported by | none |
Exports
| Export | What it does |
|---|---|
| write(name: Text, data: Text) -> Integer | replaces the object with this name in the store of the caller, with the bytes of data, in one commit on the disk |
| read(name: Text) -> Text | gives the bytes of the object with this name in the store of the caller, or a negative number with an error record |
| size(name: Text) -> Integer | gives the count of bytes of the object with this name in the store of the caller, or a negative number with an error record |
| remove(name: Text) -> Integer | removes the object with this name and all its versions from the store of the caller, in one commit |
| objects() -> Text | gives the objects of the store of the caller: the name, the bytes and the generation of the last change of each one, and the word damaged for an object with a wrong block |
| stores() -> Text | gives each store of the disk, one line for each, with its objects, its versions, its blocks (a shared block counted one time), the blocks that two names share, its limit, the count of connections that hold its grant now, and its damage |
| versions(store: Text, name: Text) -> Table(Version) | gives the states of an object of a store, the oldest first, and its current version last: the generation, the time since the format of the disk, the date, the bytes, and the blocks that only this state holds |
| version(store: Text, name: Text, generation: Integer) -> Text | gives the bytes of an object of a store at a generation: one of its versions, or its current version |
| restore(store: Text, name: Text, generation: Integer) -> Integer | makes a version of an object of a store its current version again, in one commit: the current version before it becomes a version, so nothing is lost |
| clone(store: Text, name: Text, new_name: Text) -> Integer | makes the object new_name of a store a copy of the object name: the two name the same blocks until one of them changes |
| compare(store: Text, name: Text, first: Integer, second: Integer) -> Table(Byte_Range) | gives the ranges of bytes that differ between two states of an object of a store (two generations: a version or the current version) |
| entry() |
Read from the source of the module, as the build reads it to describe the exports (tools/kerneltool/describe.odin).
What the root service gives it
| What | Value | As the root service says |
|---|---|---|
| Grants | {.Serve, .Data_Disk} | |
| Budget: pages, programs, threads | {pages = 4096, programs = 1, threads = 1} | About 9 MB of tables: the count of names of each block of the disk, the changes of one commit, the leaves of one version index, and the versions of one object for versions(). |
Read from grants_of and things_of in programs/root/main.odin; budget_of in the same file adds the limits of processor time and of log records.
