-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
*: refactor table.Allocator to improve readability #17238
Conversation
No release note, Please follow https://github.com/pingcap/community/blob/master/contributors/release-note-checker.md |
/bench |
Codecov Report
@@ Coverage Diff @@
## master #17238 +/- ##
================================================
- Coverage 79.9304% 79.4427% -0.4878%
================================================
Files 526 526
Lines 145584 142884 -2700
================================================
- Hits 116366 113511 -2855
- Misses 20019 20189 +170
+ Partials 9199 9184 -15 |
Benchmark Report
@@ Benchmark Diff @@
================================================================================
--- tidb: 2efab88a59499ea3934c8c1eba7b695cf24b9d29
+++ tidb: f78f7c687551542ac7127f826efb802831e9a1c5
tikv: e5afd630e35b42e970e6184e8b71eb98263a9363
pd: a80b99ef0d70807d106bdc1b7c6e97a118679c7e
================================================================================
oltp_update_index:
* QPS: 4158.98 ± 2.54% (std=70.56) delta: -4.46% (p=0.073)
* Latency p50: 30.79 ± 2.57% (std=0.53) delta: 4.61%
* Latency p99: 56.33 ± 0.91% (std=0.51) delta: 1.78%
oltp_insert:
* QPS: 7105.49 ± 0.36% (std=17.77) delta: 0.08% (p=0.715)
* Latency p50: 18.01 ± 0.33% (std=0.04) delta: -0.08%
* Latency p99: 30.81 ± 0.00% (std=0.00) delta: 0.00%
oltp_read_write:
* QPS: 14600.60 ± 2.23% (std=193.65) delta: -1.77% (p=0.115)
* Latency p50: 174.42 ± 0.46% (std=0.62) delta: 1.07%
* Latency p99: 332.04 ± 3.63% (std=9.45) delta: 6.23%
oltp_point_select:
* QPS: 41050.67 ± 2.62% (std=743.75) delta: -0.03% (p=0.981)
* Latency p50: 3.12 ± 2.65% (std=0.06) delta: 0.08%
* Latency p99: 10.46 ± 0.00% (std=0.00) delta: 0.00%
|
// Use uint64 n directly. | ||
alloc.base = int64(uint64(alloc.base) + uint64(n1)) | ||
return min, alloc.base, nil | ||
nr := (base + increment - offset) / increment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handle overflow here
@@ -129,6 +128,49 @@ type Allocator interface { | |||
GetType() AllocatorType | |||
} | |||
|
|||
// IDIterator represent a list of values allocated by Alloc.alloc(). | |||
type IDIterator struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe the computation in IDIterator should be under uint64.
refer the old code:id := int64(uint64(min) + uint64(j)*uint64(increment))
if err != nil { | ||
return IDIterator{}, err | ||
} | ||
alloc.lastAllocTime = time.Now() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better update alloc.step
here like alloc.lastAllocTime
does if it's not customized.
it's used to compute the next dynamic step.
if !alloc.customStep {
alloc.step = nextStep
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alloc.adjustStep()
updated the alloc.step
:
func (alloc *allocator) adjustStep(startTime time.Time) {
if alloc.customStep {
return
}
consumeDur := startTime.Sub(alloc.lastAllocTime)
alloc.step = NextStep(alloc.step, consumeDur)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, the step will also be modified in L541actualStep
Maybe we should record the actualStep
to alloc.step
in L549 if it's not user-customized.
if !alloc.customStep {
alloc.step = actualStep
}
reslove the conflicts, let's merge this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR description says it needs to update the docs. Really? Why?
The description is outdated. This PR used to support |
// calcNeededBatchSize calculates the total batch size needed. | ||
firstID, batchSize, expectedEnd, isOverflow := alloc.calcNeededBatchSize(alloc.base, int64(n), increment, offset) | ||
if isOverflow { | ||
return IDIterator{}, ErrAutoincReadFailed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is consistent with MySQL.
// Assign autoIDs to rows. | ||
for j := 0; j < cnt; j++ { | ||
offset := j + start | ||
d := rows[offset][colIdx] | ||
|
||
id := int64(uint64(min) + uint64(j)*uint64(increment)) | ||
_, id := idIter.Next() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first return value is ignored, it may be false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this PR does too much compare to the PR description, it's better to split into some small PRs for review.
// It gets a batch of autoIDs at a time. So it does not need to access storage for each call. | ||
// The consecutive feature is used to insert multiple rows in a statement. | ||
// increment & offset is used to validate the start position (the allocator's base is not always the last allocated id). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you remove these comments?
} | ||
|
||
// Next returns the next allocated value. | ||
func (iter *IDIterator) Next() (bool, int64) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to return bool as the second result.
Ok. |
I'm going to close this PR since it hasn't been updated for a long time. feel free to reopen if you want to continue with it. thank you for your contribution. |
What problem does this PR solve?
Issue Number: N/A
What is changed and how it works?
Alloc()
in interfaceAllocator
. The origin signature is:The return values represent an interval that contains the first ID to allocate. It is neither easy to understand nor easy to use.
In this PR, I have changed it into:
The
IDIterator
represents a collection of allocated values. Here is the methods provided byIDIterator
:To retrieve the values in it, one can keep calling
Next()
until thehasNext == false
.Related changes
Check List
Tests
Side effects
Release note