vector.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Copyright (C) 2015 The Protocol Authors.
  2. package protocol
  3. // The Vector type represents a version vector. The zero value is a usable
  4. // version vector. The vector has slice semantics and some operations on it
  5. // are "append-like" in that they may return the same vector modified, or v
  6. // new allocated Vector with the modified contents.
  7. // Counter represents a single counter in the version vector.
  8. // Update returns a Vector with the index for the specific ID incremented by
  9. // one. If it is possible, the vector v is updated and returned. If it is not,
  10. // a copy will be created, updated and returned.
  11. func (v Vector) Update(id ShortID) Vector {
  12. for i := range v.Counters {
  13. if v.Counters[i].ID == id {
  14. // Update an existing index
  15. v.Counters[i].Value++
  16. return v
  17. } else if v.Counters[i].ID > id {
  18. // Insert a new index
  19. nv := make([]Counter, len(v.Counters)+1)
  20. copy(nv, v.Counters[:i])
  21. nv[i].ID = id
  22. nv[i].Value = 1
  23. copy(nv[i+1:], v.Counters[i:])
  24. return Vector{nv}
  25. }
  26. }
  27. // Append a new index
  28. return Vector{append(v.Counters, Counter{id, 1})}
  29. }
  30. // Merge returns the vector containing the maximum indexes from v and b. If it
  31. // is possible, the vector v is updated and returned. If it is not, a copy
  32. // will be created, updated and returned.
  33. func (v Vector) Merge(b Vector) Vector {
  34. var vi, bi int
  35. for bi < len(b.Counters) {
  36. if vi == len(v.Counters) {
  37. // We've reach the end of v, all that remains are appends
  38. return Vector{append(v.Counters, b.Counters[bi:]...)}
  39. }
  40. if v.Counters[vi].ID > b.Counters[bi].ID {
  41. // The index from b should be inserted here
  42. n := make([]Counter, len(v.Counters)+1)
  43. copy(n, v.Counters[:vi])
  44. n[vi] = b.Counters[bi]
  45. copy(n[vi+1:], v.Counters[vi:])
  46. v.Counters = n
  47. }
  48. if v.Counters[vi].ID == b.Counters[bi].ID {
  49. if val := b.Counters[bi].Value; val > v.Counters[vi].Value {
  50. v.Counters[vi].Value = val
  51. }
  52. }
  53. if bi < len(b.Counters) && v.Counters[vi].ID == b.Counters[bi].ID {
  54. bi++
  55. }
  56. vi++
  57. }
  58. return v
  59. }
  60. // Copy returns an identical vector that is not shared with v.
  61. func (v Vector) Copy() Vector {
  62. nv := make([]Counter, len(v.Counters))
  63. copy(nv, v.Counters)
  64. return Vector{nv}
  65. }
  66. // Equal returns true when the two vectors are equivalent.
  67. func (v Vector) Equal(b Vector) bool {
  68. return v.Compare(b) == Equal
  69. }
  70. // LesserEqual returns true when the two vectors are equivalent or v is Lesser
  71. // than b.
  72. func (v Vector) LesserEqual(b Vector) bool {
  73. comp := v.Compare(b)
  74. return comp == Lesser || comp == Equal
  75. }
  76. // GreaterEqual returns true when the two vectors are equivalent or v is Greater
  77. // than b.
  78. func (v Vector) GreaterEqual(b Vector) bool {
  79. comp := v.Compare(b)
  80. return comp == Greater || comp == Equal
  81. }
  82. // Concurrent returns true when the two vectors are concurrent.
  83. func (v Vector) Concurrent(b Vector) bool {
  84. comp := v.Compare(b)
  85. return comp == ConcurrentGreater || comp == ConcurrentLesser
  86. }
  87. // Counter returns the current value of the given counter ID.
  88. func (v Vector) Counter(id ShortID) uint64 {
  89. for _, c := range v.Counters {
  90. if c.ID == id {
  91. return c.Value
  92. }
  93. }
  94. return 0
  95. }
  96. // DropOthers removes all counters, keeping only the one with given id. If there
  97. // is no such counter, an empty Vector is returned.
  98. func (v Vector) DropOthers(id ShortID) Vector {
  99. for i, c := range v.Counters {
  100. if c.ID == id {
  101. v.Counters = v.Counters[i : i+1]
  102. return v
  103. }
  104. }
  105. return Vector{}
  106. }
  107. // Ordering represents the relationship between two Vectors.
  108. type Ordering int
  109. const (
  110. Equal Ordering = iota
  111. Greater
  112. Lesser
  113. ConcurrentLesser
  114. ConcurrentGreater
  115. )
  116. // There's really no such thing as "concurrent lesser" and "concurrent
  117. // greater" in version vectors, just "concurrent". But it's useful to be able
  118. // to get a strict ordering between versions for stable sorts and so on, so we
  119. // return both variants. The convenience method Concurrent() can be used to
  120. // check for either case.
  121. // Compare returns the Ordering that describes a's relation to b.
  122. func (v Vector) Compare(b Vector) Ordering {
  123. var ai, bi int // index into a and b
  124. var av, bv Counter // value at current index
  125. result := Equal
  126. for ai < len(v.Counters) || bi < len(b.Counters) {
  127. var aMissing, bMissing bool
  128. if ai < len(v.Counters) {
  129. av = v.Counters[ai]
  130. } else {
  131. av = Counter{}
  132. aMissing = true
  133. }
  134. if bi < len(b.Counters) {
  135. bv = b.Counters[bi]
  136. } else {
  137. bv = Counter{}
  138. bMissing = true
  139. }
  140. switch {
  141. case av.ID == bv.ID:
  142. // We have a counter value for each side
  143. if av.Value > bv.Value {
  144. if result == Lesser {
  145. return ConcurrentLesser
  146. }
  147. result = Greater
  148. } else if av.Value < bv.Value {
  149. if result == Greater {
  150. return ConcurrentGreater
  151. }
  152. result = Lesser
  153. }
  154. case !aMissing && av.ID < bv.ID || bMissing:
  155. // Value is missing on the b side
  156. if av.Value > 0 {
  157. if result == Lesser {
  158. return ConcurrentLesser
  159. }
  160. result = Greater
  161. }
  162. case !bMissing && bv.ID < av.ID || aMissing:
  163. // Value is missing on the a side
  164. if bv.Value > 0 {
  165. if result == Greater {
  166. return ConcurrentGreater
  167. }
  168. result = Lesser
  169. }
  170. }
  171. if ai < len(v.Counters) && (av.ID <= bv.ID || bMissing) {
  172. ai++
  173. }
  174. if bi < len(b.Counters) && (bv.ID <= av.ID || aMissing) {
  175. bi++
  176. }
  177. }
  178. return result
  179. }