TrimToBlockOverlap returns the overlap between the given time range and block. It is used to split a block to only the portion overlapping, or when the entire block is within range then opportunistically remove time slots that are known to be unused. When possible and not exceeding the request rang
(req *tempopb.QueryRangeRequest, blockStart, blockEnd time.Time)
| 82 | // When possible and not exceeding the request range, borders are aligned to the step. |
| 83 | // When a block is split then the borders will maintain the nanosecond precision of the request. |
| 84 | func TrimToBlockOverlap(req *tempopb.QueryRangeRequest, blockStart, blockEnd time.Time) (uint64, uint64, uint64) { |
| 85 | start := req.Start |
| 86 | end := req.End |
| 87 | step := req.Step |
| 88 | |
| 89 | // We subtract 1 nanosecond from the block's start time |
| 90 | // to make sure we include the left border of the block. |
| 91 | start2 := uint64(blockStart.UnixNano()) - 1 |
| 92 | // Block's endTime is rounded down to the nearest second and considered inclusive. |
| 93 | // In order to include the right border with nanoseconds, we add 1 second |
| 94 | blockEnd = blockEnd.Add(time.Second) |
| 95 | end2 := uint64(blockEnd.UnixNano()) |
| 96 | |
| 97 | // Align the block data range to the step. This is because |
| 98 | // low-precision timestamps within the block may be rounded up to |
| 99 | // this step. If the boundaries exceed the overall range |
| 100 | // they will get trimmed back down. |
| 101 | start2 = alignStart(start2, end2, step, IsInstant(req)) |
| 102 | end2 = alignEnd(start2, end2, step, IsInstant(req)) |
| 103 | |
| 104 | // Now trim to the overlap preserving nanosecond precision for |
| 105 | // when we split a block. |
| 106 | start = max(start, start2) |
| 107 | end = min(end, end2) |
| 108 | |
| 109 | // if no instant flag but step is instant, restore it |
| 110 | // this can happen during new version rollout |
| 111 | if !req.HasInstant() && IsInstant(req) { |
| 112 | step = end - start |
| 113 | } |
| 114 | |
| 115 | // if had no instant flag set, had no instant step and become instant, |
| 116 | // add one nanosecond. This usually happens to small blocks. |
| 117 | wasAssumedRange := !req.HasInstant() && !IsInstant(req) |
| 118 | willBecomeInstant := (end-start == step) |
| 119 | if wasAssumedRange && willBecomeInstant { |
| 120 | end++ |
| 121 | } |
| 122 | |
| 123 | return start, end, step |
| 124 | } |
| 125 | |
| 126 | // TrimToBefore shortens the query window to only include before the given time. |
| 127 | // Request must be in unix nanoseconds already. |