Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit 635a4bb

Browse files
committed
sean feedback
1 parent 526b443 commit 635a4bb

File tree

6 files changed

+28
-20
lines changed

6 files changed

+28
-20
lines changed

api/graphite_req.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
// ReqMap is a map of requests of data,
1010
// it has single requests for which no pre-normalization effort will be performed, and
11-
// requests are that can be pre-normalized together to the same resolution, bundled by their PNGroup
11+
// requests that can be pre-normalized together to the same resolution, bundled by their PNGroup
1212
type ReqMap struct {
1313
single []models.Req
1414
pngroups map[models.PNGroup][]models.Req

api/models/request.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func (r *Req) AdjustTo(interval, from uint32, rets []conf.Retention) {
126126
// we will have to apply normalization
127127
// we use the initially found archive as starting point. there could be some cases - if you have exotic settings -
128128
// where it may be more efficient to pick a lower res archive as starting point (it would still require an interval
129-
// divisible by the output interval) but let's not worry about that edge case.
129+
// that is a factor of the output interval) but let's not worry about that edge case.
130130
r.PlanNormalization(interval)
131131
}
132132

devdocs/expr.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
Such functions require special options.
1313
see https://github.com/grafana/metrictank/issues/926#issuecomment-559596384
1414

15-
## implement our copy-o-write approach when dealing with modifying series
15+
## implement our copy-on-write approach when dealing with modifying series
1616

1717
See section 'Considerations around Series changes and reuse and why we chose copy-on-write' below.
1818

@@ -27,7 +27,7 @@ example: an averageSeries() of 3 series:
2727
* will create an output series value.
2828
* it will use a new datapoints slice, retrieved from pool, because the points will be different. also it will allocate a new meta section and tags map because they are different from the input series also.
2929
* won't put the 3 inputs back in the pool or cache, because whoever allocated the input series was responsible for doing that. we should not add the same arrays to the pool multiple times.
30-
* It will however store the newly created series into the cache such that that during plan cleanup time, the series' datapoints slice will be moved back to the pool.
30+
* It will however store the newly created series into the cache such that during plan cleanup time, the series' datapoints slice will be moved back to the pool.
3131

3232
# Considerations around Series changes and reuse and why we chose copy-on-write.
3333

@@ -72,7 +72,7 @@ for now we assume that multi-steps in a row is not that common, and COW seems mo
7272

7373

7474
This leaves the problem of effectively managing allocations and using a sync.Pool.
75-
Note that the expr library can be called by different clients. At this point only Metrictank uses it, but we intend this lirbrary to be easily embeddable in other programs.
75+
Note that the expr library can be called by different clients. At this point only Metrictank uses it, but we intend this library to be easily embeddable in other programs.
7676
It's up to the client to instantiate the pool, and set up the default allocation to return point slices of desired point capacity.
7777
The client can then of course use this pool to store series, which it then feeds to expr.
7878
expr library does the rest. It manages the series/pointslices and gets new ones as a basis for the COW.

docs/render-path.md

+13-7
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ First, let's look at some definitions.
113113
Certain functions will return output series in an interval different from the input interval.
114114
For example summarize() and smartSummarize(). We refer to these as IA-functions below.
115115
In principle we can predict what the output interval will be during the plan phase, because we can parse the function arguments.
116-
However, for simplicty, we don't implement this and treat all IA functions as functions that may change the interval of series in unpredicatable ways.
116+
However, for simplicity, we don't implement this and treat all IA functions as functions that may change the interval of series in unpredicatable ways.
117117

118118
### Transparent aggregation
119119

@@ -133,9 +133,16 @@ Generally, if series have different intervals, they can keep those and we return
133133
However, when data will be used together (e.g. aggregating multiple series together, or certain functions like divideSeries, asPercent, etc) they will need to have the same interval.
134134
An aggregation can be opaque or transparent as defined above.
135135

136-
Pre-normalizing is when we can safely - during planning - set up normalization to happen right after fetching (or better: set up the fetch parameters such that normalizing is not needed) and wen we know the normalization won't affect anything else.
137-
This is the case when series go from fetching to transparent aggregation, possibly with some processing functions - except opaque aggregation(s) or IA-function(s) - in between, and
138-
with asPercent in a certain mode (where it has to normalize all inputs), but not with divideSeries where it applies the same divisor to multiple dividend inputs, for example.
136+
Pre-normalizing is when we can safely - during planning - set up normalization to happen right after fetching (or better: set up the fetch parameters such that normalizing is not needed) and when we know the normalization won't affect anything else.
137+
138+
This is the case when series go from fetching to a processing function like:
139+
* a transparent aggregation
140+
* asPercent in a certain mode (where it has to normalize all inputs)
141+
142+
possibly with some processing functions in between the fetching and the above function, except opaque aggregation(s) or IA-function(s).
143+
144+
Some functions also have to normalize (some of) their inputs, but yet cannot have their inputs pre-normalized. For example,
145+
divideSeries because it applies the same divisor to multiple distinct dividend inputs (of possibly different intervals).
139146

140147
For example if we have these schemas:
141148
```
@@ -152,13 +159,12 @@ Likewise, if the query is `groupByNode(group(A,B), 2, callback='sum')` we cannot
152159

153160
Benefits of this optimization:
154161
1) less work spent consolidating at runtime, less data to fetch
155-
2) it assures data will be fetched in a pre-canonical way. If we don't set up normalization for fetching, data may not be pre-canonical, such that
162+
2) it assures data will be fetched in a pre-canonical way. If we don't set up normalization for fetching, data may not be pre-canonical, which means we may have to add null points to normalize it to canonical data, lowering the accuracy of the first or last point.
156163
3) pre-normalized data reduces a request's chance of breaching max-points-per-req-soft and thus makes it less likely that other data that should be high-resolution gets fetched in a coarser way.
157164
when it eventually needs to be normalized at runtime, points at the beginning or end of the series may be less accurate.
158165

159166
Downsides of this optimization:
160-
1) if you already have the raw data cached, and the rollup data is not cached yet, it may result in a slower query. But this is an edge case
161-
2) uses slightly more of the chunk cache.
167+
1) if you already have the raw data cached, and the rollup data is not cached yet, it may result in a slower query, and you'd use slightly more chunk cache after the fetch. But this is an edge case
162168

163169
## MDP-optimizable
164170

expr/plan.go

+2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ type Optimizations struct {
1616
}
1717

1818
func (o Optimizations) ApplyUserPrefs(s string) Optimizations {
19+
// no user override. stick to what we have
1920
if s == "" {
2021
return o
2122
}
23+
// user passed an override. it's either 'none' (no optimizations) or a list of the ones that should be enabled
2224
o.PreNormalization = false
2325
o.MDP = false
2426
if s == "none" {

util/combinations.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,31 @@ func AllCombinationsUint32(parts [][]uint32) (out [][]uint32) {
1111
out = make([][]uint32, 0, num)
1212

1313
// will contain idx of which one to pick for each part
14-
idexes := make([]int, len(parts))
14+
indexes := make([]int, len(parts))
1515

1616
mainloop:
1717
for {
18-
// update idexes:
18+
// update indexes:
1919
// travel backwards. whenever we encounter an index that "overflowed"
2020
// reset it back to 0 and bump the previous one, until they are all maxed out
21-
for i := len(idexes) - 1; i >= 0; i-- {
22-
if idexes[i] >= len(parts[i]) {
21+
for i := len(indexes) - 1; i >= 0; i-- {
22+
if indexes[i] >= len(parts[i]) {
2323
if i == 0 {
2424
break mainloop
2525
}
26-
idexes[i] = 0
27-
idexes[i-1]++
26+
indexes[i] = 0
27+
indexes[i-1]++
2828
}
2929
}
3030

3131
combo := make([]uint32, len(parts))
3232
for i, part := range parts {
33-
combo[i] = part[idexes[i]]
33+
combo[i] = part[indexes[i]]
3434
}
3535
out = append(out, combo)
3636

3737
// always bump idx of the last one
38-
idexes[len(parts)-1]++
38+
indexes[len(parts)-1]++
3939
}
4040
return out
4141
}

0 commit comments

Comments
 (0)