1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- // Copyright (C) 2015 The Protocol Authors.
- package protocol
- // Ordering represents the relationship between two Vectors.
- type Ordering int
- const (
- Equal Ordering = iota
- Greater
- Lesser
- ConcurrentLesser
- ConcurrentGreater
- )
- // There's really no such thing as "concurrent lesser" and "concurrent
- // greater" in version vectors, just "concurrent". But it's useful to be able
- // to get a strict ordering between versions for stable sorts and so on, so we
- // return both variants. The convenience method Concurrent() can be used to
- // check for either case.
- // Compare returns the Ordering that describes a's relation to b.
- func (a Vector) Compare(b Vector) Ordering {
- var ai, bi int // index into a and b
- var av, bv Counter // value at current index
- result := Equal
- for ai < len(a) || bi < len(b) {
- var aMissing, bMissing bool
- if ai < len(a) {
- av = a[ai]
- } else {
- av = Counter{}
- aMissing = true
- }
- if bi < len(b) {
- bv = b[bi]
- } else {
- bv = Counter{}
- bMissing = true
- }
- switch {
- case av.ID == bv.ID:
- // We have a counter value for each side
- if av.Value > bv.Value {
- if result == Lesser {
- return ConcurrentLesser
- }
- result = Greater
- } else if av.Value < bv.Value {
- if result == Greater {
- return ConcurrentGreater
- }
- result = Lesser
- }
- case !aMissing && av.ID < bv.ID || bMissing:
- // Value is missing on the b side
- if av.Value > 0 {
- if result == Lesser {
- return ConcurrentLesser
- }
- result = Greater
- }
- case !bMissing && bv.ID < av.ID || aMissing:
- // Value is missing on the a side
- if bv.Value > 0 {
- if result == Greater {
- return ConcurrentGreater
- }
- result = Lesser
- }
- }
- if ai < len(a) && (av.ID <= bv.ID || bMissing) {
- ai++
- }
- if bi < len(b) && (bv.ID <= av.ID || aMissing) {
- bi++
- }
- }
- return result
- }
|