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

Memoize partial set results #822

Closed
tsandall opened this issue Jul 4, 2018 · 0 comments · Fixed by #3492
Closed

Memoize partial set results #822

tsandall opened this issue Jul 4, 2018 · 0 comments · Fixed by #3492
Assignees

Comments

@tsandall
Copy link
Member

tsandall commented Jul 4, 2018

OPA memoizes partial object and complete document results during evaluation but not partial set results. There's no reason not to do the same for partial sets. The challenge with sets is that they may contain composite values however the current cache implementation only supports scalar path segments. The cache can be modified to use an util.HashMap instead of map[ast.Value]cacheElem so that composites can be supported. Alternatively, we can treat this as a hillclimbing exercise and only support caching for scalar path segments for now.

tsandall added a commit to tsandall/opa that referenced this issue Jun 24, 2019
Previously the virtual cache was implemented using a
map[ast.Value]... which works for scalar key terms but not composites
(because they're not comparable.) This change updates the virtual
cache to use a util.HashMap that supports all term kinds. This
prevents the virtual cache lookup/insert from panicing when a key like
data.x.y[[1]] is received.

In addition to fixing the virtual cache, this change updates the
Term.Equal() function to include an early-exit for types that do not
allocate in their Equal() functions.

The early-exit was added because swapping out the map[ast.Value]...
for util.HashMap introduced allocations into the virtual cache
lookup/insert operations which doubled the benchmark latency. See
below for benchmark results before/after this commit.

```
BEFORE
======
goos: linux
goarch: amd64
pkg: github.com/open-policy-agent/opa/topdown
BenchmarkVirtualCache-8   	 5000000	       284 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/open-policy-agent/opa/topdown	1.731s
Success: Benchmarks passed.

AFTER
=====
goos: linux
goarch: amd64
pkg: github.com/open-policy-agent/opa/topdown
BenchmarkVirtualCache-8   	 5000000	       322 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/open-policy-agent/opa/topdown	1.969s
Success: Benchmarks passed.
```

This change will also let us memoize virtual sets using the same cache
(see open-policy-agent#822).

Fixes open-policy-agent#1197

Signed-off-by: Torin Sandall <[email protected]>
patrick-east pushed a commit that referenced this issue Jun 24, 2019
Previously the virtual cache was implemented using a
map[ast.Value]... which works for scalar key terms but not composites
(because they're not comparable.) This change updates the virtual
cache to use a util.HashMap that supports all term kinds. This
prevents the virtual cache lookup/insert from panicing when a key like
data.x.y[[1]] is received.

In addition to fixing the virtual cache, this change updates the
Term.Equal() function to include an early-exit for types that do not
allocate in their Equal() functions.

The early-exit was added because swapping out the map[ast.Value]...
for util.HashMap introduced allocations into the virtual cache
lookup/insert operations which doubled the benchmark latency. See
below for benchmark results before/after this commit.

```
BEFORE
======
goos: linux
goarch: amd64
pkg: github.com/open-policy-agent/opa/topdown
BenchmarkVirtualCache-8   	 5000000	       284 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/open-policy-agent/opa/topdown	1.731s
Success: Benchmarks passed.

AFTER
=====
goos: linux
goarch: amd64
pkg: github.com/open-policy-agent/opa/topdown
BenchmarkVirtualCache-8   	 5000000	       322 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/open-policy-agent/opa/topdown	1.969s
Success: Benchmarks passed.
```

This change will also let us memoize virtual sets using the same cache
(see #822).

Fixes #1197

Signed-off-by: Torin Sandall <[email protected]>
@srenatus srenatus self-assigned this May 27, 2021
tsandall pushed a commit to tsandall/opa that referenced this issue Jun 23, 2021
Turns out the groundwork had already been done in open-policy-agent#1520.

This changes wires the existing cache into the eval steps of partial sets.

Fixes open-policy-agent#822.

Signed-off-by: Stephan Renatus <[email protected]>
srenatus added a commit to srenatus/opa that referenced this issue Jul 14, 2021
We can either cache individual elements (`data.foo.p["bar"]`), or the
full extent of a partial set/object. A cached full extent of the partial
would be used when evaluating individual elements of the partial.

If the first encounter with a partial set/object has to materialize the
full extent with a variable key, like `data.foo.p[x]`, then we cache the
fully-evaluated result for `data.foo.p`.

Fixes open-policy-agent#822.

Co-authored-by: Torin Sandall <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
srenatus added a commit that referenced this issue Jul 14, 2021
We can either cache individual elements (`data.foo.p["bar"]`), or the
full extent of a partial set/object. A cached full extent of the partial
would be used when evaluating individual elements of the partial.

If the first encounter with a partial set/object has to materialize the
full extent with a variable key, like `data.foo.p[x]`, then we cache the
fully-evaluated result for `data.foo.p`.

Fixes #822.

Co-authored-by: Torin Sandall <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
dolevf pushed a commit to dolevf/opa that referenced this issue Nov 4, 2021
We can either cache individual elements (`data.foo.p["bar"]`), or the
full extent of a partial set/object. A cached full extent of the partial
would be used when evaluating individual elements of the partial.

If the first encounter with a partial set/object has to materialize the
full extent with a variable key, like `data.foo.p[x]`, then we cache the
fully-evaluated result for `data.foo.p`.

Fixes open-policy-agent#822.

Co-authored-by: Torin Sandall <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Dolev Farhi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants