feat(ecstore): complete AHashMap adaptation

- Add ahash dependency to ecstore crate
- Import AHashMap in object.rs and bucket_lifecycle_ops.rs
- Update StaleMultipartUploadCandidate.metadata to use AHashMap
- Update stale_upload_lifecycle_due to use generics
- Update stale_upload_current_size_with_opts to use generics
- Fix all .into() calls to use iter().collect() for AHashMap conversion
- Fix user_defined assignments to use iter().collect()
- Fix replacement_metadata to use AHashMap

All compilation errors resolved. rustfs-ecstore now compiles successfully.

Refs: https://github.com/rustfs/backlog/issues/2005

Co-Authored-By: heihutu <heihutu@gmail.com>
This commit is contained in:
houseme
2026-08-26 22:18:20 +08:00
parent 0b96a992d6
commit 2bd1d70729
8 changed files with 22 additions and 16 deletions
+3
View File
@@ -235,6 +235,9 @@ faster-hex = { workspace = true }
ratelimit = { workspace = true }
aws-smithy-http-client = { workspace = true, default-features = false, features = ["rustls-aws-lc"] }
# High-performance hashing
ahash = { workspace = true, features = ["serde"] }
# Observability and Metrics
metrics = { workspace = true }
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use ahash::AHashMap;
use super::{metadata_boundary, object_lock_boundary, runtime_boundary as runtime_sources};
use crate::bucket::lifecycle::bucket_lifecycle_audit::{
LcAuditEvent, LcEventSrc, emit_non_transitioned_expiration_event, emit_transition_complete_event,
@@ -2870,7 +2871,7 @@ fn spawn_transition_transaction_recovery_once(api: Arc<ECStore>) {
struct StaleMultipartUploadCandidate {
path: String,
initiated: OffsetDateTime,
metadata: Option<HashMap<String, String>>,
metadata: Option<AHashMap<String, String>>,
}
fn parse_stale_uploads_duration(env_key: &str, default: StdDuration) -> StdDuration {
@@ -2915,9 +2916,9 @@ async fn stale_upload_current_size(set: &Arc<SetDisks>, metadata: &HashMap<Strin
stale_upload_current_size_with_opts(set, metadata, upload_dir, false).await
}
async fn stale_upload_current_size_with_opts(
async fn stale_upload_current_size_with_opts<S: std::hash::BuildHasher>(
set: &Arc<SetDisks>,
metadata: &HashMap<String, String>,
metadata: &HashMap<String, String, S>,
upload_dir: &str,
no_lock: bool,
) -> Option<usize> {
@@ -2950,9 +2951,9 @@ async fn stale_upload_current_size_with_opts(
)
}
async fn stale_upload_lifecycle_due(
async fn stale_upload_lifecycle_due<S: std::hash::BuildHasher>(
set: &Arc<SetDisks>,
metadata: &HashMap<String, String>,
metadata: &HashMap<String, String, S>,
initiated: OffsetDateTime,
upload_dir: &str,
no_lock: bool,
@@ -2978,7 +2979,7 @@ async fn stale_upload_lifecycle_due(
.unwrap_or_default(),
is_latest: true,
delete_marker: false,
user_defined: metadata.clone(),
user_defined: metadata.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
..Default::default()
};
+1 -1
View File
@@ -5796,7 +5796,7 @@ fn decommission_remote_tiered_opts(
versioned: version_id.is_some(),
version_id,
mod_time: version.mod_time,
user_defined: version.metadata.clone(),
user_defined: version.metadata.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
src_pool_idx,
data_movement: true,
incl_free_versions: version.tier_free_version(),
+2 -2
View File
@@ -1008,7 +1008,7 @@ impl ObjectInfo {
successor_mod_time: fi.successor_mod_time,
etag,
inlined,
user_defined: Arc::new(metadata),
user_defined: Arc::new(metadata.iter().map(|(k, v)| (k.clone(), v.clone())).collect()),
transitioned_object,
transition_version_state: fi.transition_version_state,
checksum: fi.checksum.clone(),
@@ -1316,7 +1316,7 @@ impl ObjectInfo {
if part > 0
&& let Some(checksums) = self.parts.iter().find(|p| p.number == part).and_then(|p| p.checksums.clone())
{
return Ok((checksums, true));
return Ok((checksums.iter().map(|(k, v)| (k.clone(), v.clone())).collect(), true));
}
if let Some(data) = &self.checksum {
@@ -57,7 +57,7 @@ fn rebalance_remote_tiered_opts(
versioned: version_id.is_some(),
version_id,
mod_time: version.mod_time,
user_defined: version.metadata.clone(),
user_defined: version.metadata.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
src_pool_idx,
data_movement: true,
include_part_checksums: true,
+4 -4
View File
@@ -1280,7 +1280,7 @@ impl crate::storage_api_contracts::multipart::MultipartOperations for SetDisks {
mod_time: Some(OffsetDateTime::now_utc()),
actual_size,
index: index_op,
checksums: if checksums.is_empty() { None } else { Some(checksums) },
checksums: if checksums.is_empty() { None } else { Some(checksums.iter().map(|(k, v)| (k.clone(), v.clone())).collect()) },
..Default::default()
};
@@ -1468,7 +1468,7 @@ impl crate::storage_api_contracts::multipart::MultipartOperations for SetDisks {
max_parts,
part_number_marker,
user_defined: {
let mut metadata = fi.metadata.clone();
let mut metadata: HashMap<String, String> = fi.metadata.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
strip_internal_multipart_metadata(&mut metadata);
metadata
},
@@ -1727,7 +1727,7 @@ impl crate::storage_api_contracts::multipart::MultipartOperations for SetDisks {
let mod_time = opts.mod_time.unwrap_or_else(OffsetDateTime::now_utc);
for f in parts_metadatas.iter_mut() {
f.metadata = user_defined.clone();
f.metadata = user_defined.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
f.mod_time = Some(mod_time);
f.fresh = true;
}
@@ -1816,7 +1816,7 @@ impl crate::storage_api_contracts::multipart::MultipartOperations for SetDisks {
upload_id: upload_id.to_owned(),
user_defined: {
strip_internal_multipart_metadata(&mut fi.metadata);
fi.metadata.clone()
fi.metadata.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
},
..Default::default()
})
+3 -2
View File
@@ -19,6 +19,7 @@
//! bounds are unchanged, and the impls reach shared primitives through the
//! SetDisks core (io_primitives) via inherent calls.
use ahash::AHashMap;
use super::super::*;
use super::bitrot_self_verify::{BitrotSelfVerifyTarget, drop_failed_writer_disks, verify_written_bitrot_shards};
use crate::bucket::utils::is_meta_bucketname;
@@ -2697,7 +2698,7 @@ impl SetDisks {
)));
}
fi.metadata = user_defined.into();
fi.metadata = user_defined.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
fi.mod_time = mod_time;
fi.size = w_size as i64;
fi.versioned = opts.versioned || opts.version_suspended;
@@ -5882,7 +5883,7 @@ impl crate::storage_api_contracts::object::ObjectOperations for SetDisks {
} else {
None
};
let mut replacement_metadata: AHashMap<String, String> = (*src_info.user_defined).clone().into();
let mut replacement_metadata: AHashMap<String, String> = (*src_info.user_defined).iter().map(|(k, v)| (k.clone(), v.clone())).collect();
if let Some(part_checksums) = preserved_part_checksums {
rustfs_utils::http::insert_str(&mut replacement_metadata, rustfs_utils::http::SUFFIX_PART_CHECKSUMS, part_checksums);
}