Сортировочный список векторных часов (общий порядок)?

Я понимаю, что векторные часы обеспечивают только частичный порядок. Таким образом, вы не можете напрямую их отсортировать. По этой причине вы используете разделитель для векторов, которые являются параллельными, что приводит к общему порядку.

Однако сортировка векторных часов так, чтобы каждая причина предшествовала каждому эффекту в результирующем списке, похоже, не работает, и я не совсем понимаю, почему.

У меня есть обширные тесты, которые показывают, что сравнение двух векторов работает:

    @Override
    public int compareTo(VectorClock<K> that) {

        var res = 0;

        if (this.isAfter(that))
            res = 1;
        else if (that.isAfter(this))
            res = -1;
        else
            res = this.timestamp.compareTo(that.timestamp);

        System.out.println("compare " + this + " : " + that + " => " + res);

        return res;
    }

    public boolean isAfter(VectorClock<K> that) {
        boolean anyClockGreater = false;

        var set = new HashSet<K>();
        set.addAll(this.keySet());
        set.addAll(that.keySet());

        for (K key : set) {
            final Clock thatClock = that.get(key);
            final Clock thisClock = this.get(key);

            if (thisClock == null || thisClock.isBefore(thatClock)) {
                return false;
            } else if (thisClock.isAfter(thatClock)) {
                anyClockGreater = true;
            }
        }
        // there is at least one local timestamp greater or local vector clock has additional timestamps
        return anyClockGreater || that.entrySet().size() < entrySet().size();
    }

Однако при сортировке списка векторных часов, например, одного с двумя векторами, которые имеют отношение случившегося до, и третьего вектора, который является параллельным обоим другим, может случиться так, что только параллельный вектор сравнивается с двумя другими, а векторы, которые зависят от друг на друга не сравниваются. Вместо этого их порядок (ошибочно) транзитивно определяется тай-брейком:

VectorClock<String> v1 = VectorClock.fromString("{0=23, 1=28, 2=15, 3=23, 4=15, 5=22, 6=14, 7=19}"); // after v3
VectorClock<String> v2 = VectorClock.fromString("{0=11, 1=16, 2=28, 3=17, 4=24, 5=15, 6=10, 7=8}");
VectorClock<String> v3 = VectorClock.fromString("{0=15, 1=19, 2=15, 3=20, 4=15, 5=22, 6=14, 7=19}"); // before v1

var s = new ArrayList<>(List.of(v1, v2, v3));
s.sort(VectorClock::compareTo);
assertTrue(s.indexOf(v3) < s.indexOf(v1));

Печатает (и терпит неудачу):

compare {0=11, 1=16, 2=28, 3=17, 4=24, 5=15, 6=10, 7=8} : {0=23, 1=28, 2=15, 3=23, 4=15, 5=22, 6=14, 7=19} => 1
compare {0=15, 1=19, 2=15, 3=20, 4=15, 5=22, 6=14, 7=19} : {0=11, 1=16, 2=28, 3=17, 4=24, 5=15, 6=10, 7=8} => 1

В чем основная причина этого? Это вообще невозможно или есть ошибка?

0 ответов

Другие вопросы по тегам