system.storage.storage_layer module

Storage-hierarchy layer abstraction (DRAM, caches, SSD, disk, …) with address conversion.

class system.storage.storage_layer.AddressConversionStrategy[source]

Bases: ABC, Generic

A strategy to split an address used by one storage layer into the address of the layer below plus an offset within the fetched storage unit.

abstractmethod split_address(address: Address) → tuple[Address, Address][source]

Split the given address into two parts.

Parameters:

address – The address as seen by this storage layer.

Returns:

A pair (layer_below_address, offset): the first element is the address to look up in the layer below (e.g. a page id); the second is the offset used to index into the fetched storage unit in this layer.

class system.storage.storage_layer.StorageLayer(max_capacity: int, name: str = 'StorageLayer', layer_below: StorageLayer[Address, StorageUnit] | None = None, address_conversion_strategy: AddressConversionStrategy[Address] | None = None)[source]

Bases: KeyValueStore, Generic

A layer in a storage hierarchy, example incarnations of this are: DRAM, any L1, L2, L<whatever> cache, NVRAM, SSD, disk, tape, a CDN in a network, etc.

get(address: Address) → StorageUnit[source]

See PointQueryMixIn.get().

Storage-hierarchy variant: returns the single stored unit for the address rather than an iterator. On a miss in this layer, the address is looked up in the layer below (after optional address conversion) and the result is cached in this layer. Raises KeyError if there is no layer below to satisfy the miss.

put(address: Address, storage_unit: StorageUnit)[source]

See Index.put().

Overwrites any previous mapping for the given key. If this layer is at capacity, it first evicts an entry to the layer below to make room; a failed eviction raises ValueError.

fix(address: Address)[source]

Fix the key-value pair in this storage layer, i.e. this mapping may not be evicted anymore

unfix(address: Address)[source]

Unfixes the key-value pair in this storage layer, i.e. this mapping may again be evicted

choose_eviction_candidate() → Address[source]

Choose a key to evict from this storage layer. This implementation chooses a random key to evict (which is stupid and just done here for educational purposes: a real implementation would have a more sophisticated eviction policy like LRU, LFU, etc.).

evict() → int[source]

Evict some data from this storage layer to the layer below to make room for new data.

Returns:

The number of key-value pairs evicted from this storage layer.

size() → int[source]

See Index.size().

Counts only the entries held in this layer, not those in the layers below.

delete(key: Address, value: StorageUnit | None = None) → None[source]

See Index.delete().

Removes the mapping from this layer’s own storage only; the value argument is ignored. Raises KeyError if the key is not present here.

flush(key: Address | None = None) → None[source]

See Index.flush().

Not implemented for this storage layer: always raises NotImplementedError.

show() → None[source]

See Index.show().

Prints this layer’s name followed by its raw storage dictionary.