vector.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // Copyright (C) 2015 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package protocol
  7. import (
  8. "time"
  9. "github.com/syncthing/syncthing/internal/gen/bep"
  10. )
  11. // The Vector type represents a version vector. The zero value is a usable
  12. // version vector. The vector has slice semantics and some operations on it
  13. // are "append-like" in that they may return the same vector modified, or v
  14. // new allocated Vector with the modified contents.
  15. type Vector struct {
  16. Counters []Counter
  17. }
  18. func (v *Vector) ToWire() *bep.Vector {
  19. counters := make([]*bep.Counter, len(v.Counters))
  20. for i, c := range v.Counters {
  21. counters[i] = c.toWire()
  22. }
  23. return &bep.Vector{
  24. Counters: counters,
  25. }
  26. }
  27. func VectorFromWire(w *bep.Vector) Vector {
  28. var v Vector
  29. if w == nil || len(w.Counters) == 0 {
  30. return v
  31. }
  32. v.Counters = make([]Counter, len(w.Counters))
  33. for i, c := range w.Counters {
  34. v.Counters[i] = counterFromWire(c)
  35. }
  36. return v
  37. }
  38. // Counter represents a single counter in the version vector.
  39. type Counter struct {
  40. ID ShortID
  41. Value uint64
  42. }
  43. func (c *Counter) toWire() *bep.Counter {
  44. return &bep.Counter{
  45. Id: uint64(c.ID),
  46. Value: c.Value,
  47. }
  48. }
  49. func counterFromWire(w *bep.Counter) Counter {
  50. return Counter{
  51. ID: ShortID(w.Id),
  52. Value: w.Value,
  53. }
  54. }
  55. // Update returns a Vector with the index for the specific ID incremented by
  56. // one. If it is possible, the vector v is updated and returned. If it is not,
  57. // a copy will be created, updated and returned.
  58. func (v Vector) Update(id ShortID) Vector {
  59. now := uint64(time.Now().Unix())
  60. return v.updateWithNow(id, now)
  61. }
  62. func (v Vector) updateWithNow(id ShortID, now uint64) Vector {
  63. for i := range v.Counters {
  64. if v.Counters[i].ID == id {
  65. // Update an existing index
  66. v.Counters[i].Value = max(v.Counters[i].Value+1, now)
  67. return v
  68. } else if v.Counters[i].ID > id {
  69. // Insert a new index
  70. nv := make([]Counter, len(v.Counters)+1)
  71. copy(nv, v.Counters[:i])
  72. nv[i].ID = id
  73. nv[i].Value = max(1, now)
  74. copy(nv[i+1:], v.Counters[i:])
  75. return Vector{Counters: nv}
  76. }
  77. }
  78. // Append a new index
  79. return Vector{Counters: append(v.Counters, Counter{
  80. ID: id,
  81. Value: max(1, now),
  82. })}
  83. }
  84. // Merge returns the vector containing the maximum indexes from v and b. If it
  85. // is possible, the vector v is updated and returned. If it is not, a copy
  86. // will be created, updated and returned.
  87. func (v Vector) Merge(b Vector) Vector {
  88. var vi, bi int
  89. for bi < len(b.Counters) {
  90. if vi == len(v.Counters) {
  91. // We've reach the end of v, all that remains are appends
  92. return Vector{Counters: append(v.Counters, b.Counters[bi:]...)}
  93. }
  94. if v.Counters[vi].ID > b.Counters[bi].ID {
  95. // The index from b should be inserted here
  96. n := make([]Counter, len(v.Counters)+1)
  97. copy(n, v.Counters[:vi])
  98. n[vi] = b.Counters[bi]
  99. copy(n[vi+1:], v.Counters[vi:])
  100. v.Counters = n
  101. }
  102. if v.Counters[vi].ID == b.Counters[bi].ID {
  103. if val := b.Counters[bi].Value; val > v.Counters[vi].Value {
  104. v.Counters[vi].Value = val
  105. }
  106. }
  107. if bi < len(b.Counters) && v.Counters[vi].ID == b.Counters[bi].ID {
  108. bi++
  109. }
  110. vi++
  111. }
  112. return v
  113. }
  114. // Copy returns an identical vector that is not shared with v.
  115. func (v Vector) Copy() Vector {
  116. nv := make([]Counter, len(v.Counters))
  117. copy(nv, v.Counters)
  118. return Vector{Counters: nv}
  119. }
  120. // Equal returns true when the two vectors are equivalent.
  121. func (v Vector) Equal(b Vector) bool {
  122. return v.Compare(b) == Equal
  123. }
  124. // LesserEqual returns true when the two vectors are equivalent or v is Lesser
  125. // than b.
  126. func (v Vector) LesserEqual(b Vector) bool {
  127. comp := v.Compare(b)
  128. return comp == Lesser || comp == Equal
  129. }
  130. // GreaterEqual returns true when the two vectors are equivalent or v is Greater
  131. // than b.
  132. func (v Vector) GreaterEqual(b Vector) bool {
  133. comp := v.Compare(b)
  134. return comp == Greater || comp == Equal
  135. }
  136. // Concurrent returns true when the two vectors are concurrent.
  137. func (v Vector) Concurrent(b Vector) bool {
  138. comp := v.Compare(b)
  139. return comp == ConcurrentGreater || comp == ConcurrentLesser
  140. }
  141. // Counter returns the current value of the given counter ID.
  142. func (v Vector) Counter(id ShortID) uint64 {
  143. for _, c := range v.Counters {
  144. if c.ID == id {
  145. return c.Value
  146. }
  147. }
  148. return 0
  149. }
  150. // IsEmpty returns true when there are no counters.
  151. func (v Vector) IsEmpty() bool {
  152. return len(v.Counters) == 0
  153. }
  154. // DropOthers removes all counters, keeping only the one with given id. If there
  155. // is no such counter, an empty Vector is returned.
  156. func (v Vector) DropOthers(id ShortID) Vector {
  157. for i, c := range v.Counters {
  158. if c.ID == id {
  159. v.Counters = v.Counters[i : i+1]
  160. return v
  161. }
  162. }
  163. return Vector{}
  164. }
  165. // Ordering represents the relationship between two Vectors.
  166. type Ordering int
  167. const (
  168. Equal Ordering = iota
  169. Greater
  170. Lesser
  171. ConcurrentLesser
  172. ConcurrentGreater
  173. )
  174. // There's really no such thing as "concurrent lesser" and "concurrent
  175. // greater" in version vectors, just "concurrent". But it's useful to be able
  176. // to get a strict ordering between versions for stable sorts and so on, so we
  177. // return both variants. The convenience method Concurrent() can be used to
  178. // check for either case.
  179. // Compare returns the Ordering that describes a's relation to b.
  180. func (v Vector) Compare(b Vector) Ordering {
  181. var ai, bi int // index into a and b
  182. var av, bv Counter // value at current index
  183. result := Equal
  184. for ai < len(v.Counters) || bi < len(b.Counters) {
  185. var aMissing, bMissing bool
  186. if ai < len(v.Counters) {
  187. av = v.Counters[ai]
  188. } else {
  189. av = Counter{}
  190. aMissing = true
  191. }
  192. if bi < len(b.Counters) {
  193. bv = b.Counters[bi]
  194. } else {
  195. bv = Counter{}
  196. bMissing = true
  197. }
  198. switch {
  199. case av.ID == bv.ID:
  200. // We have a counter value for each side
  201. if av.Value > bv.Value {
  202. if result == Lesser {
  203. return ConcurrentLesser
  204. }
  205. result = Greater
  206. } else if av.Value < bv.Value {
  207. if result == Greater {
  208. return ConcurrentGreater
  209. }
  210. result = Lesser
  211. }
  212. case !aMissing && av.ID < bv.ID || bMissing:
  213. // Value is missing on the b side
  214. if av.Value > 0 {
  215. if result == Lesser {
  216. return ConcurrentLesser
  217. }
  218. result = Greater
  219. }
  220. case !bMissing && bv.ID < av.ID || aMissing:
  221. // Value is missing on the a side
  222. if bv.Value > 0 {
  223. if result == Greater {
  224. return ConcurrentGreater
  225. }
  226. result = Lesser
  227. }
  228. }
  229. if ai < len(v.Counters) && (av.ID <= bv.ID || bMissing) {
  230. ai++
  231. }
  232. if bi < len(b.Counters) && (bv.ID <= av.ID || aMissing) {
  233. bi++
  234. }
  235. }
  236. return result
  237. }