22// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
33
44use std:: collections:: HashMap ;
5- use std:: hash:: Hasher ;
5+ use std:: hash:: { BuildHasher , Hasher } ;
66use std:: sync:: Arc ;
7-
87use fnv:: FnvHasher ;
8+ use nohash_hasher:: BuildNoHashHasher ;
99use parking_lot:: RwLock ;
1010
1111use crate :: desc:: { Desc , Describer } ;
@@ -26,7 +26,8 @@ pub trait MetricVecBuilder: Send + Sync + Clone {
2626
2727#[ derive( Debug ) ]
2828pub ( crate ) struct MetricVecCore < T : MetricVecBuilder > {
29- pub children : RwLock < HashMap < u64 , T :: M > > ,
29+ // the key is pre-hashed, and so we use a no-hash hasher to avoid hashing again.
30+ pub children : RwLock < HashMap < u64 , T :: M , BuildNoHashHasher < u64 > > > ,
3031 pub desc : Desc ,
3132 pub metric_type : MetricType ,
3233 pub new_metric : T ,
@@ -59,7 +60,7 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
5960 self . get_or_create_metric ( h, vals)
6061 }
6162
62- pub fn get_metric_with ( & self , labels : & HashMap < & str , & str > ) -> Result < T :: M > {
63+ pub fn get_metric_with < S : BuildHasher > ( & self , labels : & HashMap < & str , & str , S > ) -> Result < T :: M > {
6364 let h = self . hash_labels ( labels) ?;
6465
6566 if let Some ( metric) = self . children . read ( ) . get ( & h) . cloned ( ) {
@@ -81,7 +82,7 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
8182 Ok ( ( ) )
8283 }
8384
84- pub fn delete ( & self , labels : & HashMap < & str , & str > ) -> Result < ( ) > {
85+ pub fn delete < S : BuildHasher > ( & self , labels : & HashMap < & str , & str , S > ) -> Result < ( ) > {
8586 let h = self . hash_labels ( labels) ?;
8687
8788 let mut children = self . children . write ( ) ;
@@ -113,7 +114,7 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
113114 Ok ( h. finish ( ) )
114115 }
115116
116- fn hash_labels ( & self , labels : & HashMap < & str , & str > ) -> Result < u64 > {
117+ fn hash_labels < S : BuildHasher > ( & self , labels : & HashMap < & str , & str , S > ) -> Result < u64 > {
117118 if labels. len ( ) != self . desc . variable_labels . len ( ) {
118119 return Err ( Error :: InconsistentCardinality {
119120 expect : self . desc . variable_labels . len ( ) ,
@@ -137,7 +138,7 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
137138 Ok ( h. finish ( ) )
138139 }
139140
140- fn get_label_values < ' a > ( & self , labels : & ' a HashMap < & str , & str > ) -> Result < Vec < & ' a str > > {
141+ fn get_label_values < ' a , S : BuildHasher > ( & self , labels : & ' a HashMap < & str , & str , S > ) -> Result < Vec < & ' a str > > {
141142 let mut values = Vec :: new ( ) ;
142143 for name in & self . desc . variable_labels {
143144 match labels. get ( & name. as_ref ( ) ) {
@@ -188,7 +189,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
188189 pub fn create ( metric_type : MetricType , new_metric : T , opts : T :: P ) -> Result < MetricVec < T > > {
189190 let desc = opts. describe ( ) ?;
190191 let v = MetricVecCore {
191- children : RwLock :: new ( HashMap :: new ( ) ) ,
192+ children : RwLock :: new ( HashMap :: default ( ) ) ,
192193 desc,
193194 metric_type,
194195 new_metric,
@@ -237,7 +238,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
237238 /// This method is used for the same purpose as
238239 /// `get_metric_with_label_values`. See there for pros and cons of the two
239240 /// methods.
240- pub fn get_metric_with ( & self , labels : & HashMap < & str , & str > ) -> Result < T :: M > {
241+ pub fn get_metric_with < S : BuildHasher > ( & self , labels : & HashMap < & str , & str , S > ) -> Result < T :: M > {
241242 self . v . get_metric_with ( labels)
242243 }
243244
@@ -261,7 +262,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
261262 /// `with` works as `get_metric_with`, but panics if an error occurs. The method allows
262263 /// neat syntax like:
263264 /// httpReqs.with(Labels{"status":"404", "method":"POST"}).inc()
264- pub fn with ( & self , labels : & HashMap < & str , & str > ) -> T :: M {
265+ pub fn with < S : BuildHasher > ( & self , labels : & HashMap < & str , & str , S > ) -> T :: M {
265266 self . get_metric_with ( labels) . unwrap ( )
266267 }
267268
@@ -289,7 +290,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
289290 ///
290291 /// This method is used for the same purpose as `delete_label_values`. See
291292 /// there for pros and cons of the two methods.
292- pub fn remove ( & self , labels : & HashMap < & str , & str > ) -> Result < ( ) > {
293+ pub fn remove < S : BuildHasher > ( & self , labels : & HashMap < & str , & str , S > ) -> Result < ( ) > {
293294 self . v . delete ( labels)
294295 }
295296
0 commit comments