Files
upstream-bleve/index/scorch/merge_test.go
upstream-mirror f8d3d9f0cf
Some checks failed
Coverage / coverage (push) Failing after 6s
Tests / test (1.24.x, ubuntu-latest) (push) Failing after 42s
Tests / test (1.26.x, ubuntu-latest) (push) Failing after 38s
Tests / test (1.25.x, ubuntu-latest) (push) Failing after 35s
Tests / test (1.25.x, windows-latest) (push) Has been cancelled
Tests / test (1.26.x, macos-latest) (push) Has been cancelled
Tests / test (1.26.x, windows-latest) (push) Has been cancelled
Tests / test (1.24.x, macos-latest) (push) Has been cancelled
Tests / test (1.24.x, windows-latest) (push) Has been cancelled
Tests / test (1.25.x, macos-latest) (push) Has been cancelled
snapshot of https://github.com/blevesearch/bleve.git (master, 2026-09-15; blobs > 131072B omitted)
2026-09-15 22:27:16 +05:00

158 lines
4.0 KiB
Go

// Copyright (c) 2020 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package scorch
import (
"sync"
"sync/atomic"
"testing"
"github.com/blevesearch/bleve/v2/document"
index "github.com/blevesearch/bleve_index_api"
)
func TestObsoleteSegmentMergeIntroduction(t *testing.T) {
testConfig := CreateConfig("TestObsoleteSegmentMergeIntroduction")
err := InitTest(testConfig)
if err != nil {
t.Fatal(err)
}
defer func() {
err := DestroyTest(testConfig)
if err != nil {
t.Fatal(err)
}
}()
var introComplete, mergeIntroStart, mergeIntroComplete sync.WaitGroup
introComplete.Add(1)
mergeIntroStart.Add(1)
mergeIntroComplete.Add(1)
var segIntroCompleted int
RegistryEventCallbacks["test"] = func(e Event) bool {
switch e.Kind {
case EventKindBatchIntroduction:
segIntroCompleted++
if segIntroCompleted == 3 {
// all 3 segments introduced
introComplete.Done()
}
case EventKindMergeTaskIntroductionStart:
// signal the start of merge task introduction so that
// we can introduce a new batch which obsoletes the
// merged segment's contents.
mergeIntroStart.Done()
// hold the merge task introduction until the merged segment contents
// are obsoleted with the next batch/segment introduction.
introComplete.Wait()
case EventKindMergeTaskIntroduction:
// signal the completion of the merge task introduction.
mergeIntroComplete.Done()
}
return true
}
ourConfig := make(map[string]interface{}, len(testConfig))
for k, v := range testConfig {
ourConfig[k] = v
}
ourConfig["eventCallbackName"] = "test"
analysisQueue := index.NewAnalysisQueue(1)
idx, err := NewScorch(Name, ourConfig, analysisQueue)
if err != nil {
t.Fatal(err)
}
err = idx.Open()
if err != nil {
t.Fatalf("error opening index: %v", err)
}
defer func() {
err := idx.Close()
if err != nil {
t.Fatal(err)
}
}()
// first introduce two documents over two batches.
batch := index.NewBatch()
doc := document.NewDocument("1")
doc.AddField(document.NewTextField("name", []uint64{}, []byte("test3")))
batch.Update(doc)
err = idx.Batch(batch)
if err != nil {
t.Error(err)
}
batch.Reset()
doc = document.NewDocument("2")
doc.AddField(document.NewTextField("name", []uint64{}, []byte("test2updated")))
batch.Update(doc)
err = idx.Batch(batch)
if err != nil {
t.Error(err)
}
// wait until the merger trying to introduce the new merged segment.
mergeIntroStart.Wait()
// execute another batch which obsoletes the contents of the new merged
// segment awaiting introduction.
batch.Reset()
batch.Delete("1")
batch.Delete("2")
doc = document.NewDocument("3")
doc.AddField(document.NewTextField("name", []uint64{}, []byte("test3updated")))
batch.Update(doc)
err = idx.Batch(batch)
if err != nil {
t.Error(err)
}
// wait until the merge task introduction complete.
mergeIntroComplete.Wait()
idxr, err := idx.Reader()
if err != nil {
t.Error(err)
}
numSegments := len(idxr.(*IndexSnapshot).segment)
if numSegments != 1 {
t.Errorf("expected one segment at the root, got: %d", numSegments)
}
skipIntroCount := atomic.LoadUint64(&idxr.(*IndexSnapshot).parent.stats.TotFileMergeIntroductionsObsoleted)
if skipIntroCount != 1 {
t.Errorf("expected one obsolete merge segment skipping the introduction, got: %d", skipIntroCount)
}
docCount, err := idxr.DocCount()
if err != nil {
t.Fatal(err)
}
if docCount != 1 {
t.Errorf("Expected document count to be %d got %d", 1, docCount)
}
err = idxr.Close()
if err != nil {
t.Fatal(err)
}
}