Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use flat array for field indexing instead of hashmap #247

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
65 changes: 43 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ fnv = "1"

[dev-dependencies]
criterion = "0.*"
serde_json = "1"
serde = "1"
uuid = {version = "1.8", features = ["v4"]}

[[bench]]
name = "misc_match"
harness = false

[lib]
crate-type = ["lib", "cdylib", "staticlib"]
Expand Down
33 changes: 28 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ATC Router library for Kong.
* [resty.router.context](#restyroutercontext)
* [new](#new)
* [add\_value](#add_value)
* [add\_value\_by\_index](#add_value_by_index)
* [get\_result](#get_result)
* [reset](#reset)
* [Copyright and license](#copyright-and-license)
Expand Down Expand Up @@ -186,9 +187,9 @@ none of the matcher matched.

**context:** *any*

Returns the currently used field names by all matchers inside the router as
an Lua array. It can help reduce unnecessarily producing values that are not
actually used by the user supplied matchers.
Returns the currently used {field name: field index} map by all matchers inside
the router as an Lua table. It can help reduce unnecessarily producing values
that are not actually used by the user supplied matchers.

[Back to TOC](#table-of-contents)

Expand All @@ -209,12 +210,12 @@ Returns the fields used in the provided expression when the expression is valid.

### new

**syntax:** *c = context.new(schema)*
**syntax:** *c = context.new(router)*

**context:** *any*

Create a new context instance that can later be used for storing contextual information.
for router matches. `schema` must refer to an existing schema instance.
for router matches. `router` must refer to an existing router instance.

[Back to TOC](#table-of-contents)

Expand All @@ -232,6 +233,28 @@ If an error occurred, `nil` and a string describing the error will be returned.

[Back to TOC](#table-of-contents)

### add\_value\_by\_index

**syntax:** *res, err = c:add_value_by_index(field, value, index)*

**context:** *any*

Provides `value` for `field` inside the context.

Use `index` got from `r:get_fields()` to provide `value` for `field`.

This method is faster than `add_value`, but notice that users should gurantee

the index got from `r:get_fields()` is not stale. e.g. `router` fields changed

by `remove_matcher` may cause field indexes got previously invalid.

Returns `true` if field exists and value has successfully been provided.

If an error occurred, `nil` and a string describing the error will be returned.

[Back to TOC](#table-of-contents)

### get\_result

**syntax:** *uuid, matched_value, captures = c:get_result(matched_field)*
Expand Down
3 changes: 0 additions & 3 deletions benches/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ fn criterion_benchmark(c: &mut Criterion) {
let mut schema = Schema::default();
schema.add_field("a", Type::Int);

let mut context = Context::new(&schema);
context.add_value("a", Value::Int(N as i64));

c.bench_function("Build Router", |b| {
b.iter_with_large_drop(|| {
let mut router = Router::new(&schema);
Expand Down
55 changes: 55 additions & 0 deletions benches/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"rules": [
"net.protocol == \"http\"",
"tls.sni == \"server1\"",
"http.method == \"GET\"",
"http.host == \"example.com\"",
"http.path == \"/foo\"",
"http.path.segments.1 == \"bar\"",
"http.path.segments.0_1 == \"foo/bar\"",
"http.path.segments.len == 2",
"http.headers.foo_bar == \"whatever\"",
"net.dst.port == 8443",
"net.src.ip == 192.168.1.1",
"net.src.ip in 192.168.1.0/24"
],
"match_keys": [
"net.protocol",
"tls.sni",
"http.method",
"http.host",
"http.path",
"http.path.segments.1",
"http.path.segments.0_1",
"http.path.segments.len",
"http.headers.foo_bar",
"net.dst.port",
"net.src.ip"
],
"match_values": [
"http",
"server1",
"GET",
"example.com",
"/foo",
"bar\"",
"foo/bar\"",
2,
"whatever",
8443,
["192.168.1.1"]
],
"not_match_values": [
"https",
"server2",
"POST",
"example_foo.com",
"/fooo",
"/barr\"",
"/fooo/bar\"",
3,
"whatever_wrong",
18443,
["192.168.2.1"]
]
}
2 changes: 1 addition & 1 deletion benches/match_mix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn criterion_benchmark(c: &mut Criterion) {
router.add_matcher(N - i, uuid, &expr).unwrap();
}

let mut ctx_match = Context::new(&schema);
let mut ctx_match = Context::new(&router);
ctx_match.add_value(
"http.path",
atc_router::ast::Value::String("hello49999".to_string()),
Expand Down
Loading
Loading