Repository: tikv/tikv
File: components/resource_metering/src/model.rs (Rust)

Code before:
    // tag -> record
    pub records: HashMap<Arc<TagInfos>, RawRecord>,
}

impl Default for RawRecords {
    fn default() -> Self {
        let now_unix_time = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .expect("clock may have gone backwards");
        Self {
            begin_unix_time_secs: now_unix_time.as_secs(),
            duration: Duration::default(),
            records: HashMap::default(),
        }
    }
}

impl RawRecords {
    /// Returns RawRecord aggregated by extra tag.
    pub fn aggregate_by_extra_tag(&self) -> HashMap<Vec<u8>, RawRecord>
    {
        let mut raw_map : HashMap<Vec<u8>, RawRecord> = HashMap::default();
        // Aggregate
        for (tag_info, record) in self.records.iter() {
            let tag = &tag_info.extra_attachment;
            if tag.is_empty() {
                continue;
            }       
            let value = raw_map.get_mut(tag);
            if value.is_none() {
                raw_map.insert(
                    tag.clone(),
                    *record,
                );
                continue;
            }
            value.unwrap().merge(record);
        }
        raw_map
    }
}

/// Resource statistics.
///
/// TODO(mornyx): Optimize to Vec<Item{timestamp,cpu_time,read_keys,write_keys}>
#[derive(Debug, Default, Clone)]
pub struct Record {
    pub timestamps: Vec<u64>,
    pub cpu_time_list: Vec<u32>,
    pub read_keys_list: Vec<u32>,
    pub write_keys_list: Vec<u32>,

Review comment (suggestion):
Since `extra_attachment` remains unmodified in this process, cloning it would be a waste, especially since it includes the SQL digtest. Maybe we can try to change the type of this field from `Vec<u8>` to `Arc<Vec<u8>>`, so that cloning will only incur the overhead of reference counting.

Code after:
    pub begin_unix_time_secs: u64,
    pub duration: Duration,

    // tag -> record
    pub records: HashMap<Arc<TagInfos>, RawRecord>,
}

impl Default for RawRecords {
    fn default() -> Self {
        let now_unix_time = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .expect("clock may have gone backwards");
        Self {
            begin_unix_time_secs: now_unix_time.as_secs(),
            duration: Duration::default(),
            records: HashMap::default(),
        }
    }
}

impl RawRecords {
    /// Returns RawRecord aggregated by extra tag.
    pub fn aggregate_by_extra_tag(&self) -> HashMap<Arc<Vec<u8>>, RawRecord> {
        let mut raw_map: HashMap<Arc<Vec<u8>>, RawRecord> = HashMap::default();
        for (tag_info, record) in self.records.iter() {
            let tag = &tag_info.extra_attachment;
            if tag.is_empty() {
                continue;
            }
            let value = raw_map.get_mut(tag);
            if value.is_none() {
                raw_map.insert(tag.clone(), *record);
                continue;
            }
            value.unwrap().merge(record);
        }
        raw_map
    }
}

/// Resource statistics.
///
/// TODO(mornyx): Optimize to Vec<Item{timestamp,cpu_time,read_keys,write_keys}>
#[derive(Debug, Default, Clone)]
pub struct Record {
    pub timestamps: Vec<u64>,
    pub cpu_time_list: Vec<u32>,
    pub read_keys_list: Vec<u32>,
    pub write_keys_list: Vec<u32>,
    pub total_cpu_time: u32,
}