Skip to content

Commit b42fd45

Browse files
committed
feat(agent): improve deleting a set of rules into the router
1 parent 5614cd1 commit b42fd45

File tree

13 files changed

+187
-17
lines changed

13 files changed

+187
-17
lines changed

src/api/rules_message.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::api::Rule;
22
use crate::router::Router;
33
use serde::{Deserialize, Serialize};
4+
use std::collections::HashSet;
45
use std::sync::Arc;
56

67
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -11,9 +12,9 @@ pub struct RulesMessage {
1112

1213
#[derive(Deserialize, Debug, Clone)]
1314
pub struct RuleChangeSet {
14-
pub deleted: Vec<String>,
1515
pub added: Vec<Rule>,
1616
pub updated: Vec<Rule>,
17+
pub deleted: HashSet<String>,
1718
}
1819

1920
impl RuleChangeSet {

src/regex_radix_tree/item.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ impl<V> Item<V> {
6767
}
6868
}
6969

70+
pub fn retain<F>(self, f: &F) -> Item<V>
71+
where
72+
F: Fn(&str, &mut V) -> bool,
73+
{
74+
match self {
75+
Item::Empty(_) => self,
76+
Item::Node(node) => node.retain(f),
77+
Item::Leaf(leaf) => leaf.retain(f),
78+
}
79+
}
80+
7081
/// Length of node
7182
pub fn len(&self) -> usize {
7283
match self {

src/regex_radix_tree/leaf.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,18 @@ impl<V> Leaf<V> {
9999
}
100100
}
101101
}
102+
pub fn retain<F>(mut self, f: &F) -> Item<V>
103+
where
104+
F: Fn(&str, &mut V) -> bool,
105+
{
106+
self.values.retain(|k, v| f(k, v));
107+
108+
if self.values.is_empty() {
109+
Item::Empty(self.regex.ignore_case)
110+
} else {
111+
Item::Leaf(self)
112+
}
113+
}
102114

103115
/// Length of node
104116
pub fn len(&self) -> usize {

src/regex_radix_tree/node.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,33 @@ impl<V> Node<V> {
140140
(Item::Node(self), removed)
141141
}
142142

143+
pub fn retain<F>(mut self, f: &F) -> Item<V>
144+
where
145+
F: Fn(&str, &mut V) -> bool,
146+
{
147+
let mut children = Vec::new();
148+
149+
for child in self.children {
150+
let child = child.retain(f);
151+
152+
if !child.is_empty() {
153+
children.push(child);
154+
}
155+
}
156+
157+
if children.is_empty() {
158+
return Item::Empty(self.regex.ignore_case);
159+
}
160+
161+
if children.len() == 1 {
162+
return children.pop().unwrap();
163+
}
164+
165+
self.children = children;
166+
167+
Item::Node(self)
168+
}
169+
143170
/// Length of node
144171
pub fn len(&self) -> usize {
145172
let mut count = 0;

src/regex_radix_tree/tree.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ impl<V> RegexTreeMap<V> {
4343
removed
4444
}
4545

46+
pub fn retain<F>(&mut self, f: &F)
47+
where
48+
F: Fn(&str, &mut V) -> bool,
49+
{
50+
let mut root = Item::Empty(false);
51+
std::mem::swap(&mut self.root, &mut root);
52+
let root = root.retain(f);
53+
self.root = root;
54+
}
55+
4656
pub fn len(&self) -> usize {
4757
self.root.len()
4858
}
@@ -114,6 +124,13 @@ impl<V> UniqueRegexTreeMap<V> {
114124
self.tree.remove(regex)
115125
}
116126

127+
pub fn retain<F>(&mut self, f: &F)
128+
where
129+
F: Fn(&str, &mut V) -> bool,
130+
{
131+
self.tree.retain(f)
132+
}
133+
117134
pub fn len(&self) -> usize {
118135
self.tree.len()
119136
}

src/router/mod.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use route_weekday::RouteWeekday;
2020
pub use trace::{RouteTrace, Trace};
2121

2222
use core::cmp::Reverse;
23-
use std::collections::HashMap;
23+
use std::collections::{HashMap, HashSet};
2424
use std::sync::Arc;
2525

2626
#[derive(Debug, Clone)]
@@ -76,6 +76,11 @@ impl<T> Router<T> {
7676
}
7777
}
7878

79+
pub fn batch_remove(&mut self, ids: &HashSet<String>) {
80+
self.routes.retain(|id, _| !ids.contains(id));
81+
self.matcher.batch_remove(ids);
82+
}
83+
7984
pub fn rebuild_request(&self, request: &Request) -> Request {
8085
Request::rebuild_with_config(self.config.as_ref(), request)
8186
}
@@ -154,16 +159,17 @@ where
154159
self.insert_route(item.into_route(self.config.as_ref()));
155160
}
156161

157-
pub fn apply_change_set(&mut self, added: Vec<T>, updated: Vec<T>, removed: Vec<String>) {
158-
for id in removed {
159-
self.remove(id.as_str());
160-
}
162+
pub fn apply_change_set(&mut self, added: Vec<T>, updated: Vec<T>, mut removed: HashSet<String>) {
163+
let updated_route = updated
164+
.into_iter()
165+
.map(|item| item.into_route(self.config.as_ref()))
166+
.collect::<Vec<Route<T>>>();
161167

162-
for item in updated {
163-
let route = item.into_route(self.config.as_ref());
168+
removed.extend(updated_route.iter().map(|item| item.id().to_string()));
169+
self.batch_remove(&removed);
164170

165-
self.remove(route.id());
166-
self.insert_route(route);
171+
for item in updated_route {
172+
self.insert_route(item);
167173
}
168174

169175
for item in added {

src/router/request_matcher/datetime.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use super::super::trace::{TraceInfo, TraceInfoDateTimeCondition};
66
use super::super::{Route, RouterConfig, Trace};
77
use crate::http::Request;
88
use serde::{Deserialize, Serialize};
9-
use std::collections::BTreeMap;
109
use std::collections::BTreeSet;
10+
use std::collections::{BTreeMap, HashSet};
1111
use std::sync::Arc;
1212

1313
#[derive(Debug, Clone)]
@@ -106,6 +106,18 @@ impl<T> DateTimeMatcher<T> {
106106
removed
107107
}
108108

109+
pub fn batch_remove(&mut self, ids: &HashSet<String>) -> bool {
110+
self.any_datetime.batch_remove(ids);
111+
112+
self.condition_groups.retain(|_, matcher| {
113+
matcher.batch_remove(ids);
114+
115+
!matcher.is_empty()
116+
});
117+
118+
self.any_datetime.is_empty() && self.condition_groups.is_empty()
119+
}
120+
109121
pub fn match_request(&self, request: &Request) -> Vec<Arc<Route<T>>> {
110122
let mut rules = self.any_datetime.match_request(request);
111123
let mut execute_conditions = BTreeMap::new();

src/router/request_matcher/header.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use super::super::{Route, RouteHeaderKind, Trace};
55
use crate::http::Request;
66
use regex::Regex;
77
use serde::{Deserialize, Serialize};
8-
use std::collections::BTreeMap;
98
use std::collections::BTreeSet;
9+
use std::collections::{BTreeMap, HashSet};
1010
use std::sync::Arc;
1111

1212
#[derive(Debug, Clone)]
@@ -117,6 +117,18 @@ impl<T> HeaderMatcher<T> {
117117
removed
118118
}
119119

120+
pub fn batch_remove(&mut self, ids: &HashSet<String>) -> bool {
121+
self.any_header.batch_remove(ids);
122+
123+
self.condition_groups.retain(|_, matcher| {
124+
matcher.batch_remove(ids);
125+
126+
!matcher.is_empty()
127+
});
128+
129+
self.any_header.is_empty() && self.condition_groups.is_empty()
130+
}
131+
120132
pub fn match_request(&self, request: &Request) -> Vec<Arc<Route<T>>> {
121133
let mut rules = self.any_header.match_request(request);
122134
let mut execute_conditions = BTreeMap::new();

src/router/request_matcher/host.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::super::{IpMatcher, Route, RouterConfig, Trace};
33
use crate::http::Request;
44
use crate::marker::StaticOrDynamic;
55
use crate::regex_radix_tree::{Trace as TreeTrace, UniqueRegexTreeMap};
6-
use std::collections::HashMap;
6+
use std::collections::{HashMap, HashSet};
77
use std::sync::Arc;
88

99
#[derive(Debug, Clone)]
@@ -91,6 +91,24 @@ impl<T> HostMatcher<T> {
9191
removed
9292
}
9393

94+
pub fn batch_remove(&mut self, ids: &HashSet<String>) -> bool {
95+
self.any_host.batch_remove(ids);
96+
97+
self.static_hosts.retain(|_, matcher| {
98+
matcher.batch_remove(ids);
99+
100+
!matcher.is_empty()
101+
});
102+
103+
self.regex_tree_rule.retain(&|_, matcher| {
104+
matcher.batch_remove(ids);
105+
106+
!matcher.is_empty()
107+
});
108+
109+
self.any_host.is_empty() && self.static_hosts.is_empty() && self.regex_tree_rule.is_empty()
110+
}
111+
94112
pub fn match_request(&self, request: &Request) -> Vec<Arc<Route<T>>> {
95113
let mut routes = Vec::new();
96114

src/router/request_matcher/ip.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::super::route_ip::RouteIp;
22
use super::super::trace::TraceInfo;
33
use super::super::{MethodMatcher, Route, RouterConfig, Trace};
44
use crate::http::Request;
5-
use std::collections::HashMap;
5+
use std::collections::{HashMap, HashSet};
66
use std::sync::Arc;
77

88
#[derive(Debug, Clone)]
@@ -67,6 +67,18 @@ impl<T> IpMatcher<T> {
6767
removed
6868
}
6969

70+
pub fn batch_remove(&mut self, ids: &HashSet<String>) -> bool {
71+
self.no_matcher.batch_remove(ids);
72+
73+
self.matchers.retain(|_, matcher| {
74+
matcher.batch_remove(ids);
75+
76+
!matcher.is_empty()
77+
});
78+
79+
self.no_matcher.is_empty() && self.matchers.is_empty()
80+
}
81+
7082
pub fn match_request(&self, request: &Request) -> Vec<Arc<Route<T>>> {
7183
let mut routes = self.no_matcher.match_request(request);
7284

0 commit comments

Comments
 (0)