Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion core/stat/base/atomic_window_wrap_array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ func Test_atomicBucketWrapArray_elementOffset(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
now := uint64(1596199310000)
aa := NewAtomicBucketWrapArrayWithTime(tt.args.len, tt.args.bucketLengthInMs, now, tt.args.bg)
if got := uintptr(aa.elementOffset(tt.args.idx)) - uintptr(aa.base); got != tt.want {
offset, ok := aa.elementOffset(tt.args.idx)
assert.True(t, ok)
if got := uintptr(offset) - uintptr(aa.base); got != tt.want {
t.Errorf("AtomicBucketWrapArray.elementOffset() = %v, want %v \n", got, tt.want)
}
})
Expand Down
6 changes: 2 additions & 4 deletions core/stat/base/bucket_leap_array.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package base

import (
"fmt"
"sync/atomic"

"github.com/alibaba/sentinel-golang/core/base"
Expand Down Expand Up @@ -30,10 +29,9 @@ func (bla *BucketLeapArray) ResetBucketTo(bw *BucketWrap, startTime uint64) *Buc

// sampleCount is the number of slots
// intervalInMs is the time length of sliding window
// sampleCount and intervalInMs must be positive and intervalInMs%sampleCount == 0,
// the validation must be done before call NewBucketLeapArray
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about change the param to bucket span time and bucket count in future? Is it more easy to use?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is your meaning bucket count and bucketLengthMs?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could file another PR to enhance here

Copy link
Collaborator

@luckyxiaoqiang luckyxiaoqiang Oct 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a try, please add an issue and assign to me.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can submit a issue.

func NewBucketLeapArray(sampleCount uint32, intervalInMs uint32) *BucketLeapArray {
if intervalInMs%sampleCount != 0 {
panic(fmt.Sprintf("Invalid parameters, intervalInMs is %d, sampleCount is %d.", intervalInMs, sampleCount))
}
bucketLengthInMs := intervalInMs / sampleCount
ret := &BucketLeapArray{
data: LeapArray{
Expand Down
20 changes: 15 additions & 5 deletions core/stat/base/leap_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"unsafe"

"github.com/alibaba/sentinel-golang/core/base"
"github.com/alibaba/sentinel-golang/logging"
"github.com/alibaba/sentinel-golang/util"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -93,25 +94,34 @@ func NewAtomicBucketWrapArray(len int, bucketLengthInMs uint32, generator Bucket
return NewAtomicBucketWrapArrayWithTime(len, bucketLengthInMs, util.CurrentTimeMillis(), generator)
}

func (aa *AtomicBucketWrapArray) elementOffset(idx int) unsafe.Pointer {
func (aa *AtomicBucketWrapArray) elementOffset(idx int) (unsafe.Pointer, bool) {
if idx >= aa.length || idx < 0 {
panic(fmt.Sprintf("The index (%d) is out of bounds, length is %d.", idx, aa.length))
logging.Error(errors.New("array index out of bounds"),
"array index out of bounds in AtomicBucketWrapArray.elementOffset()",
"idx", idx, "arrayLength", aa.length)
return nil, false
}
basePtr := aa.base
return unsafe.Pointer(uintptr(basePtr) + uintptr(idx*PtrSize))
return unsafe.Pointer(uintptr(basePtr) + uintptr(idx*PtrSize)), true
}

func (aa *AtomicBucketWrapArray) get(idx int) *BucketWrap {
// aa.elementOffset(idx) return the secondary pointer of BucketWrap, which is the pointer to the aa.data[idx]
// then convert to (*unsafe.Pointer)
return (*BucketWrap)(atomic.LoadPointer((*unsafe.Pointer)(aa.elementOffset(idx))))
if offset, ok := aa.elementOffset(idx); ok {
return (*BucketWrap)(atomic.LoadPointer((*unsafe.Pointer)(offset)))
}
return nil
}

func (aa *AtomicBucketWrapArray) compareAndSet(idx int, except, update *BucketWrap) bool {
// aa.elementOffset(idx) return the secondary pointer of BucketWrap, which is the pointer to the aa.data[idx]
// then convert to (*unsafe.Pointer)
// update secondary pointer
return atomic.CompareAndSwapPointer((*unsafe.Pointer)(aa.elementOffset(idx)), unsafe.Pointer(except), unsafe.Pointer(update))
if offset, ok := aa.elementOffset(idx); ok {
return atomic.CompareAndSwapPointer((*unsafe.Pointer)(offset), unsafe.Pointer(except), unsafe.Pointer(update))
}
return false
}

// The BucketWrap leap array,
Expand Down
9 changes: 6 additions & 3 deletions core/stat/base/metric_bucket.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package base

import (
"fmt"
"sync/atomic"

"github.com/alibaba/sentinel-golang/core/base"
"github.com/alibaba/sentinel-golang/logging"
"github.com/pkg/errors"
)

// MetricBucket represents the entity to record metrics per minimum time unit (i.e. the bucket time span).
Expand All @@ -25,7 +26,8 @@ func NewMetricBucket() *MetricBucket {
// Add statistic count for the given metric event.
func (mb *MetricBucket) Add(event base.MetricEvent, count int64) {
if event >= base.MetricEventTotal || event < 0 {
panic(fmt.Sprintf("Unknown metric event: %v", event))
logging.Error(errors.Errorf("Unknown metric event: %v", event), "")
return
}
if event == base.MetricEventRt {
mb.AddRt(count)
Expand All @@ -41,7 +43,8 @@ func (mb *MetricBucket) addCount(event base.MetricEvent, count int64) {
// Get current statistic count of the given metric event.
func (mb *MetricBucket) Get(event base.MetricEvent) int64 {
if event >= base.MetricEventTotal || event < 0 {
panic(fmt.Sprintf("Unknown metric event: %v", event))
logging.Error(errors.Errorf("Unknown metric event: %v", event), "")
return 0
}
return atomic.LoadInt64(&mb.counter[event])
}
Expand Down