vector.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. "encoding/binary"
  9. "encoding/hex"
  10. "fmt"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "github.com/syncthing/syncthing/internal/gen/bep"
  15. )
  16. // The Vector type represents a version vector. The zero value is a usable
  17. // version vector. The vector has slice semantics and some operations on it
  18. // are "append-like" in that they may return the same vector modified, or v
  19. // new allocated Vector with the modified contents.
  20. type Vector struct {
  21. Counters []Counter
  22. }
  23. func (v *Vector) String() string {
  24. var buf strings.Builder
  25. for i, c := range v.Counters {
  26. if i > 0 {
  27. buf.WriteRune(',')
  28. }
  29. var idbs [8]byte
  30. binary.BigEndian.PutUint64(idbs[:], uint64(c.ID))
  31. fmt.Fprintf(&buf, "%x:%d", idbs, c.Value)
  32. }
  33. return buf.String()
  34. }
  35. func (v *Vector) HumanString() string {
  36. var buf strings.Builder
  37. for i, c := range v.Counters {
  38. if i > 0 {
  39. buf.WriteRune(',')
  40. }
  41. fmt.Fprintf(&buf, "%s:%d", c.ID, c.Value)
  42. }
  43. return buf.String()
  44. }
  45. func (v *Vector) ToWire() *bep.Vector {
  46. counters := make([]*bep.Counter, len(v.Counters))
  47. for i, c := range v.Counters {
  48. counters[i] = c.toWire()
  49. }
  50. return &bep.Vector{
  51. Counters: counters,
  52. }
  53. }
  54. func VectorFromWire(w *bep.Vector) Vector {
  55. var v Vector
  56. if w == nil || len(w.Counters) == 0 {
  57. return v
  58. }
  59. v.Counters = make([]Counter, len(w.Counters))
  60. for i, c := range w.Counters {
  61. v.Counters[i] = counterFromWire(c)
  62. }
  63. return v
  64. }
  65. func VectorFromString(s string) (Vector, error) {
  66. pairs := strings.Split(s, ",")
  67. var v Vector
  68. v.Counters = make([]Counter, len(pairs))
  69. for i, pair := range pairs {
  70. idStr, valStr, ok := strings.Cut(pair, ":")
  71. if !ok {
  72. return Vector{}, fmt.Errorf("bad pair %q", pair)
  73. }
  74. idslice, err := hex.DecodeString(idStr)
  75. if err != nil {
  76. return Vector{}, fmt.Errorf("bad id in pair %q", pair)
  77. }
  78. var idbs [8]byte
  79. copy(idbs[8-len(idslice):], idslice)
  80. id := binary.BigEndian.Uint64(idbs[:])
  81. val, err := strconv.ParseUint(valStr, 10, 64)
  82. if err != nil {
  83. return Vector{}, fmt.Errorf("bad val in pair %q", pair)
  84. }
  85. v.Counters[i] = Counter{ID: ShortID(id), Value: val}
  86. }
  87. return v, nil
  88. }
  89. // Counter represents a single counter in the version vector.
  90. type Counter struct {
  91. ID ShortID
  92. Value uint64
  93. }
  94. func (c *Counter) toWire() *bep.Counter {
  95. return &bep.Counter{
  96. Id: uint64(c.ID),
  97. Value: c.Value,
  98. }
  99. }
  100. func counterFromWire(w *bep.Counter) Counter {
  101. return Counter{
  102. ID: ShortID(w.Id),
  103. Value: w.Value,
  104. }
  105. }
  106. // Update returns a Vector with the index for the specific ID incremented by
  107. // one. If it is possible, the vector v is updated and returned. If it is not,
  108. // a copy will be created, updated and returned.
  109. func (v Vector) Update(id ShortID) Vector {
  110. now := uint64(time.Now().Unix())
  111. return v.updateWithNow(id, now)
  112. }
  113. func (v Vector) updateWithNow(id ShortID, now uint64) Vector {
  114. for i := range v.Counters {
  115. if v.Counters[i].ID == id {
  116. // Update an existing index
  117. v.Counters[i].Value = max(v.Counters[i].Value+1, now)
  118. return v
  119. } else if v.Counters[i].ID > id {
  120. // Insert a new index
  121. nv := make([]Counter, len(v.Counters)+1)
  122. copy(nv, v.Counters[:i])
  123. nv[i].ID = id
  124. nv[i].Value = max(1, now)
  125. copy(nv[i+1:], v.Counters[i:])
  126. return Vector{Counters: nv}
  127. }
  128. }
  129. // Append a new index
  130. return Vector{Counters: append(v.Counters, Counter{
  131. ID: id,
  132. Value: max(1, now),
  133. })}
  134. }
  135. // Merge returns the vector containing the maximum indexes from v and b. If it
  136. // is possible, the vector v is updated and returned. If it is not, a copy
  137. // will be created, updated and returned.
  138. func (v Vector) Merge(b Vector) Vector {
  139. var vi, bi int
  140. for bi < len(b.Counters) {
  141. if vi == len(v.Counters) {
  142. // We've reach the end of v, all that remains are appends
  143. return Vector{Counters: append(v.Counters, b.Counters[bi:]...)}
  144. }
  145. if v.Counters[vi].ID > b.Counters[bi].ID {
  146. // The index from b should be inserted here
  147. n := make([]Counter, len(v.Counters)+1)
  148. copy(n, v.Counters[:vi])
  149. n[vi] = b.Counters[bi]
  150. copy(n[vi+1:], v.Counters[vi:])
  151. v.Counters = n
  152. }
  153. if v.Counters[vi].ID == b.Counters[bi].ID {
  154. if val := b.Counters[bi].Value; val > v.Counters[vi].Value {
  155. v.Counters[vi].Value = val
  156. }
  157. }
  158. if bi < len(b.Counters) && v.Counters[vi].ID == b.Counters[bi].ID {
  159. bi++
  160. }
  161. vi++
  162. }
  163. return v
  164. }
  165. // Copy returns an identical vector that is not shared with v.
  166. func (v Vector) Copy() Vector {
  167. nv := make([]Counter, len(v.Counters))
  168. copy(nv, v.Counters)
  169. return Vector{Counters: nv}
  170. }
  171. // Equal returns true when the two vectors are equivalent.
  172. func (v Vector) Equal(b Vector) bool {
  173. return v.Compare(b) == Equal
  174. }
  175. // LesserEqual returns true when the two vectors are equivalent or v is Lesser
  176. // than b.
  177. func (v Vector) LesserEqual(b Vector) bool {
  178. comp := v.Compare(b)
  179. return comp == Lesser || comp == Equal
  180. }
  181. // GreaterEqual returns true when the two vectors are equivalent or v is Greater
  182. // than b.
  183. func (v Vector) GreaterEqual(b Vector) bool {
  184. comp := v.Compare(b)
  185. return comp == Greater || comp == Equal
  186. }
  187. // Concurrent returns true when the two vectors are concurrent.
  188. func (v Vector) Concurrent(b Vector) bool {
  189. comp := v.Compare(b)
  190. return comp == ConcurrentGreater || comp == ConcurrentLesser
  191. }
  192. // Counter returns the current value of the given counter ID.
  193. func (v Vector) Counter(id ShortID) uint64 {
  194. for _, c := range v.Counters {
  195. if c.ID == id {
  196. return c.Value
  197. }
  198. }
  199. return 0
  200. }
  201. // IsEmpty returns true when there are no counters.
  202. func (v Vector) IsEmpty() bool {
  203. return len(v.Counters) == 0
  204. }
  205. // DropOthers removes all counters, keeping only the one with given id. If there
  206. // is no such counter, an empty Vector is returned.
  207. func (v Vector) DropOthers(id ShortID) Vector {
  208. for i, c := range v.Counters {
  209. if c.ID == id {
  210. v.Counters = v.Counters[i : i+1]
  211. return v
  212. }
  213. }
  214. return Vector{}
  215. }
  216. // Ordering represents the relationship between two Vectors.
  217. type Ordering int
  218. const (
  219. Equal Ordering = iota
  220. Greater
  221. Lesser
  222. ConcurrentLesser
  223. ConcurrentGreater
  224. )
  225. // There's really no such thing as "concurrent lesser" and "concurrent
  226. // greater" in version vectors, just "concurrent". But it's useful to be able
  227. // to get a strict ordering between versions for stable sorts and so on, so we
  228. // return both variants. The convenience method Concurrent() can be used to
  229. // check for either case.
  230. // Compare returns the Ordering that describes a's relation to b.
  231. func (v Vector) Compare(b Vector) Ordering {
  232. var ai, bi int // index into a and b
  233. var av, bv Counter // value at current index
  234. result := Equal
  235. for ai < len(v.Counters) || bi < len(b.Counters) {
  236. var aMissing, bMissing bool
  237. if ai < len(v.Counters) {
  238. av = v.Counters[ai]
  239. } else {
  240. av = Counter{}
  241. aMissing = true
  242. }
  243. if bi < len(b.Counters) {
  244. bv = b.Counters[bi]
  245. } else {
  246. bv = Counter{}
  247. bMissing = true
  248. }
  249. switch {
  250. case av.ID == bv.ID:
  251. // We have a counter value for each side
  252. if av.Value > bv.Value {
  253. if result == Lesser {
  254. return ConcurrentLesser
  255. }
  256. result = Greater
  257. } else if av.Value < bv.Value {
  258. if result == Greater {
  259. return ConcurrentGreater
  260. }
  261. result = Lesser
  262. }
  263. case !aMissing && av.ID < bv.ID || bMissing:
  264. // Value is missing on the b side
  265. if av.Value > 0 {
  266. if result == Lesser {
  267. return ConcurrentLesser
  268. }
  269. result = Greater
  270. }
  271. case !bMissing && bv.ID < av.ID || aMissing:
  272. // Value is missing on the a side
  273. if bv.Value > 0 {
  274. if result == Greater {
  275. return ConcurrentGreater
  276. }
  277. result = Lesser
  278. }
  279. }
  280. if ai < len(v.Counters) && (av.ID <= bv.ID || bMissing) {
  281. ai++
  282. }
  283. if bi < len(b.Counters) && (bv.ID <= av.ID || aMissing) {
  284. bi++
  285. }
  286. }
  287. return result
  288. }