vector_compare.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright (C) 2015 The Protocol Authors.
  2. package protocol
  3. // Ordering represents the relationship between two Vectors.
  4. type Ordering int
  5. const (
  6. Equal Ordering = iota
  7. Greater
  8. Lesser
  9. ConcurrentLesser
  10. ConcurrentGreater
  11. )
  12. // There's really no such thing as "concurrent lesser" and "concurrent
  13. // greater" in version vectors, just "concurrent". But it's useful to be able
  14. // to get a strict ordering between versions for stable sorts and so on, so we
  15. // return both variants. The convenience method Concurrent() can be used to
  16. // check for either case.
  17. // Compare returns the Ordering that describes a's relation to b.
  18. func (a Vector) Compare(b Vector) Ordering {
  19. var ai, bi int // index into a and b
  20. var av, bv Counter // value at current index
  21. result := Equal
  22. for ai < len(a) || bi < len(b) {
  23. var aMissing, bMissing bool
  24. if ai < len(a) {
  25. av = a[ai]
  26. } else {
  27. av = Counter{}
  28. aMissing = true
  29. }
  30. if bi < len(b) {
  31. bv = b[bi]
  32. } else {
  33. bv = Counter{}
  34. bMissing = true
  35. }
  36. switch {
  37. case av.ID == bv.ID:
  38. // We have a counter value for each side
  39. if av.Value > bv.Value {
  40. if result == Lesser {
  41. return ConcurrentLesser
  42. }
  43. result = Greater
  44. } else if av.Value < bv.Value {
  45. if result == Greater {
  46. return ConcurrentGreater
  47. }
  48. result = Lesser
  49. }
  50. case !aMissing && av.ID < bv.ID || bMissing:
  51. // Value is missing on the b side
  52. if av.Value > 0 {
  53. if result == Lesser {
  54. return ConcurrentLesser
  55. }
  56. result = Greater
  57. }
  58. case !bMissing && bv.ID < av.ID || aMissing:
  59. // Value is missing on the a side
  60. if bv.Value > 0 {
  61. if result == Greater {
  62. return ConcurrentGreater
  63. }
  64. result = Lesser
  65. }
  66. }
  67. if ai < len(a) && (av.ID <= bv.ID || bMissing) {
  68. ai++
  69. }
  70. if bi < len(b) && (bv.ID <= av.ID || aMissing) {
  71. bi++
  72. }
  73. }
  74. return result
  75. }