summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2017-09-19 21:10:24 +0200
committerChristian Pointner <equinox@anytun.org>2017-09-19 21:10:24 +0200
commite29eb0041f8ad3984122207c3a4f8203d440ea6c (patch)
treef66210d479d1508714cf1ec3aca633b35a04abeb
parentrefactored role and direction (diff)
sequence window partially implemented
-rw-r--r--satp/sequence-window.go39
-rw-r--r--satp/sequence-window_test.go90
2 files changed, 125 insertions, 4 deletions
diff --git a/satp/sequence-window.go b/satp/sequence-window.go
index c74ca62..94a7b0b 100644
--- a/satp/sequence-window.go
+++ b/satp/sequence-window.go
@@ -32,23 +32,43 @@ package satp
import (
"errors"
+ "sync"
+ "sync/atomic"
)
type SequenceWindow struct {
- size int
+ size int
+ head uint64
+ body []uint32
+ mutex *sync.RWMutex
+}
+
+func (w *SequenceWindow) Size() int {
+ return w.size
+}
+
+func (w *SequenceWindow) Top() uint32 {
+ if w.size > 0 {
+ w.mutex.RLock()
+ defer w.mutex.RUnlock()
+ }
+ v := atomic.LoadUint64(&w.head)
+ return uint32(v >> 32)
}
func (w *SequenceWindow) Check(sequenceNumber uint32) (bool, error) {
- if w.size == 0 {
+ if w.size <= 0 {
return false, nil
}
+ // TODO: implement this
return false, nil
}
func (w *SequenceWindow) CheckAndSet(sequenceNumber uint32) (bool, error) {
- if w.size == 0 {
+ if w.size <= 0 {
return false, nil
}
+ // TODO: implement this
return false, nil
}
@@ -56,6 +76,17 @@ func NewSequenceWindow(size int) (w *SequenceWindow, err error) {
if size < 0 {
return nil, errors.New("invalid sequence window size")
}
- w = &SequenceWindow{size: size}
+ w = &SequenceWindow{size: size, head: 0}
+ if w.size > 0 {
+ bodyLen := (w.size / 32)
+ if (w.size % 32) != 0 {
+ bodyLen++
+ }
+ w.body = make([]uint32, bodyLen, bodyLen)
+ for i := range w.body {
+ w.body[i] = 0
+ }
+ w.mutex = &sync.RWMutex{}
+ }
return
}
diff --git a/satp/sequence-window_test.go b/satp/sequence-window_test.go
new file mode 100644
index 0000000..4fc244a
--- /dev/null
+++ b/satp/sequence-window_test.go
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2017 anygone contributors (see AUTHORS file)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of anygone nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+package satp
+
+import (
+ "testing"
+)
+
+func TestSequenceWindowNew(t *testing.T) {
+ testvectors := []struct {
+ size int
+ bodyLen int
+ valid bool
+ }{
+ {-1, 0, false},
+ {0, 0, true},
+ {1, 1, true},
+ {10, 1, true},
+ {32, 1, true},
+ {33, 2, true},
+ {63, 2, true},
+ {64, 2, true},
+ {65, 3, true},
+ {100, 4, true},
+ }
+
+ for _, vector := range testvectors {
+ w, err := NewSequenceWindow(vector.size)
+ if vector.valid {
+ if err != nil {
+ t.Fatal("unexpected error:", err)
+ }
+ if w.Size() != vector.size {
+ t.Fatalf("sequence-window has wrong size, is: %d, should be %d", w.Size(), vector.size)
+ }
+ if w.Top() != 0 {
+ t.Fatalf("sequence-window(%d) top value not 0: 0x%08X", vector.size, w.Top())
+ }
+ if w.head != 0 {
+ t.Fatalf("sequence-window(%d) head not 0: 0x%16X", vector.size, w.head)
+ }
+ bodyLen := len(w.body)
+ if bodyLen != vector.bodyLen {
+ t.Fatalf("sequence-window(%d) body length has invalid length, is: %d, should be %d", vector.size, bodyLen, vector.bodyLen)
+ }
+ isEmpty := true
+ for _, v := range w.body {
+ if v != 0 {
+ isEmpty = false
+ }
+ }
+ if !isEmpty {
+ t.Fatalf("sequence-window(%d) body not empty, is: %v", vector.size, w.body)
+ }
+ } else {
+ if err == nil {
+ t.Fatalf("creating sequence-window(%d) should give an error", vector.size)
+ }
+ }
+ }
+
+}