diff --git a/spec/3-memory-layout.md b/spec/3-memory-layout.md index 67e61b2ac..00e89cf7f 100644 --- a/spec/3-memory-layout.md +++ b/spec/3-memory-layout.md @@ -54,7 +54,7 @@ offsets, etc. See the specification of the fields on [Map Header Fields](3_1-hea ## Global mutable state -The global mutable state is 36 bytes long. +The global mutable state is 33 bytes long. 1. Bytes 0..7 - the global mutable state lock, a [lock structure](3_2-lock-structure.md). @@ -62,12 +62,12 @@ The global mutable state is 36 bytes long. > (the write lock) level is used. This is done for sharing the lock implementation for the > global mutable state and segment headers (see below). - 2. Bytes 8..11 - the number of allocated [extra tier bulks](#extra-tier-bulks). A non-negative - 32-bit value, stored in the little-endian order. + 2. Bytes 8..10 - the number of allocated [extra tier bulks](#extra-tier-bulks). An unsigned 24-bit + value, stored in the little-endian order. See also the [extra tier bulk allocation](5-initialization.md#entra-tier-bulk-allocation) operation. - 3. Bytes 12..19 - the index of the first *free* segment tier. A non-negative 64-bit value, stored + 3. Bytes 11..15 - the index of the first *free* segment tier. An unsigned 40-bit value, stored in the little-endian order. Extra segment tiers are allocated in bulks, so there is usually a chain of allocated, but unused yet segment tiers. This field points to the head of this chain, or has value `0`, if there are no free segment tiers. @@ -79,11 +79,15 @@ The global mutable state is 36 bytes long. [`actualSegments`](3_1-header-fields.md#actualsegments) − 1) has tier index `actualSegments`, the first tier of the first extra tier bulk has tier index `actualSegments` + 1, etc. Tier indexes are 1-counted, because value 0 has some special meaning. - 4. Bytes 20..27 - the number of used extra segment tiers. A non-negative 64-bit value, stored in + 4. Bytes 16..20 - the number of used extra segment tiers. An unsigned 40-bit value, stored in the little-endian order. - 5. Bytes 28..35 - the offset of the segment headers area from the beginning of the memory of this - Chronicle Map instance. This field determines the size of [the 4th area of the general Chronicle - Map structure](#segment-headers-alignment). + 5. Bytes 21..24 - the offset of the segment headers area from the beginning of the memory of this + Chronicle Map instance. An unsigned 32-bit value, stored in the little-endian ordered. This field + determines the size of [the 4th area of the general Chronicle Map structure]( + #segment-headers-alignment). + 6. Bytes 25..32 - the Chronicle Map data store size, the offset to the end of the [main segments + area](#main-segments area) or the last [extra tier bulk](#extra-tier-bulks). A non-negative 64-bit + value, stored in the little-endian order. > The reference Java implementation: [`VanillaGlobalMutableState` > ](../src/main/java/net/openhft/chronicle/hash/VanillaGlobalMutableState.java). diff --git a/spec/3_2-lock-structure.md b/spec/3_2-lock-structure.md index eec64312b..4951fd715 100644 --- a/spec/3_2-lock-structure.md +++ b/spec/3_2-lock-structure.md @@ -158,7 +158,7 @@ acquiring read and update lock](#time-limited-read-or-update-lock-acquisition). > ## The reference Java implementation > -> Attempt operations: [`VanillaReadWriteUpdateWithWaitsLockingStrategy`]( +> Attempt, release and downgrade operations: [`VanillaReadWriteUpdateWithWaitsLockingStrategy`]( > https://github.com/OpenHFT/Chronicle-Algorithms/blob/master/src/main/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategy.java) > > Time-limited operations: [`BigSegmentHeader`]( diff --git a/spec/5-initialization.md b/spec/5-initialization.md index 120464c1e..db77d499c 100644 --- a/spec/5-initialization.md +++ b/spec/5-initialization.md @@ -50,10 +50,12 @@ existing Map, persisted to some file). 3-memory-layout.md#entry-space), i. e. zero out this tier's hash lookup, segment tier counters area and free list. 6. White the segment headers offset into the 5th field of the global mutable state. - 7. If the Chronicle Map is persisted, ensure all data written to the file is flushed to the disk. + 7. Write the offset to the end of the main segments area into the 6th field of the global mutable + state. + 8. If the Chronicle Map is persisted, ensure all data written to the file is flushed to the disk. For example on Linux, this could be done with `msync` and `fdatasync` calls, on Windows - with `FlushFileBuffers` system call. - 8. If the Chronicle Map is persisted, write the readiness bit into the header, i. e. the highest + 9. If the Chronicle Map is persisted, write the readiness bit into the header, i. e. the highest bit of the 32-bit word by offset 8 from the beginning of the file, read and written in the little-endian order. Read the [Size Prefix Blob]( https://github.com/OpenHFT/RFC/blob/master/Size-Prefixed-Blob/Size-Prefixed-Blob-0.1.md) @@ -125,6 +127,8 @@ by [global mutable state](3-memory-layout.md#global-mutable-state) lock. 7. Write the [index](3-memory-layout.md#tier-index) of the first tier in this extra tier bulk into the 3rd field (the index of the first *free* segment tier) of this Chronicle Map's global mutable state. + 8. Increment the value in the 6th field (the data store size) of the global mutable state by + [`tierBulkSizeInBytes`](3_1-header-fields.md#tierbulksizeinbytes). ## Tier allocation diff --git a/src/main/java/net/openhft/chronicle/hash/VanillaGlobalMutableState.java b/src/main/java/net/openhft/chronicle/hash/VanillaGlobalMutableState.java index 24678eb02..4b32eb051 100644 --- a/src/main/java/net/openhft/chronicle/hash/VanillaGlobalMutableState.java +++ b/src/main/java/net/openhft/chronicle/hash/VanillaGlobalMutableState.java @@ -18,6 +18,8 @@ package net.openhft.chronicle.hash; import net.openhft.chronicle.bytes.Byteable; import net.openhft.chronicle.values.Group; +import net.openhft.chronicle.values.Range; +import net.openhft.chronicle.values.Values; /** *