Expand description
Version compatibility checking.
Provides version range checking and graceful degradation for reading files created with different format versions. Format version management and compatibility checking.
This module defines the versioning strategy for Hexz snapshot files (.hxz),
enabling safe evolution of the on-disk format while maintaining backward and
forward compatibility guarantees. Version negotiation ensures that readers can
detect incompatible snapshots and provide actionable error messages.
§Versioning Strategy
Hexz uses a monotonic integer versioning scheme where each version number represents a distinct on-disk format:
- Version 1: Initial format with two-level index, LZ4/Zstd compression, optional encryption, thin provisioning support
- Future versions: Reserved for incompatible format changes (e.g., new index structures, alternative serialization formats, block metadata extensions)
§Semantic Versioning Alignment
Format versions are independent of Hexz software versions (semver). A software release may support multiple format versions for backward compatibility. The mapping is defined as:
| Format Version | Hexz Software Versions | Key Changes |
|---|---|---|
| 1 | 0.1.0+ | Initial release |
§Compatibility Model
§Backward Compatibility (Reading Old Snapshots)
Hexz readers maintain compatibility with snapshots created by older software:
- MIN_SUPPORTED_VERSION: Oldest format version we can read (currently 1)
- Upgrade Path: Snapshots older than MIN_SUPPORTED_VERSION must be migrated
using the
hexz-migratetool (see Migration section below)
§Forward Compatibility (Reading New Snapshots)
Hexz readers handle snapshots created by newer software:
- MAX_SUPPORTED_VERSION: Newest format version we can read (currently 1)
- Degraded Mode: Future versions may enable partial reads with warnings if minor features are unrecognized (not yet implemented)
- Strict Rejection: Snapshots with
version > MAX_SUPPORTED_VERSIONare rejected with an actionable error message
§Version Negotiation Workflow
When opening a snapshot file:
1. Read header magic bytes (validate "HEXZ" signature)
2. Read header.version field
3. Call check_version(header.version)
4. If VersionCompatibility::Incompatible:
- Generate human-readable error via compatibility_message()
- Suggest upgrade/migration path
- Abort operation
5. If VersionCompatibility::Full:
- Proceed with normal operations
6. If VersionCompatibility::Degraded (future):
- Log warning about unsupported features
- Proceed with limited functionality§Adding New Format Versions
To introduce a breaking format change:
§Step 1: Increment Version Constant
pub const CURRENT_VERSION: u32 = 2; // Changed from 1
pub const MAX_SUPPORTED_VERSION: u32 = 2;§Step 2: Update Serialization Logic
Modify crate::format::header::Header or crate::format::index::MasterIndex
to include new fields or change existing structures. Use serde attributes to
maintain compatibility:
#[derive(Serialize, Deserialize)]
pub struct Header {
// Existing fields...
#[serde(skip_serializing_if = "Option::is_none")]
pub new_feature: Option<NewFeatureData>, // Version 2+ only
}§Step 3: Conditional Deserialization
Add version-aware deserialization in reader code:
match header.version {
1 => {
// Legacy path for version 1
read_index_v1(reader)?
}
2 => {
// New path for version 2
read_index_v2(reader)?
}
_ => unreachable!("check_version already validated"),
}§Step 4: Update Tests
Add test fixtures for the new format version:
#[test]
fn test_read_v2_snapshot() {
let snapshot = load_fixture("testdata/v2_snapshot.hxz");
assert_eq!(snapshot.header.version, 2);
// Verify new features work correctly
}§Step 5: Document Migration Path
Update the migration guide with conversion instructions (see Migration section).
§Migration Between Versions
The hexz-migrate tool converts snapshots between format versions:
# Upgrade old snapshot to current format
hexz-migrate upgrade --input old_v1.hxz --output new_v2.hxz
# Downgrade for compatibility (if supported)
hexz-migrate downgrade --input new_v2.hxz --output legacy_v1.hxz \
--target-version 1§Migration Algorithm
The migration tool performs a streaming rewrite:
- Open source snapshot with reader for version N
- Create destination snapshot with writer for version M
- Stream all blocks through decompression/re-compression
- Rebuild index in target format
- Preserve metadata (encryption keys, parent references, etc.)
§Lossy Migrations
Downgrading may lose features unsupported in the target version:
- Version 2 → 1: Hypothetical new features would be discarded with warnings
§Performance Considerations
Version checking is performed once per snapshot open operation:
- Overhead: Negligible (~100ns for integer comparison)
- Caching: Version is cached in
crate::api::file::Filestruct - Hot Path: Not in block read/write paths
§Examples
§Basic Version Check
use hexz_core::format::version::{check_version, VersionCompatibility};
let snapshot_version = 1;
let compat = check_version(snapshot_version);
match compat {
VersionCompatibility::Full => {
println!("Snapshot is fully compatible");
}
VersionCompatibility::Incompatible => {
eprintln!("Cannot read snapshot (incompatible version)");
}
VersionCompatibility::Degraded => {
println!("Snapshot readable with warnings");
}
}§User-Facing Error Messages
use hexz_core::format::version::compatibility_message;
let version = 999; // Future version
let message = compatibility_message(version);
println!("{}", message);
// Output: "Version 999 is too new (max supported: 1). Please upgrade Hexz."§Reader Implementation
use hexz_core::format::version::check_version;
use hexz_core::error::Error;
fn open_snapshot(path: &Path) -> Result<Snapshot, Error> {
let header = read_header(path)?;
if !check_version(header.version).is_compatible() {
return Err(Error::IncompatibleVersion {
found: header.version,
min_supported: MIN_SUPPORTED_VERSION,
max_supported: MAX_SUPPORTED_VERSION,
});
}
// Proceed with version-aware deserialization
Ok(Snapshot { header, /* ... */ })
}Enums§
- Version
Compatibility - Result of snapshot version compatibility analysis.
Constants§
- CURRENT_
VERSION - Current format version written by this build of Hexz.
- MAX_
SUPPORTED_ VERSION - Maximum format version readable by this build.
- MIN_
SUPPORTED_ VERSION - Minimum format version readable by this build.
Functions§
- check_
version - Determines compatibility status of a snapshot format version.
- compatibility_
message - Generates a user-facing message describing version compatibility status.