From f74c90da9c81f2030698346c4b4bbc1af3dc2df8 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 13 Oct 2017 22:30:44 +0200 Subject: checkAndSet works now in any case --- satp/sequence-window.go | 24 ++++++++++++++++++++---- satp/sequence-window_test.go | 11 +++++++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/satp/sequence-window.go b/satp/sequence-window.go index f529231..9fa4385 100644 --- a/satp/sequence-window.go +++ b/satp/sequence-window.go @@ -139,7 +139,23 @@ func (w *SequenceWindow) checkAndSet(sequenceNumber uint32) bool { } func (w *SequenceWindow) advanceTop(newTop uint32) { - // TODO: implement this + oldIdx := int(w.top() / 32) + newIdx := int(newTop / 32) + diff := newIdx - oldIdx + if oldIdx > newIdx { + diff = oldIdx - newIdx + } + oldHeadSlice := uint32(w.head) + w.head = uint64(newTop) << 32 + for i := len(w.body) - 1; i >= 0; i-- { + if i < (diff - 1) { + w.body[i] = 0 + } else if i < diff { + w.body[i] = oldHeadSlice + } else { + w.body[i] = w.body[i-diff] + } + } } func (w *SequenceWindow) top() uint32 { @@ -182,10 +198,10 @@ func (w *SequenceWindow) CheckAndSet(sequenceNumber uint32) bool { if lt && d > uint32(w.size) { return false } - if lt || top/32 == sequenceNumber/32 { - return w.checkAndSet(sequenceNumber) + if lt || top/32 == (sequenceNumber+1)/32 { + result := w.checkAndSet(sequenceNumber) + return result } - // TODO: only now we would need the writers lock w.advanceTop(sequenceNumber + 1) return w.checkAndSet(sequenceNumber) diff --git a/satp/sequence-window_test.go b/satp/sequence-window_test.go index 91211cd..41ee713 100644 --- a/satp/sequence-window_test.go +++ b/satp/sequence-window_test.go @@ -196,12 +196,18 @@ func TestSequenceWindowCheckAndSet(t *testing.T) { }{ {0, 0, []uint32{0, 1, 2, 3, 4}, true}, {0, 0, []uint32{^uint32(0)}, true}, + {1, 0, []uint32{0}, true}, {10, 0, []uint32{^uint32(0)}, false}, - {10, 20, []uint32{^uint32(0), 5, 9, 10}, false}, + {10, 20, []uint32{^uint32(0), 5, 9, 10, 12, 13}, false}, + {10, 20, []uint32{20, 23, 31, 32, 35}, true}, {32, 0, []uint32{0, 1, 2, 3, 4}, true}, {32, 10, []uint32{0, 1, 2, 3, 4}, false}, {32, 10, []uint32{10, 11, 12, 13, 14}, true}, {32, 0, []uint32{10, 17, 23, 0, 1, 18, 9, 8, 31}, true}, + {32, 30, []uint32{30, 31, 32, 33, 34}, true}, + {32, 0, []uint32{95, 100, 96, 97, 99, 98}, true}, + {50, 0, []uint32{31, 32, 35, 33, 34, 64}, true}, + {30, ^uint32(0) - 10, []uint32{0, 1, 2, 3, ^uint32(0), ^uint32(0) - 2}, true}, } for _, vector := range testvectors { @@ -209,12 +215,13 @@ func TestSequenceWindowCheckAndSet(t *testing.T) { if err != nil { t.Fatal("unexpected error:", err) } + t.Logf("--------------, %v", w) for _, seq := range vector.seqs { result := w.CheckAndSet(seq) if result != vector.result { t.Fatalf("check-and-set %d on %s returned %v but should be %v", seq, w, result, vector.result) } - t.Log(w) + t.Logf("chk %10d, %v", seq, w) } } } -- cgit v1.2.3