@@ -26,15 +26,16 @@ import (
2626 "github.com/pkg/errors"
2727)
2828
29- // BucketWrap represent a slot to record metrics
30- // In order to reduce the usage of memory, BucketWrap don't hold length of BucketWrap
29+ // BucketWrap represents a slot to record metrics.
30+ //
31+ // In order to reduce memory footprint, BucketWrap does not hold the length of the bucket.
3132// The length of BucketWrap could be seen in LeapArray.
32- // The scope of time is [startTime, startTime+bucketLength)
33- // The size of BucketWrap is 24(8+16) bytes
33+ // The scope of time is [startTime, startTime+bucketLength).
34+ // The size of BucketWrap is 24(8+16) bytes.
3435type BucketWrap struct {
35- // The start timestamp of this statistic bucket wrapper.
36+ // BucketStart represents start timestamp of this statistic bucket wrapper.
3637 BucketStart uint64
37- // The actual data structure to record the metrics (e.g. MetricBucket).
38+ // Value represents the actual data structure of the metrics (e.g. MetricBucket).
3839 Value atomic.Value
3940}
4041
@@ -50,8 +51,9 @@ func calculateStartTime(now uint64, bucketLengthInMs uint32) uint64 {
5051 return now - (now % uint64 (bucketLengthInMs ))
5152}
5253
53- // atomic BucketWrap array to resolve race condition
54- // AtomicBucketWrapArray can not append or delete element after initializing
54+ // AtomicBucketWrapArray represents a thread-safe circular array.
55+ //
56+ // The length of the array should be provided on-create and cannot be modified.
5557type AtomicBucketWrapArray struct {
5658 // The base address for real data array
5759 base unsafe.Pointer
@@ -94,11 +96,11 @@ func NewAtomicBucketWrapArrayWithTime(len int, bucketLengthInMs uint32, now uint
9496 return ret
9597}
9698
97- // New AtomicBucketWrapArray with initializing field data
98- // Default, automatically initialize each BucketWrap
99- // len: length of array
100- // bucketLengthInMs: bucket length of BucketWrap
101- // generator: generator to generate bucket
99+ // NewAtomicBucketWrapArray creates an AtomicBucketWrapArray and initializes data of each BucketWrap.
100+ //
101+ // The len represents the length of the circular array.
102+ // The bucketLengthInMs represents bucket length of each bucket (in milliseconds).
103+ // The generator accepts a BucketGenerator to generate and refresh buckets.
102104func NewAtomicBucketWrapArray (len int , bucketLengthInMs uint32 , generator BucketGenerator ) * AtomicBucketWrapArray {
103105 return NewAtomicBucketWrapArrayWithTime (len , bucketLengthInMs , util .CurrentTimeMillis (), generator )
104106}
@@ -133,23 +135,30 @@ func (aa *AtomicBucketWrapArray) compareAndSet(idx int, except, update *BucketWr
133135 return false
134136}
135137
136- // The BucketWrap leap array,
137- // sampleCount represent the number of BucketWrap
138- // intervalInMs represent the interval of LeapArray.
139- // For example, bucketLengthInMs is 200ms, intervalInMs is 1000ms, so sampleCount is 5.
140- // Give a diagram to illustrate
141- // Suppose current time is 888, bucketLengthInMs is 200ms, intervalInMs is 1000ms, LeapArray will build the below windows
138+ // LeapArray represents the fundamental implementation of a sliding window data-structure.
139+ //
140+ // Some important attributes: the sampleCount represents the number of buckets,
141+ // while intervalInMs represents the total time span of the sliding window.
142+ //
143+ // For example, assuming sampleCount=5, intervalInMs is 1000ms, so the bucketLength is 200ms.
144+ // Let's give a diagram to illustrate.
145+ // Suppose current timestamp is 1188, bucketLength is 200ms, intervalInMs is 1000ms, then
146+ // time span of current bucket is [1000, 1200). The representation of the underlying structure:
147+ //
142148// B0 B1 B2 B3 B4
143149// |_______|_______|_______|_______|_______|
144- // 1000 1200 1400 1600 800 (1000)
145- // ^
146- // time=888
150+ // 1000 1200 400 600 800 (1000) ms
151+ // ^
152+ // time=1188
147153type LeapArray struct {
148154 bucketLengthInMs uint32
149- sampleCount uint32
150- intervalInMs uint32
151- array * AtomicBucketWrapArray
152- // update lock
155+ // sampleCount represents the number of BucketWrap.
156+ sampleCount uint32
157+ // intervalInMs represents the total time span of the sliding window (in milliseconds).
158+ intervalInMs uint32
159+ // array represents the internal circular array.
160+ array * AtomicBucketWrapArray
161+ // updateLock is the internal lock for update operations.
153162 updateLock mutex
154163}
155164
@@ -224,7 +233,8 @@ func (la *LeapArray) calculateTimeIdx(now uint64) int {
224233 return int (timeId ) % la .array .length
225234}
226235
227- // Get all BucketWrap between [current time - leap array interval, current time]
236+ // Values returns all valid (non-expired) buckets between [curBucketEnd-windowInterval, curBucketEnd],
237+ // where curBucketEnd=curBucketStart+bucketLength.
228238func (la * LeapArray ) Values () []* BucketWrap {
229239 return la .valuesWithTime (util .CurrentTimeMillis ())
230240}
@@ -244,6 +254,8 @@ func (la *LeapArray) valuesWithTime(now uint64) []*BucketWrap {
244254 return ret
245255}
246256
257+ // ValuesConditional returns all buckets of which the startTimestamp satisfies the given timestamp condition (predicate).
258+ // The function uses the parameter "now" as the target timestamp.
247259func (la * LeapArray ) ValuesConditional (now uint64 , predicate base.TimePredicate ) []* BucketWrap {
248260 if now <= 0 {
249261 return make ([]* BucketWrap , 0 )
@@ -259,17 +271,17 @@ func (la *LeapArray) ValuesConditional(now uint64, predicate base.TimePredicate)
259271 return ret
260272}
261273
262- // Judge whether the BucketWrap is expired
274+ // isBucketDeprecated checks whether the BucketWrap is expired, according to given timestamp.
263275func (la * LeapArray ) isBucketDeprecated (now uint64 , ww * BucketWrap ) bool {
264276 ws := atomic .LoadUint64 (& ww .BucketStart )
265277 return (now - ws ) > uint64 (la .intervalInMs )
266278}
267279
268- // Generic interface to generate bucket
280+ // BucketGenerator represents the "generic" interface for generating and refreshing buckets.
269281type BucketGenerator interface {
270- // called when timestamp entry a new slot interval
282+ // NewEmptyBucket creates new raw data inside the bucket.
271283 NewEmptyBucket () interface {}
272284
273- // reset the BucketWrap, clear all data of BucketWrap
274- ResetBucketTo (bw * BucketWrap , startTime uint64 ) * BucketWrap
285+ // ResetBucketTo refreshes the BucketWrap to provided startTime and resets all data inside the given bucket.
286+ ResetBucketTo (bucket * BucketWrap , startTime uint64 ) * BucketWrap
275287}
0 commit comments