aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/layout/history.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2023-11-09 14:53:34 +0100
committerAlex Auvolat <alex@adnab.me>2023-11-09 14:53:34 +0100
commit94caf9c0c1342ce1d2ba3ac7af39fb133721ee83 (patch)
treeb1ac2bff79fb0f05256f0636e2272442c7994b6d /src/rpc/layout/history.rs
parentbfb1845fdc981a370539d641a5d80f438f184f07 (diff)
downloadgarage-94caf9c0c1342ce1d2ba3ac7af39fb133721ee83.tar.gz
garage-94caf9c0c1342ce1d2ba3ac7af39fb133721ee83.zip
layout: separate code path for synchronizing update trackers only
Diffstat (limited to 'src/rpc/layout/history.rs')
-rw-r--r--src/rpc/layout/history.rs51
1 files changed, 37 insertions, 14 deletions
diff --git a/src/rpc/layout/history.rs b/src/rpc/layout/history.rs
index 9ae28887..357b9d62 100644
--- a/src/rpc/layout/history.rs
+++ b/src/rpc/layout/history.rs
@@ -18,10 +18,11 @@ impl LayoutHistory {
let mut ret = LayoutHistory {
versions: vec![version].into_boxed_slice().into(),
update_trackers: Default::default(),
+ trackers_hash: [0u8; 32].into(),
staging: Lww::raw(0, staging),
staging_hash: [0u8; 32].into(),
};
- ret.staging_hash = ret.calculate_staging_hash();
+ ret.update_hashes();
ret
}
@@ -29,6 +30,15 @@ impl LayoutHistory {
self.versions.last().as_ref().unwrap()
}
+ pub(crate) fn update_hashes(&mut self) {
+ self.trackers_hash = self.calculate_trackers_hash();
+ self.staging_hash = self.calculate_staging_hash();
+ }
+
+ pub(crate) fn calculate_trackers_hash(&self) -> Hash {
+ blake2sum(&nonversioned_encode(&self.update_trackers).unwrap()[..])
+ }
+
pub(crate) fn calculate_staging_hash(&self) -> Hash {
blake2sum(&nonversioned_encode(&self.staging).unwrap()[..])
}
@@ -38,12 +48,6 @@ impl LayoutHistory {
pub fn merge(&mut self, other: &LayoutHistory) -> bool {
let mut changed = false;
- // Merge staged layout changes
- if self.staging != other.staging {
- changed = true;
- }
- self.staging.merge(&other.staging);
-
// Add any new versions to history
for v2 in other.versions.iter() {
if let Some(v1) = self.versions.iter().find(|v| v.version == v2.version) {
@@ -63,7 +67,21 @@ impl LayoutHistory {
}
// Merge trackers
- self.update_trackers.merge(&other.update_trackers);
+ if self.update_trackers != other.update_trackers {
+ let c = self.update_trackers.merge(&other.update_trackers);
+ changed = changed || c;
+ }
+
+ // Merge staged layout changes
+ if self.staging != other.staging {
+ self.staging.merge(&other.staging);
+ changed = true;
+ }
+
+ // Update hashes if there are changes
+ if changed {
+ self.update_hashes();
+ }
changed
}
@@ -100,7 +118,7 @@ To know the correct value of the new layout version, invoke `garage layout show`
parameters: self.staging.get().parameters.clone(),
roles: LwwMap::new(),
});
- self.staging_hash = self.calculate_staging_hash();
+ self.update_hashes();
Ok((self, msg))
}
@@ -110,20 +128,25 @@ To know the correct value of the new layout version, invoke `garage layout show`
parameters: Lww::new(self.current().parameters.clone()),
roles: LwwMap::new(),
});
- self.staging_hash = self.calculate_staging_hash();
+ self.update_hashes();
Ok(self)
}
pub fn check(&self) -> Result<(), String> {
// Check that the hash of the staging data is correct
- let staging_hash = self.calculate_staging_hash();
- if staging_hash != self.staging_hash {
+ if self.trackers_hash != self.calculate_trackers_hash() {
+ return Err("trackers_hash is incorrect".into());
+ }
+ if self.staging_hash != self.calculate_staging_hash() {
return Err("staging_hash is incorrect".into());
}
- // TODO: anythign more ?
+ for version in self.versions.iter() {
+ version.check()?;
+ }
- self.current().check()
+ // TODO: anythign more ?
+ Ok(())
}
}