@@ -849,7 +849,10 @@ fn max_tracked_keys_caps_across_per_metric_buckets() {
849849
850850fn make_per_tag ( value_limit : usize ) -> PerTagConfig {
851851 PerTagConfig {
852- mode : PerTagMode :: LimitOverride { value_limit } ,
852+ mode : PerTagMode :: LimitOverride {
853+ value_limit,
854+ cache_size_per_key : None ,
855+ } ,
853856 }
854857}
855858
@@ -1127,7 +1130,10 @@ fn tag_excluded_unbounded_sibling_limited() {
11271130#[ test]
11281131fn per_tag_limit_override_caps_at_explicit_value ( ) {
11291132 let per_tag = PerTagConfig {
1130- mode : PerTagMode :: LimitOverride { value_limit : 2 } ,
1133+ mode : PerTagMode :: LimitOverride {
1134+ value_limit : 2 ,
1135+ cache_size_per_key : None ,
1136+ } ,
11311137 } ;
11321138 let config = make_transform_hashset_with_per_metric_limits (
11331139 500 ,
@@ -1210,7 +1216,13 @@ per_metric_limits:
12101216 let per_metric = parsed. per_metric_limits . get ( "metric_a" ) . unwrap ( ) ;
12111217
12121218 let capped = per_metric. per_tag_limits . get ( "capped_tag" ) . unwrap ( ) ;
1213- assert_eq ! ( capped. mode, PerTagMode :: LimitOverride { value_limit: 10 } ) ;
1219+ assert_eq ! (
1220+ capped. mode,
1221+ PerTagMode :: LimitOverride {
1222+ value_limit: 10 ,
1223+ cache_size_per_key: None ,
1224+ }
1225+ ) ;
12141226
12151227 let excluded = per_metric. per_tag_limits . get ( "excluded_tag" ) . unwrap ( ) ;
12161228 assert_eq ! ( excluded. mode, PerTagMode :: Excluded ) ;
@@ -1456,8 +1468,134 @@ per_tag_limits:
14561468 let parsed: Config = serde_yaml:: from_str ( yaml) . expect ( "yaml should deserialize" ) ;
14571469
14581470 let capped = parsed. per_tag_limits . get ( "capped_tag" ) . unwrap ( ) ;
1459- assert_eq ! ( capped. mode, PerTagMode :: LimitOverride { value_limit: 10 } ) ;
1471+ assert_eq ! (
1472+ capped. mode,
1473+ PerTagMode :: LimitOverride {
1474+ value_limit: 10 ,
1475+ cache_size_per_key: None ,
1476+ }
1477+ ) ;
14601478
14611479 let excluded = parsed. per_tag_limits . get ( "excluded_tag" ) . unwrap ( ) ;
14621480 assert_eq ! ( excluded. mode, PerTagMode :: Excluded ) ;
14631481}
1482+
1483+ // ============================================================================
1484+ // cache_size_per_key override tests
1485+ // ============================================================================
1486+
1487+ /// `apply_cache_size_override` replaces the bloom size when mode is probabilistic and an
1488+ /// override is given; leaves the mode unchanged in all other cases.
1489+ #[ test]
1490+ fn apply_cache_size_override_probabilistic_with_some ( ) {
1491+ let base = Mode :: Probabilistic ( BloomFilterConfig {
1492+ cache_size_per_key : default_cache_size ( ) ,
1493+ } ) ;
1494+ let result = apply_cache_size_override ( base, Some ( 1024 ) ) ;
1495+ assert_eq ! (
1496+ result,
1497+ Mode :: Probabilistic ( BloomFilterConfig {
1498+ cache_size_per_key: 1024 ,
1499+ } )
1500+ ) ;
1501+ }
1502+
1503+ #[ test]
1504+ fn apply_cache_size_override_exact_with_some_is_noop ( ) {
1505+ let result = apply_cache_size_override ( Mode :: Exact , Some ( 1024 ) ) ;
1506+ assert_eq ! ( result, Mode :: Exact ) ;
1507+ }
1508+
1509+ #[ test]
1510+ fn apply_cache_size_override_probabilistic_with_none_inherits ( ) {
1511+ let base = Mode :: Probabilistic ( BloomFilterConfig {
1512+ cache_size_per_key : default_cache_size ( ) ,
1513+ } ) ;
1514+ let result = apply_cache_size_override ( base, None ) ;
1515+ assert_eq ! (
1516+ result,
1517+ Mode :: Probabilistic ( BloomFilterConfig {
1518+ cache_size_per_key: default_cache_size( ) ,
1519+ } )
1520+ ) ;
1521+ }
1522+
1523+ /// A per-metric `limit_override` with `cache_size_per_key` set deserializes correctly.
1524+ #[ test]
1525+ fn per_tag_cache_size_per_key_deserializes ( ) {
1526+ let yaml = r#"
1527+ value_limit: 5
1528+ mode: probabilistic
1529+ cache_size_per_key: 5120
1530+ per_metric_limits:
1531+ metric_a:
1532+ mode: probabilistic
1533+ cache_size_per_key: 5120
1534+ per_tag_limits:
1535+ big_tag:
1536+ mode: limit_override
1537+ value_limit: 100
1538+ cache_size_per_key: 32768
1539+ default_tag:
1540+ mode: limit_override
1541+ value_limit: 10
1542+ "# ;
1543+ let parsed: Config = serde_yaml:: from_str ( yaml) . expect ( "yaml should deserialize" ) ;
1544+ let per_metric = parsed. per_metric_limits . get ( "metric_a" ) . unwrap ( ) ;
1545+
1546+ let big_tag = per_metric. per_tag_limits . get ( "big_tag" ) . unwrap ( ) ;
1547+ assert_eq ! (
1548+ big_tag. mode,
1549+ PerTagMode :: LimitOverride {
1550+ value_limit: 100 ,
1551+ cache_size_per_key: Some ( 32768 ) ,
1552+ }
1553+ ) ;
1554+
1555+ // Omitting the field defaults to None (inherits from enclosing config).
1556+ let default_tag = per_metric. per_tag_limits . get ( "default_tag" ) . unwrap ( ) ;
1557+ assert_eq ! (
1558+ default_tag. mode,
1559+ PerTagMode :: LimitOverride {
1560+ value_limit: 10 ,
1561+ cache_size_per_key: None ,
1562+ }
1563+ ) ;
1564+ }
1565+
1566+ /// A global `per_tag_limits` `limit_override` with `cache_size_per_key` set deserializes correctly.
1567+ #[ test]
1568+ fn global_per_tag_cache_size_per_key_deserializes ( ) {
1569+ let yaml = r#"
1570+ value_limit: 5
1571+ mode: probabilistic
1572+ cache_size_per_key: 5120
1573+ per_tag_limits:
1574+ big_tag:
1575+ mode: limit_override
1576+ value_limit: 100
1577+ cache_size_per_key: 32768
1578+ default_tag:
1579+ mode: limit_override
1580+ value_limit: 10
1581+ "# ;
1582+ let parsed: Config = serde_yaml:: from_str ( yaml) . expect ( "yaml should deserialize" ) ;
1583+
1584+ let big_tag = parsed. per_tag_limits . get ( "big_tag" ) . unwrap ( ) ;
1585+ assert_eq ! (
1586+ big_tag. mode,
1587+ PerTagMode :: LimitOverride {
1588+ value_limit: 100 ,
1589+ cache_size_per_key: Some ( 32768 ) ,
1590+ }
1591+ ) ;
1592+
1593+ let default_tag = parsed. per_tag_limits . get ( "default_tag" ) . unwrap ( ) ;
1594+ assert_eq ! (
1595+ default_tag. mode,
1596+ PerTagMode :: LimitOverride {
1597+ value_limit: 10 ,
1598+ cache_size_per_key: None ,
1599+ }
1600+ ) ;
1601+ }
0 commit comments