storj/satellite/audit/reservoir.go
Egon Elbre 267506bb20 satellite/metabase: move package one level higher
metabase has become a central concept and it's more suitable for it to
be directly nested under satellite rather than being part of metainfo.

metainfo is going to be the "endpoint" logic for handling requests.

Change-Id: I53770d6761ac1e9a1283b5aa68f471b21e784198
2021-04-21 15:54:22 +03:00

71 lines
1.7 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package audit
import (
"math/rand"
"time"
"storj.io/common/uuid"
"storj.io/storj/satellite/metabase"
"storj.io/storj/satellite/metainfo/metaloop"
)
const maxReservoirSize = 3
// Reservoir holds a certain number of segments to reflect a random sample.
type Reservoir struct {
Segments [maxReservoirSize]Segment
size int8
index int64
}
// NewReservoir instantiates a Reservoir.
func NewReservoir(size int) *Reservoir {
if size < 1 {
size = 1
} else if size > maxReservoirSize {
size = maxReservoirSize
}
return &Reservoir{
size: int8(size),
index: 0,
}
}
// Sample makes sure that for every segment in metainfo from index i=size..n-1,
// pick a random number r = rand(0..i), and if r < size, replace reservoir.Segments[r] with segment.
func (reservoir *Reservoir) Sample(r *rand.Rand, segment Segment) {
reservoir.index++
if reservoir.index < int64(reservoir.size) {
reservoir.Segments[reservoir.index] = segment
} else {
random := r.Int63n(reservoir.index)
if random < int64(reservoir.size) {
reservoir.Segments[random] = segment
}
}
}
// Segment is a segment to audit.
type Segment struct {
metabase.SegmentLocation
StreamID uuid.UUID
ExpirationDate time.Time
}
// NewSegment creates a new segment to audit from a metainfo loop segment.
func NewSegment(loopSegment *metaloop.Segment) Segment {
return Segment{
SegmentLocation: loopSegment.Location,
StreamID: loopSegment.StreamID,
ExpirationDate: loopSegment.ExpirationDate,
}
}
// Expired checks if segment is expired relative to now.
func (segment *Segment) Expired(now time.Time) bool {
return !segment.ExpirationDate.IsZero() && segment.ExpirationDate.Before(now)
}