mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Formatted source code for go 1.19.6.
Signed-off-by: James Blair <mail@jamesblair.net>
This commit is contained in:
parent
1bd835383b
commit
183af509f6
@ -68,6 +68,5 @@ Use a custom context to set timeouts on your operations:
|
|||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package client
|
package client
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
//
|
//
|
||||||
// 1. context error: canceled or deadline exceeded.
|
// 1. context error: canceled or deadline exceeded.
|
||||||
// 2. gRPC error: e.g. when clock drifts in server-side before client's context deadline exceeded.
|
// 2. gRPC error: e.g. when clock drifts in server-side before client's context deadline exceeded.
|
||||||
|
//
|
||||||
// See https://github.com/etcd-io/etcd/blob/main/api/v3rpc/rpctypes/error.go
|
// See https://github.com/etcd-io/etcd/blob/main/api/v3rpc/rpctypes/error.go
|
||||||
//
|
//
|
||||||
// Here is the example code to handle client errors:
|
// Here is the example code to handle client errors:
|
||||||
@ -102,5 +103,4 @@
|
|||||||
// The grpc load balancer is registered statically and is shared across etcd clients.
|
// The grpc load balancer is registered statically and is shared across etcd clients.
|
||||||
// To enable detailed load balancer logging, set the ETCD_CLIENT_DEBUG environment
|
// To enable detailed load balancer logging, set the ETCD_CLIENT_DEBUG environment
|
||||||
// variable. E.g. "ETCD_CLIENT_DEBUG=1".
|
// variable. E.g. "ETCD_CLIENT_DEBUG=1".
|
||||||
//
|
|
||||||
package clientv3
|
package clientv3
|
||||||
|
@ -45,8 +45,8 @@ func extractHostFromPath(pathStr string) string {
|
|||||||
return extractHostFromHostPort(path.Base(pathStr))
|
return extractHostFromHostPort(path.Base(pathStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
//mustSplit2 returns the values from strings.SplitN(s, sep, 2).
|
// mustSplit2 returns the values from strings.SplitN(s, sep, 2).
|
||||||
//If sep is not found, it returns ("", "", false) instead.
|
// If sep is not found, it returns ("", "", false) instead.
|
||||||
func mustSplit2(s, sep string) (string, string) {
|
func mustSplit2(s, sep string) (string, string) {
|
||||||
spl := strings.SplitN(s, sep, 2)
|
spl := strings.SplitN(s, sep, 2)
|
||||||
if len(spl) < 2 {
|
if len(spl) < 2 {
|
||||||
@ -86,6 +86,7 @@ func schemeToCredsRequirement(schema string) CredsRequirement {
|
|||||||
// (as opposed to unix:local-file canonical name used by grpc for current dir files).
|
// (as opposed to unix:local-file canonical name used by grpc for current dir files).
|
||||||
// - Within the unix(s) schemas, the last segment (filename) without 'port' (content after colon)
|
// - Within the unix(s) schemas, the last segment (filename) without 'port' (content after colon)
|
||||||
// is considered serverName - to allow local testing of cert-protected communication.
|
// is considered serverName - to allow local testing of cert-protected communication.
|
||||||
|
//
|
||||||
// See more:
|
// See more:
|
||||||
// - https://github.com/grpc/grpc-go/blob/26c143bd5f59344a4b8a1e491e0f5e18aa97abc7/internal/grpcutil/target.go#L47
|
// - https://github.com/grpc/grpc-go/blob/26c143bd5f59344a4b8a1e491e0f5e18aa97abc7/internal/grpcutil/target.go#L47
|
||||||
// - https://golang.org/pkg/net/#Dial
|
// - https://golang.org/pkg/net/#Dial
|
||||||
|
@ -42,5 +42,4 @@
|
|||||||
// }
|
// }
|
||||||
// lkv2.Put(context.TODO(), "abc", "456")
|
// lkv2.Put(context.TODO(), "abc", "456")
|
||||||
// resp, err = lkv.Get("abc")
|
// resp, err = lkv.Get("abc")
|
||||||
//
|
|
||||||
package leasing
|
package leasing
|
||||||
|
@ -39,5 +39,4 @@
|
|||||||
// resp, _ = cli.Get(context.TODO(), "abc")
|
// resp, _ = cli.Get(context.TODO(), "abc")
|
||||||
// fmt.Printf("%s\n", resp.Kvs[0].Value)
|
// fmt.Printf("%s\n", resp.Kvs[0].Value)
|
||||||
// // Output: 456
|
// // Output: 456
|
||||||
//
|
|
||||||
package namespace
|
package namespace
|
||||||
|
@ -55,5 +55,4 @@
|
|||||||
// em := endpoints.NewManager(c, service)
|
// em := endpoints.NewManager(c, service)
|
||||||
// return em.AddEndpoint(c.Ctx(), service+"/"+addr, endpoints.Endpoint{Addr:addr}, clientv3.WithLease(lid));
|
// return em.AddEndpoint(c.Ctx(), service+"/"+addr, endpoints.Endpoint{Addr:addr}, clientv3.WithLease(lid));
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
package naming
|
package naming
|
||||||
|
@ -38,5 +38,4 @@
|
|||||||
// cli.KV = ordering.NewKV(cli.KV, vf)
|
// cli.KV = ordering.NewKV(cli.KV, vf)
|
||||||
//
|
//
|
||||||
// Now calls using 'cli' will reject order violations with an error.
|
// Now calls using 'cli' will reject order violations with an error.
|
||||||
//
|
|
||||||
package ordering
|
package ordering
|
||||||
|
@ -33,7 +33,6 @@ import (
|
|||||||
// ).Else(
|
// ).Else(
|
||||||
// OpPut(k4,v4), OpPut(k5,v5)
|
// OpPut(k4,v4), OpPut(k5,v5)
|
||||||
// ).Commit()
|
// ).Commit()
|
||||||
//
|
|
||||||
type Txn interface {
|
type Txn interface {
|
||||||
// If takes a list of comparison. If all comparisons passed in succeed,
|
// If takes a list of comparison. If all comparisons passed in succeed,
|
||||||
// the operations passed into Then() will be executed. Or the operations
|
// the operations passed into Then() will be executed. Or the operations
|
||||||
|
@ -27,7 +27,7 @@ const (
|
|||||||
apiEnv = "ETCDCTL_API"
|
apiEnv = "ETCDCTL_API"
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/*
|
||||||
mainWithError is fully analogous to main, but instead of signaling errors
|
mainWithError is fully analogous to main, but instead of signaling errors
|
||||||
by os.Exit, it exposes the error explicitly, such that test-logic can intercept
|
by os.Exit, it exposes the error explicitly, such that test-logic can intercept
|
||||||
control to e.g. dump coverage data (even for test-for-failure scenarios).
|
control to e.g. dump coverage data (even for test-for-failure scenarios).
|
||||||
|
@ -241,34 +241,34 @@ type intervalTree struct {
|
|||||||
//
|
//
|
||||||
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.4, p324
|
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.4, p324
|
||||||
//
|
//
|
||||||
// 0. RB-DELETE(T, z)
|
// RB-DELETE(T, z)
|
||||||
// 1.
|
//
|
||||||
// 2. y = z
|
// y = z
|
||||||
// 3. y-original-color = y.color
|
// y-original-color = y.color
|
||||||
// 4.
|
//
|
||||||
// 5. if z.left == T.nil
|
// if z.left == T.nil
|
||||||
// 6. x = z.right
|
// x = z.right
|
||||||
// 7. RB-TRANSPLANT(T, z, z.right)
|
// RB-TRANSPLANT(T, z, z.right)
|
||||||
// 8. else if z.right == T.nil
|
// else if z.right == T.nil
|
||||||
// 9. x = z.left
|
// x = z.left
|
||||||
// 10. RB-TRANSPLANT(T, z, z.left)
|
// RB-TRANSPLANT(T, z, z.left)
|
||||||
// 11. else
|
// else
|
||||||
// 12. y = TREE-MINIMUM(z.right)
|
// y = TREE-MINIMUM(z.right)
|
||||||
// 13. y-original-color = y.color
|
// y-original-color = y.color
|
||||||
// 14. x = y.right
|
// x = y.right
|
||||||
// 15. if y.p == z
|
// if y.p == z
|
||||||
// 16. x.p = y
|
// x.p = y
|
||||||
// 17. else
|
// else
|
||||||
// 18. RB-TRANSPLANT(T, y, y.right)
|
// RB-TRANSPLANT(T, y, y.right)
|
||||||
// 19. y.right = z.right
|
// y.right = z.right
|
||||||
// 20. y.right.p = y
|
// y.right.p = y
|
||||||
// 21. RB-TRANSPLANT(T, z, y)
|
// RB-TRANSPLANT(T, z, y)
|
||||||
// 22. y.left = z.left
|
// y.left = z.left
|
||||||
// 23. y.left.p = y
|
// y.left.p = y
|
||||||
// 24. y.color = z.color
|
// y.color = z.color
|
||||||
// 25.
|
//
|
||||||
// 26. if y-original-color == BLACK
|
// if y-original-color == BLACK
|
||||||
// 27. RB-DELETE-FIXUP(T, x)
|
// RB-DELETE-FIXUP(T, x)
|
||||||
|
|
||||||
// Delete removes the node with the given interval from the tree, returning
|
// Delete removes the node with the given interval from the tree, returning
|
||||||
// true if a node is in fact removed.
|
// true if a node is in fact removed.
|
||||||
@ -317,48 +317,47 @@ func (ivt *intervalTree) Delete(ivl Interval) bool {
|
|||||||
|
|
||||||
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.4, p326
|
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.4, p326
|
||||||
//
|
//
|
||||||
// 0. RB-DELETE-FIXUP(T, z)
|
// RB-DELETE-FIXUP(T, z)
|
||||||
// 1.
|
|
||||||
// 2. while x ≠ T.root and x.color == BLACK
|
|
||||||
// 3. if x == x.p.left
|
|
||||||
// 4. w = x.p.right
|
|
||||||
// 5. if w.color == RED
|
|
||||||
// 6. w.color = BLACK
|
|
||||||
// 7. x.p.color = RED
|
|
||||||
// 8. LEFT-ROTATE(T, x, p)
|
|
||||||
// 9. if w.left.color == BLACK and w.right.color == BLACK
|
|
||||||
// 10. w.color = RED
|
|
||||||
// 11. x = x.p
|
|
||||||
// 12. else if w.right.color == BLACK
|
|
||||||
// 13. w.left.color = BLACK
|
|
||||||
// 14. w.color = RED
|
|
||||||
// 15. RIGHT-ROTATE(T, w)
|
|
||||||
// 16. w = w.p.right
|
|
||||||
// 17. w.color = x.p.color
|
|
||||||
// 18. x.p.color = BLACK
|
|
||||||
// 19. LEFT-ROTATE(T, w.p)
|
|
||||||
// 20. x = T.root
|
|
||||||
// 21. else
|
|
||||||
// 22. w = x.p.left
|
|
||||||
// 23. if w.color == RED
|
|
||||||
// 24. w.color = BLACK
|
|
||||||
// 25. x.p.color = RED
|
|
||||||
// 26. RIGHT-ROTATE(T, x, p)
|
|
||||||
// 27. if w.right.color == BLACK and w.left.color == BLACK
|
|
||||||
// 28. w.color = RED
|
|
||||||
// 29. x = x.p
|
|
||||||
// 30. else if w.left.color == BLACK
|
|
||||||
// 31. w.right.color = BLACK
|
|
||||||
// 32. w.color = RED
|
|
||||||
// 33. LEFT-ROTATE(T, w)
|
|
||||||
// 34. w = w.p.left
|
|
||||||
// 35. w.color = x.p.color
|
|
||||||
// 36. x.p.color = BLACK
|
|
||||||
// 37. RIGHT-ROTATE(T, w.p)
|
|
||||||
// 38. x = T.root
|
|
||||||
// 39.
|
|
||||||
// 40. x.color = BLACK
|
|
||||||
//
|
//
|
||||||
|
// while x ≠ T.root and x.color == BLACK
|
||||||
|
// if x == x.p.left
|
||||||
|
// w = x.p.right
|
||||||
|
// if w.color == RED
|
||||||
|
// w.color = BLACK
|
||||||
|
// x.p.color = RED
|
||||||
|
// LEFT-ROTATE(T, x, p)
|
||||||
|
// if w.left.color == BLACK and w.right.color == BLACK
|
||||||
|
// w.color = RED
|
||||||
|
// x = x.p
|
||||||
|
// else if w.right.color == BLACK
|
||||||
|
// w.left.color = BLACK
|
||||||
|
// w.color = RED
|
||||||
|
// RIGHT-ROTATE(T, w)
|
||||||
|
// w = w.p.right
|
||||||
|
// w.color = x.p.color
|
||||||
|
// x.p.color = BLACK
|
||||||
|
// LEFT-ROTATE(T, w.p)
|
||||||
|
// x = T.root
|
||||||
|
// else
|
||||||
|
// w = x.p.left
|
||||||
|
// if w.color == RED
|
||||||
|
// w.color = BLACK
|
||||||
|
// x.p.color = RED
|
||||||
|
// RIGHT-ROTATE(T, x, p)
|
||||||
|
// if w.right.color == BLACK and w.left.color == BLACK
|
||||||
|
// w.color = RED
|
||||||
|
// x = x.p
|
||||||
|
// else if w.left.color == BLACK
|
||||||
|
// w.right.color = BLACK
|
||||||
|
// w.color = RED
|
||||||
|
// LEFT-ROTATE(T, w)
|
||||||
|
// w = w.p.left
|
||||||
|
// w.color = x.p.color
|
||||||
|
// x.p.color = BLACK
|
||||||
|
// RIGHT-ROTATE(T, w.p)
|
||||||
|
// x = T.root
|
||||||
|
//
|
||||||
|
// x.color = BLACK
|
||||||
func (ivt *intervalTree) deleteFixup(x *intervalNode) {
|
func (ivt *intervalTree) deleteFixup(x *intervalNode) {
|
||||||
for x != ivt.root && x.color(ivt.sentinel) == black {
|
for x != ivt.root && x.color(ivt.sentinel) == black {
|
||||||
if x == x.parent.left { // line 3-20
|
if x == x.parent.left { // line 3-20
|
||||||
@ -439,32 +438,32 @@ func (ivt *intervalTree) createIntervalNode(ivl Interval, val interface{}) *inte
|
|||||||
//
|
//
|
||||||
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.3, p315
|
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.3, p315
|
||||||
//
|
//
|
||||||
// 0. RB-INSERT(T, z)
|
// RB-INSERT(T, z)
|
||||||
// 1.
|
//
|
||||||
// 2. y = T.nil
|
// y = T.nil
|
||||||
// 3. x = T.root
|
// x = T.root
|
||||||
// 4.
|
//
|
||||||
// 5. while x ≠ T.nil
|
// while x ≠ T.nil
|
||||||
// 6. y = x
|
// y = x
|
||||||
// 7. if z.key < x.key
|
// if z.key < x.key
|
||||||
// 8. x = x.left
|
// x = x.left
|
||||||
// 9. else
|
// else
|
||||||
// 10. x = x.right
|
// x = x.right
|
||||||
// 11.
|
//
|
||||||
// 12. z.p = y
|
// z.p = y
|
||||||
// 13.
|
//
|
||||||
// 14. if y == T.nil
|
// if y == T.nil
|
||||||
// 15. T.root = z
|
// T.root = z
|
||||||
// 16. else if z.key < y.key
|
// else if z.key < y.key
|
||||||
// 17. y.left = z
|
// y.left = z
|
||||||
// 18. else
|
// else
|
||||||
// 19. y.right = z
|
// y.right = z
|
||||||
// 20.
|
//
|
||||||
// 21. z.left = T.nil
|
// z.left = T.nil
|
||||||
// 22. z.right = T.nil
|
// z.right = T.nil
|
||||||
// 23. z.color = RED
|
// z.color = RED
|
||||||
// 24.
|
//
|
||||||
// 25. RB-INSERT-FIXUP(T, z)
|
// RB-INSERT-FIXUP(T, z)
|
||||||
|
|
||||||
// Insert adds a node with the given interval into the tree.
|
// Insert adds a node with the given interval into the tree.
|
||||||
func (ivt *intervalTree) Insert(ivl Interval, val interface{}) {
|
func (ivt *intervalTree) Insert(ivl Interval, val interface{}) {
|
||||||
@ -499,38 +498,37 @@ func (ivt *intervalTree) Insert(ivl Interval, val interface{}) {
|
|||||||
|
|
||||||
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.3, p316
|
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.3, p316
|
||||||
//
|
//
|
||||||
// 0. RB-INSERT-FIXUP(T, z)
|
// RB-INSERT-FIXUP(T, z)
|
||||||
// 1.
|
|
||||||
// 2. while z.p.color == RED
|
|
||||||
// 3. if z.p == z.p.p.left
|
|
||||||
// 4. y = z.p.p.right
|
|
||||||
// 5. if y.color == RED
|
|
||||||
// 6. z.p.color = BLACK
|
|
||||||
// 7. y.color = BLACK
|
|
||||||
// 8. z.p.p.color = RED
|
|
||||||
// 9. z = z.p.p
|
|
||||||
// 10. else if z == z.p.right
|
|
||||||
// 11. z = z.p
|
|
||||||
// 12. LEFT-ROTATE(T, z)
|
|
||||||
// 13. z.p.color = BLACK
|
|
||||||
// 14. z.p.p.color = RED
|
|
||||||
// 15. RIGHT-ROTATE(T, z.p.p)
|
|
||||||
// 16. else
|
|
||||||
// 17. y = z.p.p.left
|
|
||||||
// 18. if y.color == RED
|
|
||||||
// 19. z.p.color = BLACK
|
|
||||||
// 20. y.color = BLACK
|
|
||||||
// 21. z.p.p.color = RED
|
|
||||||
// 22. z = z.p.p
|
|
||||||
// 23. else if z == z.p.right
|
|
||||||
// 24. z = z.p
|
|
||||||
// 25. RIGHT-ROTATE(T, z)
|
|
||||||
// 26. z.p.color = BLACK
|
|
||||||
// 27. z.p.p.color = RED
|
|
||||||
// 28. LEFT-ROTATE(T, z.p.p)
|
|
||||||
// 29.
|
|
||||||
// 30. T.root.color = BLACK
|
|
||||||
//
|
//
|
||||||
|
// while z.p.color == RED
|
||||||
|
// if z.p == z.p.p.left
|
||||||
|
// y = z.p.p.right
|
||||||
|
// if y.color == RED
|
||||||
|
// z.p.color = BLACK
|
||||||
|
// y.color = BLACK
|
||||||
|
// z.p.p.color = RED
|
||||||
|
// z = z.p.p
|
||||||
|
// else if z == z.p.right
|
||||||
|
// z = z.p
|
||||||
|
// LEFT-ROTATE(T, z)
|
||||||
|
// z.p.color = BLACK
|
||||||
|
// z.p.p.color = RED
|
||||||
|
// RIGHT-ROTATE(T, z.p.p)
|
||||||
|
// else
|
||||||
|
// y = z.p.p.left
|
||||||
|
// if y.color == RED
|
||||||
|
// z.p.color = BLACK
|
||||||
|
// y.color = BLACK
|
||||||
|
// z.p.p.color = RED
|
||||||
|
// z = z.p.p
|
||||||
|
// else if z == z.p.right
|
||||||
|
// z = z.p
|
||||||
|
// RIGHT-ROTATE(T, z)
|
||||||
|
// z.p.color = BLACK
|
||||||
|
// z.p.p.color = RED
|
||||||
|
// LEFT-ROTATE(T, z.p.p)
|
||||||
|
//
|
||||||
|
// T.root.color = BLACK
|
||||||
func (ivt *intervalTree) insertFixup(z *intervalNode) {
|
func (ivt *intervalTree) insertFixup(z *intervalNode) {
|
||||||
for z.parent.color(ivt.sentinel) == red {
|
for z.parent.color(ivt.sentinel) == red {
|
||||||
if z.parent == z.parent.parent.left { // line 3-15
|
if z.parent == z.parent.parent.left { // line 3-15
|
||||||
@ -578,26 +576,25 @@ func (ivt *intervalTree) insertFixup(z *intervalNode) {
|
|||||||
//
|
//
|
||||||
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.2, p313
|
// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.2, p313
|
||||||
//
|
//
|
||||||
// 0. LEFT-ROTATE(T, x)
|
// LEFT-ROTATE(T, x)
|
||||||
// 1.
|
|
||||||
// 2. y = x.right
|
|
||||||
// 3. x.right = y.left
|
|
||||||
// 4.
|
|
||||||
// 5. if y.left ≠ T.nil
|
|
||||||
// 6. y.left.p = x
|
|
||||||
// 7.
|
|
||||||
// 8. y.p = x.p
|
|
||||||
// 9.
|
|
||||||
// 10. if x.p == T.nil
|
|
||||||
// 11. T.root = y
|
|
||||||
// 12. else if x == x.p.left
|
|
||||||
// 13. x.p.left = y
|
|
||||||
// 14. else
|
|
||||||
// 15. x.p.right = y
|
|
||||||
// 16.
|
|
||||||
// 17. y.left = x
|
|
||||||
// 18. x.p = y
|
|
||||||
//
|
//
|
||||||
|
// y = x.right
|
||||||
|
// x.right = y.left
|
||||||
|
//
|
||||||
|
// if y.left ≠ T.nil
|
||||||
|
// y.left.p = x
|
||||||
|
//
|
||||||
|
// y.p = x.p
|
||||||
|
//
|
||||||
|
// if x.p == T.nil
|
||||||
|
// T.root = y
|
||||||
|
// else if x == x.p.left
|
||||||
|
// x.p.left = y
|
||||||
|
// else
|
||||||
|
// x.p.right = y
|
||||||
|
//
|
||||||
|
// y.left = x
|
||||||
|
// x.p = y
|
||||||
func (ivt *intervalTree) rotateLeft(x *intervalNode) {
|
func (ivt *intervalTree) rotateLeft(x *intervalNode) {
|
||||||
// rotateLeft x must have right child
|
// rotateLeft x must have right child
|
||||||
if x.right == ivt.sentinel {
|
if x.right == ivt.sentinel {
|
||||||
@ -624,26 +621,25 @@ func (ivt *intervalTree) rotateLeft(x *intervalNode) {
|
|||||||
|
|
||||||
// rotateRight moves x so it is right of its left child
|
// rotateRight moves x so it is right of its left child
|
||||||
//
|
//
|
||||||
// 0. RIGHT-ROTATE(T, x)
|
// RIGHT-ROTATE(T, x)
|
||||||
// 1.
|
|
||||||
// 2. y = x.left
|
|
||||||
// 3. x.left = y.right
|
|
||||||
// 4.
|
|
||||||
// 5. if y.right ≠ T.nil
|
|
||||||
// 6. y.right.p = x
|
|
||||||
// 7.
|
|
||||||
// 8. y.p = x.p
|
|
||||||
// 9.
|
|
||||||
// 10. if x.p == T.nil
|
|
||||||
// 11. T.root = y
|
|
||||||
// 12. else if x == x.p.right
|
|
||||||
// 13. x.p.right = y
|
|
||||||
// 14. else
|
|
||||||
// 15. x.p.left = y
|
|
||||||
// 16.
|
|
||||||
// 17. y.right = x
|
|
||||||
// 18. x.p = y
|
|
||||||
//
|
//
|
||||||
|
// y = x.left
|
||||||
|
// x.left = y.right
|
||||||
|
//
|
||||||
|
// if y.right ≠ T.nil
|
||||||
|
// y.right.p = x
|
||||||
|
//
|
||||||
|
// y.p = x.p
|
||||||
|
//
|
||||||
|
// if x.p == T.nil
|
||||||
|
// T.root = y
|
||||||
|
// else if x == x.p.right
|
||||||
|
// x.p.right = y
|
||||||
|
// else
|
||||||
|
// x.p.left = y
|
||||||
|
//
|
||||||
|
// y.right = x
|
||||||
|
// x.p = y
|
||||||
func (ivt *intervalTree) rotateRight(x *intervalNode) {
|
func (ivt *intervalTree) rotateRight(x *intervalNode) {
|
||||||
// rotateRight x must have left child
|
// rotateRight x must have left child
|
||||||
if x.left == ivt.sentinel {
|
if x.left == ivt.sentinel {
|
||||||
|
@ -63,6 +63,7 @@ func TestIntervalTreeInsert(t *testing.T) {
|
|||||||
// Use https://www.cs.usfca.edu/~galles/visualization/RedBlack.html for test case creation.
|
// Use https://www.cs.usfca.edu/~galles/visualization/RedBlack.html for test case creation.
|
||||||
//
|
//
|
||||||
// Regular Binary Search Tree
|
// Regular Binary Search Tree
|
||||||
|
//
|
||||||
// [0,1]
|
// [0,1]
|
||||||
// \
|
// \
|
||||||
// [1,2]
|
// [1,2]
|
||||||
@ -76,6 +77,7 @@ func TestIntervalTreeInsert(t *testing.T) {
|
|||||||
// [8,9]
|
// [8,9]
|
||||||
//
|
//
|
||||||
// Self-Balancing Binary Search Tree
|
// Self-Balancing Binary Search Tree
|
||||||
|
//
|
||||||
// [1,2]
|
// [1,2]
|
||||||
// / \
|
// / \
|
||||||
// [0,1] [5,6]
|
// [0,1] [5,6]
|
||||||
@ -83,7 +85,6 @@ func TestIntervalTreeInsert(t *testing.T) {
|
|||||||
// [3,4] [7,8]
|
// [3,4] [7,8]
|
||||||
// \
|
// \
|
||||||
// [8,9]
|
// [8,9]
|
||||||
//
|
|
||||||
func TestIntervalTreeSelfBalanced(t *testing.T) {
|
func TestIntervalTreeSelfBalanced(t *testing.T) {
|
||||||
ivt := NewIntervalTree()
|
ivt := NewIntervalTree()
|
||||||
ivt.Insert(NewInt64Interval(0, 1), 0)
|
ivt.Insert(NewInt64Interval(0, 1), 0)
|
||||||
@ -120,8 +121,8 @@ func TestIntervalTreeSelfBalanced(t *testing.T) {
|
|||||||
// Use https://www.cs.usfca.edu/~galles/visualization/RedBlack.html for test case creation.
|
// Use https://www.cs.usfca.edu/~galles/visualization/RedBlack.html for test case creation.
|
||||||
// See https://github.com/etcd-io/etcd/issues/10877 for more detail.
|
// See https://github.com/etcd-io/etcd/issues/10877 for more detail.
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// After insertion:
|
// After insertion:
|
||||||
|
//
|
||||||
// [510,511]
|
// [510,511]
|
||||||
// / \
|
// / \
|
||||||
// ---------- -----------------------
|
// ---------- -----------------------
|
||||||
@ -137,8 +138,8 @@ func TestIntervalTreeSelfBalanced(t *testing.T) {
|
|||||||
// / \ /
|
// / \ /
|
||||||
// [238,239](red) [292,293](red) [953,954](red)
|
// [238,239](red) [292,293](red) [953,954](red)
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// After deleting 514 (no rebalance):
|
// After deleting 514 (no rebalance):
|
||||||
|
//
|
||||||
// [510,511]
|
// [510,511]
|
||||||
// / \
|
// / \
|
||||||
// ---------- -----------------------
|
// ---------- -----------------------
|
||||||
@ -154,8 +155,8 @@ func TestIntervalTreeSelfBalanced(t *testing.T) {
|
|||||||
// / \ /
|
// / \ /
|
||||||
// [238,239](red) [292,293](red) [953,954](red)
|
// [238,239](red) [292,293](red) [953,954](red)
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// After deleting 11 (requires rebalancing):
|
// After deleting 11 (requires rebalancing):
|
||||||
|
//
|
||||||
// [510,511]
|
// [510,511]
|
||||||
// / \
|
// / \
|
||||||
// ---------- --------------------------
|
// ---------- --------------------------
|
||||||
@ -170,8 +171,6 @@ func TestIntervalTreeSelfBalanced(t *testing.T) {
|
|||||||
// \ /
|
// \ /
|
||||||
// \ /
|
// \ /
|
||||||
// [238,239](red) [953,954](red)
|
// [238,239](red) [953,954](red)
|
||||||
//
|
|
||||||
//
|
|
||||||
func TestIntervalTreeDelete(t *testing.T) {
|
func TestIntervalTreeDelete(t *testing.T) {
|
||||||
ivt := NewIntervalTree()
|
ivt := NewIntervalTree()
|
||||||
ivt.Insert(NewInt64Interval(510, 511), 0)
|
ivt.Insert(NewInt64Interval(510, 511), 0)
|
||||||
|
@ -38,7 +38,9 @@ type Changer struct {
|
|||||||
// majority config. That is, it transitions from
|
// majority config. That is, it transitions from
|
||||||
//
|
//
|
||||||
// (1 2 3)&&()
|
// (1 2 3)&&()
|
||||||
|
//
|
||||||
// to
|
// to
|
||||||
|
//
|
||||||
// (1 2 3)&&(1 2 3).
|
// (1 2 3)&&(1 2 3).
|
||||||
//
|
//
|
||||||
// The supplied changes are then applied to the incoming majority config,
|
// The supplied changes are then applied to the incoming majority config,
|
||||||
|
@ -25,7 +25,7 @@ A simple example application, _raftexample_, is also available to help illustrat
|
|||||||
how to use this package in practice:
|
how to use this package in practice:
|
||||||
https://github.com/etcd-io/etcd/tree/main/contrib/raftexample
|
https://github.com/etcd-io/etcd/tree/main/contrib/raftexample
|
||||||
|
|
||||||
Usage
|
# Usage
|
||||||
|
|
||||||
The primary object in raft is a Node. You either start a Node from scratch
|
The primary object in raft is a Node. You either start a Node from scratch
|
||||||
using raft.StartNode or start a Node from some initial state using raft.RestartNode.
|
using raft.StartNode or start a Node from some initial state using raft.RestartNode.
|
||||||
@ -169,7 +169,7 @@ given ID MUST be used only once even if the old node has been removed.
|
|||||||
This means that for example IP addresses make poor node IDs since they
|
This means that for example IP addresses make poor node IDs since they
|
||||||
may be reused. Node IDs must be non-zero.
|
may be reused. Node IDs must be non-zero.
|
||||||
|
|
||||||
Implementation notes
|
# Implementation notes
|
||||||
|
|
||||||
This implementation is up to date with the final Raft thesis
|
This implementation is up to date with the final Raft thesis
|
||||||
(https://github.com/ongardie/dissertation/blob/master/stanford.pdf), although our
|
(https://github.com/ongardie/dissertation/blob/master/stanford.pdf), although our
|
||||||
@ -194,7 +194,7 @@ cannot be removed any more since the cluster cannot make progress.
|
|||||||
For this reason it is highly recommended to use three or more nodes in
|
For this reason it is highly recommended to use three or more nodes in
|
||||||
every cluster.
|
every cluster.
|
||||||
|
|
||||||
MessageType
|
# MessageType
|
||||||
|
|
||||||
Package raft sends and receives message in Protocol Buffer format (defined
|
Package raft sends and receives message in Protocol Buffer format (defined
|
||||||
in raftpb package). Each state (follower, candidate, leader) implements its
|
in raftpb package). Each state (follower, candidate, leader) implements its
|
||||||
@ -295,6 +295,5 @@ stale log entries:
|
|||||||
that the follower that sent this 'MsgUnreachable' is not reachable, often
|
that the follower that sent this 'MsgUnreachable' is not reachable, often
|
||||||
indicating 'MsgApp' is lost. When follower's progress state is replicate,
|
indicating 'MsgApp' is lost. When follower's progress state is replicate,
|
||||||
the leader sets it back to probe.
|
the leader sets it back to probe.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package raft
|
package raft
|
||||||
|
@ -149,8 +149,10 @@ func TestAppend(t *testing.T) {
|
|||||||
// 1. If an existing entry conflicts with a new one (same index
|
// 1. If an existing entry conflicts with a new one (same index
|
||||||
// but different terms), delete the existing entry and all that
|
// but different terms), delete the existing entry and all that
|
||||||
// follow it
|
// follow it
|
||||||
// 2.Append any new entries not already in the log
|
// 2. Append any new entries not already in the log
|
||||||
|
//
|
||||||
// If the given (index, term) does not match with the existing log:
|
// If the given (index, term) does not match with the existing log:
|
||||||
|
//
|
||||||
// return false
|
// return false
|
||||||
func TestLogMaybeAppend(t *testing.T) {
|
func TestLogMaybeAppend(t *testing.T) {
|
||||||
previousEnts := []pb.Entry{{Index: 1, Term: 1}, {Index: 2, Term: 2}, {Index: 3, Term: 3}}
|
previousEnts := []pb.Entry{{Index: 1, Term: 1}, {Index: 2, Term: 2}, {Index: 3, Term: 3}}
|
||||||
@ -528,7 +530,7 @@ func TestStableToWithSnap(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TestCompaction ensures that the number of log entries is correct after compactions.
|
// TestCompaction ensures that the number of log entries is correct after compactions.
|
||||||
func TestCompaction(t *testing.T) {
|
func TestCompaction(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
lastIndex uint64
|
lastIndex uint64
|
||||||
|
@ -2818,7 +2818,7 @@ func TestRestoreWithLearner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests if outgoing voter can receive and apply snapshot correctly.
|
// Tests if outgoing voter can receive and apply snapshot correctly.
|
||||||
func TestRestoreWithVotersOutgoing(t *testing.T) {
|
func TestRestoreWithVotersOutgoing(t *testing.T) {
|
||||||
s := pb.Snapshot{
|
s := pb.Snapshot{
|
||||||
Metadata: pb.SnapshotMetadata{
|
Metadata: pb.SnapshotMetadata{
|
||||||
|
@ -98,7 +98,7 @@ func TestStoreStatsDeleteFail(t *testing.T) {
|
|||||||
testutil.AssertEqual(t, uint64(1), s.Stats.DeleteFail, "")
|
testutil.AssertEqual(t, uint64(1), s.Stats.DeleteFail, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ensure that the number of expirations is recorded in the stats.
|
// Ensure that the number of expirations is recorded in the stats.
|
||||||
func TestStoreStatsExpireCount(t *testing.T) {
|
func TestStoreStatsExpireCount(t *testing.T) {
|
||||||
s := newStore()
|
s := newStore()
|
||||||
fc := newFakeClock()
|
fc := newFakeClock()
|
||||||
|
@ -41,5 +41,4 @@
|
|||||||
// if err != nil {
|
// if err != nil {
|
||||||
// // handle error!
|
// // handle error!
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
package v3client
|
package v3client
|
||||||
|
@ -342,6 +342,7 @@ func (r *raftNode) start(rh *raftReadyHandler) {
|
|||||||
// including BoltDB and WAL, because:
|
// including BoltDB and WAL, because:
|
||||||
// 1. etcd commits the boltDB transaction periodically instead of on each request;
|
// 1. etcd commits the boltDB transaction periodically instead of on each request;
|
||||||
// 2. etcd saves WAL entries in parallel with applying the committed entries.
|
// 2. etcd saves WAL entries in parallel with applying the committed entries.
|
||||||
|
//
|
||||||
// Accordingly, it might run into a situation of data loss when the etcd crashes
|
// Accordingly, it might run into a situation of data loss when the etcd crashes
|
||||||
// immediately after responding to the client and before the boltDB and WAL
|
// immediately after responding to the client and before the boltDB and WAL
|
||||||
// successfully save the data to disk.
|
// successfully save the data to disk.
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
//
|
//
|
||||||
// This package should NOT be extended or modified in any way; to modify the
|
// This package should NOT be extended or modified in any way; to modify the
|
||||||
// etcd binary, work in the `go.etcd.io/etcd/etcdmain` package.
|
// etcd binary, work in the `go.etcd.io/etcd/etcdmain` package.
|
||||||
//
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -39,6 +39,7 @@ var (
|
|||||||
// key: "foo"
|
// key: "foo"
|
||||||
// rev: 5
|
// rev: 5
|
||||||
// generations:
|
// generations:
|
||||||
|
//
|
||||||
// {empty}
|
// {empty}
|
||||||
// {4.0, 5.0(t)}
|
// {4.0, 5.0(t)}
|
||||||
// {1.0, 2.0, 3.0(t)}
|
// {1.0, 2.0, 3.0(t)}
|
||||||
@ -51,21 +52,25 @@ var (
|
|||||||
// For example:
|
// For example:
|
||||||
// compact(2) on the previous example
|
// compact(2) on the previous example
|
||||||
// generations:
|
// generations:
|
||||||
|
//
|
||||||
// {empty}
|
// {empty}
|
||||||
// {4.0, 5.0(t)}
|
// {4.0, 5.0(t)}
|
||||||
// {2.0, 3.0(t)}
|
// {2.0, 3.0(t)}
|
||||||
//
|
//
|
||||||
// compact(4)
|
// compact(4)
|
||||||
// generations:
|
// generations:
|
||||||
|
//
|
||||||
// {empty}
|
// {empty}
|
||||||
// {4.0, 5.0(t)}
|
// {4.0, 5.0(t)}
|
||||||
//
|
//
|
||||||
// compact(5):
|
// compact(5):
|
||||||
// generations:
|
// generations:
|
||||||
|
//
|
||||||
// {empty} -> key SHOULD be removed.
|
// {empty} -> key SHOULD be removed.
|
||||||
//
|
//
|
||||||
// compact(6):
|
// compact(6):
|
||||||
// generations:
|
// generations:
|
||||||
|
//
|
||||||
// {empty} -> key SHOULD be removed.
|
// {empty} -> key SHOULD be removed.
|
||||||
type keyIndex struct {
|
type keyIndex struct {
|
||||||
key []byte
|
key []byte
|
||||||
|
@ -70,6 +70,5 @@ snapshot to the end of the WAL are read first:
|
|||||||
|
|
||||||
This will give you the metadata, the last raft.State and the slice of
|
This will give you the metadata, the last raft.State and the slice of
|
||||||
raft.Entry items in the log.
|
raft.Entry items in the log.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package wal
|
package wal
|
||||||
|
@ -41,6 +41,7 @@ x and y of GCD 1 are coprime to each other
|
|||||||
x1 = ( coprime of n * idx1 + offset ) % n
|
x1 = ( coprime of n * idx1 + offset ) % n
|
||||||
x2 = ( coprime of n * idx2 + offset ) % n
|
x2 = ( coprime of n * idx2 + offset ) % n
|
||||||
(x2 - x1) = coprime of n * (idx2 - idx1) % n
|
(x2 - x1) = coprime of n * (idx2 - idx1) % n
|
||||||
|
|
||||||
= (idx2 - idx1) = 1
|
= (idx2 - idx1) = 1
|
||||||
|
|
||||||
Consecutive x's are guaranteed to be distinct
|
Consecutive x's are guaranteed to be distinct
|
||||||
|
@ -207,7 +207,6 @@ func TestElectionSessionRecampaign(t *testing.T) {
|
|||||||
// candidate can be elected on a new key that is a prefix
|
// candidate can be elected on a new key that is a prefix
|
||||||
// of an existing key. To wit, check for regression
|
// of an existing key. To wit, check for regression
|
||||||
// of bug #6278. https://github.com/etcd-io/etcd/issues/6278
|
// of bug #6278. https://github.com/etcd-io/etcd/issues/6278
|
||||||
//
|
|
||||||
func TestElectionOnPrefixOfExistingKey(t *testing.T) {
|
func TestElectionOnPrefixOfExistingKey(t *testing.T) {
|
||||||
BeforeTest(t)
|
BeforeTest(t)
|
||||||
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build libs
|
||||||
// +build libs
|
// +build libs
|
||||||
|
|
||||||
// This file implements that pattern:
|
// This file implements that pattern:
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build tools
|
||||||
// +build tools
|
// +build tools
|
||||||
|
|
||||||
// This file implements that pattern:
|
// This file implements that pattern:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user