Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
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
13 changes: 8 additions & 5 deletions bytespool/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,18 @@ func AcquireWriterSize(out io.Writer, size int) *Writer {
}
}

func FlushReleaseWriter(w *Writer) error {
err := w.Flush()
if err != nil {
return err
}
func ReleaseWriter(w *Writer) {
Release(w.Buf)
w.Buf = nil
w.out = nil
writerPool.Put(w)
}

func FlushReleaseWriter(w *Writer) error {
if err := w.Flush(); err != nil {
return err
}
ReleaseWriter(w)
return nil
}

Expand Down
15 changes: 8 additions & 7 deletions cmd/distribution/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (

"github.com/ozontech/seq-db/cache"
"github.com/ozontech/seq-db/consts"
"github.com/ozontech/seq-db/frac"
"github.com/ozontech/seq-db/frac/common"
"github.com/ozontech/seq-db/frac/sealed"
"github.com/ozontech/seq-db/fracmanager"
"github.com/ozontech/seq-db/logger"
"github.com/ozontech/seq-db/seq"
Expand Down Expand Up @@ -58,7 +59,7 @@ func readBlock(reader storage.IndexReader, blockIndex uint32) ([]byte, error) {
return data, nil
}

func loadInfo(path string) *frac.Info {
func loadInfo(path string) *common.Info {
indexReader, f := getReader(path)
result, err := readBlock(indexReader, 0)
if err != nil {
Expand All @@ -69,7 +70,7 @@ func loadInfo(path string) *frac.Info {
logger.Fatal("seq-db index file header corrupted", zap.String("file", path))
}

b := frac.BlockInfo{}
b := sealed.BlockInfo{}
err = b.Unpack(result)
if err != nil {
logger.Fatal("can't unpack info bloc of index file", zap.String("file", path), zap.Error(err))
Expand All @@ -84,7 +85,7 @@ func loadInfo(path string) *frac.Info {
return b.Info
}

func buildDist(dist *seq.MIDsDistribution, path string, _ *frac.Info) {
func buildDist(dist *seq.MIDsDistribution, path string, _ *common.Info) {
blocksReader, _ := getReader(path)

// skip tokens
Expand Down Expand Up @@ -160,7 +161,7 @@ func main() {
}
}

fc := fracmanager.NewSealedFracCache(filePathDist)
fc := fracmanager.NewFracInfoCache(filePathDist)

lastSavedTime := time.Now()
for _, path := range getAllFracs(dataDir) {
Expand All @@ -169,7 +170,7 @@ func main() {

logger.Info("start process", zap.String("name", key))

info, ok := fc.GetFracInfo(key)
info, ok := fc.Get(key)
if ok {
logger.Info("found in frac-cache", zap.String("key", key))
} else {
Expand Down Expand Up @@ -197,7 +198,7 @@ func main() {
}

buildDist(info.Distribution, path, info)
fc.AddFraction(key, info)
fc.Add(info)
logger.Info("built distribution", zap.Int("affected_minutes", len(info.Distribution.GetDist())))
printDistribution(info.Distribution)

Expand Down
20 changes: 16 additions & 4 deletions cmd/index_analyzer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import (
"fmt"
"hash/fnv"
"os"
"sync"
"time"

"github.com/alecthomas/units"
"go.uber.org/zap"

"github.com/ozontech/seq-db/frac"
"github.com/ozontech/seq-db/frac/sealed"
"github.com/ozontech/seq-db/frac/sealed/lids"
"github.com/ozontech/seq-db/frac/sealed/token"
"github.com/ozontech/seq-db/fracmanager"
Expand Down Expand Up @@ -57,7 +58,15 @@ func main() {
func getCacheMaintainer() (*fracmanager.CacheMaintainer, func()) {
done := make(chan struct{})
cm := fracmanager.NewCacheMaintainer(uint64(units.GiB), uint64(units.MiB*64), nil)
wg := cm.RunCleanLoop(done, time.Second, time.Second)

wg := sync.WaitGroup{}

wg.Add(1)
go func() {
defer wg.Done()
cm.RunCleanLoop(done, time.Second, time.Second)
}()

return cm, func() {
close(done)
wg.Wait()
Expand Down Expand Up @@ -91,8 +100,11 @@ func analyzeIndex(
}

// load info
b := frac.BlockInfo{}
_ = b.Unpack(readBlock())
var b sealed.BlockInfo
if err := b.Unpack(readBlock()); err != nil {
logger.Fatal("error unpacking block info", zap.Error(err))
}

docsCount := int(b.Info.DocsTotal)

// load tokens
Expand Down
4 changes: 2 additions & 2 deletions cmd/seq-db/seq-db.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/ozontech/seq-db/config"
"github.com/ozontech/seq-db/consts"
"github.com/ozontech/seq-db/frac"
"github.com/ozontech/seq-db/frac/common"
"github.com/ozontech/seq-db/fracmanager"
"github.com/ozontech/seq-db/logger"
"github.com/ozontech/seq-db/mappingprovider"
Expand Down Expand Up @@ -250,11 +251,10 @@ func startStore(
CacheSize: uint64(cfg.Resources.CacheSize),
SortCacheSize: uint64(cfg.Resources.SortDocsCacheSize),
FracLoadLimit: 0,
ShouldReplay: true,
MaintenanceDelay: 0,
CacheGCDelay: 0,
CacheCleanupDelay: 0,
SealParams: frac.SealParams{
SealParams: common.SealParams{
IDsZstdLevel: cfg.Compression.SealedZstdCompressionLevel,
LIDsZstdLevel: cfg.Compression.SealedZstdCompressionLevel,
TokenListZstdLevel: cfg.Compression.SealedZstdCompressionLevel,
Expand Down
5 changes: 2 additions & 3 deletions consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ const (
// DummyMID is used in aggregations when we do not need to build time series.
DummyMID = 0

IDsBlockSize = int(4 * units.KiB)
RegularBlockSize = int(16 * units.KiB)
IDsPerBlock = int(4 * units.KiB)
LIDBlockCap = int(64 * units.KiB)
RegularBlockSize = int(16 * units.KiB)

DefaultMaintenanceDelay = time.Second
DefaultCacheGCDelay = 1 * time.Second
Expand Down Expand Up @@ -43,7 +42,7 @@ const (

MaxTextFieldValueLength = 32 * 1024

SealOnExitFracSizePercent = 20 // Percent of the max frac size, above which the fraction is sealed on exit
MinSealPercent = 20 // Percent of the max frac size, above which the fraction is sealed on exit

IngestorMaxInflightBulks = 32

Expand Down
69 changes: 15 additions & 54 deletions frac/active.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/ozontech/seq-db/cache"
"github.com/ozontech/seq-db/config"
"github.com/ozontech/seq-db/consts"
"github.com/ozontech/seq-db/frac/common"
"github.com/ozontech/seq-db/frac/processor"
"github.com/ozontech/seq-db/logger"
"github.com/ozontech/seq-db/metric"
"github.com/ozontech/seq-db/metric/stopwatch"
Expand All @@ -33,12 +35,8 @@ type Active struct {

BaseFileName string

useMu sync.RWMutex
suicided bool
released bool

infoMu sync.RWMutex
info *Info
info *common.Info

MIDs *UInt64s
RIDs *UInt64s
Expand Down Expand Up @@ -103,7 +101,7 @@ func NewActive(
writer: NewActiveWriter(docsFile, metaFile, docsStats.Size(), metaStats.Size(), config.SkipFsync),

BaseFileName: baseFileName,
info: NewInfo(baseFileName, uint64(docsStats.Size()), uint64(metaStats.Size())),
info: common.NewInfo(baseFileName, uint64(docsStats.Size()), uint64(metaStats.Size())),
Config: cfg,
}

Expand Down Expand Up @@ -265,23 +263,19 @@ func (f *Active) String() string {
return fracToString(f, "active")
}

func (f *Active) DataProvider(ctx context.Context) (DataProvider, func()) {
f.useMu.RLock()

if f.suicided || f.released || f.Info().DocsTotal == 0 { // it is empty active fraction state
if f.suicided {
metric.CountersTotal.WithLabelValues("fraction_suicided").Inc()
}
f.useMu.RUnlock()
return EmptyDataProvider{}, func() {}
func (f *Active) Fetch(ctx context.Context, ids []seq.ID) ([][]byte, error) {
if f.Info().DocsTotal == 0 { // it is empty active fraction state
return nil, nil
}
return f.createDataProvider(ctx).Fetch(ids)
}

// it is ordinary active fraction state
dp := f.createDataProvider(ctx)
return dp, func() {
dp.release()
f.useMu.RUnlock()
func (f *Active) Search(ctx context.Context, params processor.SearchParams) (*seq.QPR, error) {
if f.Info().DocsTotal == 0 { // it is empty active fraction state
metric.CountersTotal.WithLabelValues("empty_data_provider").Inc()
return &seq.QPR{Aggs: make([]seq.AggregatableSamples, len(params.AggQ))}, nil
}
return f.createDataProvider(ctx).Search(params)
}

func (f *Active) createDataProvider(ctx context.Context) *activeDataProvider {
Expand All @@ -300,7 +294,7 @@ func (f *Active) createDataProvider(ctx context.Context) *activeDataProvider {
}
}

func (f *Active) Info() *Info {
func (f *Active) Info() *common.Info {
f.infoMu.RLock()
defer f.infoMu.RUnlock()

Expand All @@ -317,10 +311,6 @@ func (f *Active) IsIntersecting(from, to seq.MID) bool {
}

func (f *Active) Release() {
f.useMu.Lock()
f.released = true
f.useMu.Unlock()

f.releaseMem()

if !f.Config.KeepMetaFile {
Expand All @@ -333,35 +323,6 @@ func (f *Active) Release() {
}
}

// Offload for [Active] fraction is no-op.
//
// Since search within [Active] fraction is too costly (we have to replay the whole index in memory),
// we decided to support offloading only for [Sealed] fractions.
func (f *Active) Offload(context.Context, storage.Uploader) (bool, error) {
return false, nil
}

func (f *Active) Suicide() {
f.useMu.Lock()
released := f.released
f.suicided = true
f.released = true
f.useMu.Unlock()

if released { // fraction can be suicided after release
if f.Config.KeepMetaFile {
f.removeMetaFile() // meta was not removed while release
}
if f.Config.SkipSortDocs {
f.removeDocsFiles() // docs was not removed while release
}
} else { // was not release
f.releaseMem()
f.removeMetaFile()
f.removeDocsFiles()
}
}

func (f *Active) releaseMem() {
f.writer.Stop()
f.TokenList.Stop()
Expand Down
33 changes: 23 additions & 10 deletions frac/active_docs_positions.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ import (
)

type DocsPositions struct {
mu sync.RWMutex
positions map[seq.ID]seq.DocPos
mu sync.RWMutex
idToPos map[seq.ID]seq.DocPos
lidToPos []seq.DocPos
}

func NewSyncDocsPositions() *DocsPositions {
return &DocsPositions{
positions: make(map[seq.ID]seq.DocPos),
dp := DocsPositions{
lidToPos: make([]seq.DocPos, 0),
idToPos: make(map[seq.ID]seq.DocPos),
}
dp.lidToPos = append(dp.lidToPos, 0) // systemID
return &dp
}

func (dp *DocsPositions) Get(id seq.ID) seq.DocPos {
if val, ok := dp.positions[id]; ok {
if val, ok := dp.idToPos[id]; ok {
return val
}
return seq.DocPosNotFound
Expand All @@ -36,13 +40,22 @@ func (dp *DocsPositions) SetMultiple(ids []seq.ID, pos []seq.DocPos) []seq.ID {
dp.mu.Lock()
defer dp.mu.Unlock()

appended := make([]seq.ID, 0)
appended := make([]seq.ID, 0, len(ids))
for i, id := range ids {
// Positions may be equal in case of nested index.
if savedPos, ok := dp.positions[id]; !ok || savedPos == pos[i] {
dp.positions[id] = pos[i]
appended = append(appended, id)
p, ok := dp.idToPos[id]

if ok {
if p != pos[i] {
// same ID but different position
// this is a duplicate ID, we can't append it
continue
}
} else {
dp.idToPos[id] = pos[i]
}

dp.lidToPos = append(dp.lidToPos, pos[i])
appended = append(appended, id)
}
return appended
}
3 changes: 2 additions & 1 deletion frac/active_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

"github.com/ozontech/seq-db/frac/common"
"github.com/ozontech/seq-db/frac/processor"
"github.com/ozontech/seq-db/frac/sealed/lids"
"github.com/ozontech/seq-db/metric"
Expand Down Expand Up @@ -47,7 +48,7 @@ var (
type activeDataProvider struct {
ctx context.Context
config *Config
info *Info
info *common.Info

mids *UInt64s
rids *UInt64s
Expand Down
Loading