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 ;
77
88use fnv:: FnvHasher ;
@@ -11,6 +11,7 @@ use parking_lot::RwLock;
1111use crate :: desc:: { Desc , Describer } ;
1212use crate :: errors:: { Error , Result } ;
1313use crate :: metrics:: { Collector , Metric } ;
14+ use crate :: nohash:: BuildNoHashHasher ;
1415use crate :: proto:: { MetricFamily , MetricType } ;
1516
1617/// An interface for building a metric vector.
@@ -26,7 +27,8 @@ pub trait MetricVecBuilder: Send + Sync + Clone {
2627
2728#[ derive( Debug ) ]
2829pub ( crate ) struct MetricVecCore < T : MetricVecBuilder > {
29- pub children : RwLock < HashMap < u64 , T :: M > > ,
30+ // the key is pre-hashed, and so we use a no-hash hasher to avoid hashing again.
31+ pub children : RwLock < HashMap < u64 , T :: M , BuildNoHashHasher > > ,
3032 pub desc : Desc ,
3133 pub metric_type : MetricType ,
3234 pub new_metric : T ,
@@ -62,7 +64,7 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
6264 self . get_or_create_metric ( h, vals)
6365 }
6466
65- pub fn get_metric_with < V > ( & self , labels : & HashMap < & str , V > ) -> Result < T :: M >
67+ pub fn get_metric_with < V , S : BuildHasher > ( & self , labels : & HashMap < & str , V , S > ) -> Result < T :: M >
6668 where
6769 V : AsRef < str > + std:: fmt:: Debug ,
6870 {
@@ -90,7 +92,7 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
9092 Ok ( ( ) )
9193 }
9294
93- pub fn delete < V > ( & self , labels : & HashMap < & str , V > ) -> Result < ( ) >
95+ pub fn delete < V , S : BuildHasher > ( & self , labels : & HashMap < & str , V , S > ) -> Result < ( ) >
9496 where
9597 V : AsRef < str > + std:: fmt:: Debug ,
9698 {
@@ -128,7 +130,7 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
128130 Ok ( h. finish ( ) )
129131 }
130132
131- fn hash_labels < V > ( & self , labels : & HashMap < & str , V > ) -> Result < u64 >
133+ fn hash_labels < V , S : BuildHasher > ( & self , labels : & HashMap < & str , V , S > ) -> Result < u64 >
132134 where
133135 V : AsRef < str > + std:: fmt:: Debug ,
134136 {
@@ -155,7 +157,10 @@ impl<T: MetricVecBuilder> MetricVecCore<T> {
155157 Ok ( h. finish ( ) )
156158 }
157159
158- fn get_label_values < ' a , V > ( & ' a self , labels : & ' a HashMap < & str , V > ) -> Result < Vec < & ' a str > >
160+ fn get_label_values < ' a , V , S : BuildHasher > (
161+ & ' a self ,
162+ labels : & ' a HashMap < & str , V , S > ,
163+ ) -> Result < Vec < & ' a str > >
159164 where
160165 V : AsRef < str > + std:: fmt:: Debug ,
161166 {
@@ -212,7 +217,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
212217 pub fn create ( metric_type : MetricType , new_metric : T , opts : T :: P ) -> Result < MetricVec < T > > {
213218 let desc = opts. describe ( ) ?;
214219 let v = MetricVecCore {
215- children : RwLock :: new ( HashMap :: new ( ) ) ,
220+ children : RwLock :: new ( HashMap :: default ( ) ) ,
216221 desc,
217222 metric_type,
218223 new_metric,
@@ -264,7 +269,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
264269 /// This method is used for the same purpose as
265270 /// `get_metric_with_label_values`. See there for pros and cons of the two
266271 /// methods.
267- pub fn get_metric_with < V > ( & self , labels : & HashMap < & str , V > ) -> Result < T :: M >
272+ pub fn get_metric_with < V , S : BuildHasher > ( & self , labels : & HashMap < & str , V , S > ) -> Result < T :: M >
268273 where
269274 V : AsRef < str > + std:: fmt:: Debug ,
270275 {
@@ -294,7 +299,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
294299 /// `with` works as `get_metric_with`, but panics if an error occurs. The method allows
295300 /// neat syntax like:
296301 /// httpReqs.with(Labels{"status":"404", "method":"POST"}).inc()
297- pub fn with < V > ( & self , labels : & HashMap < & str , V > ) -> T :: M
302+ pub fn with < V , S : BuildHasher > ( & self , labels : & HashMap < & str , V , S > ) -> T :: M
298303 where
299304 V : AsRef < str > + std:: fmt:: Debug ,
300305 {
@@ -328,7 +333,7 @@ impl<T: MetricVecBuilder> MetricVec<T> {
328333 ///
329334 /// This method is used for the same purpose as `delete_label_values`. See
330335 /// there for pros and cons of the two methods.
331- pub fn remove < V > ( & self , labels : & HashMap < & str , V > ) -> Result < ( ) >
336+ pub fn remove < V , S : BuildHasher > ( & self , labels : & HashMap < & str , V , S > ) -> Result < ( ) >
332337 where
333338 V : AsRef < str > + std:: fmt:: Debug ,
334339 {
0 commit comments