github.com/m3db/m3@v1.5.0/src/dbnode/storage/index/for_each_test.go (about)

     1  // Copyright (c) 2018 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package index
    22  
    23  import (
    24  	"fmt"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/golang/mock/gomock"
    29  	"github.com/stretchr/testify/require"
    30  
    31  	"github.com/m3db/m3/src/m3ninx/doc"
    32  	xtime "github.com/m3db/m3/src/x/time"
    33  )
    34  
    35  func TestWriteBatchForEachUnmarkedBatchByBlockStart(t *testing.T) {
    36  	ctrl := gomock.NewController(t)
    37  	defer ctrl.Finish()
    38  
    39  	blockSize := time.Hour
    40  	now := xtime.Now().Truncate(blockSize)
    41  	tn := func(n int64) xtime.UnixNano {
    42  		nDur := time.Duration(n)
    43  		return now.Add(nDur * blockSize).Add(nDur * time.Minute)
    44  	}
    45  	d := func(n int64) doc.Metadata {
    46  		return doc.Metadata{
    47  			ID: []byte(fmt.Sprintf("doc-%d", n)),
    48  		}
    49  	}
    50  	batch := NewWriteBatch(WriteBatchOptions{
    51  		IndexBlockSize: blockSize,
    52  	})
    53  	for _, n := range []int64{2, 0, 1} {
    54  		batch.Append(WriteBatchEntry{
    55  			Timestamp:     tn(n),
    56  			OnIndexSeries: doc.NewMockOnIndexSeries(ctrl),
    57  		}, d(n))
    58  	}
    59  
    60  	numCalls := 0
    61  	// entries.ForEachBlockStart(func(ts xtime.UnixNano, writes []WriteBatchEntry) {
    62  	batch.ForEachUnmarkedBatchByBlockStart(func(
    63  		blockStart xtime.UnixNano,
    64  		batch *WriteBatch,
    65  	) {
    66  		require.Equal(t, 1, batch.Len())
    67  		switch numCalls {
    68  		case 0:
    69  			require.Equal(t, "doc-0", string(batch.PendingDocs()[0].ID))
    70  		case 1:
    71  			require.Equal(t, "doc-1", string(batch.PendingDocs()[0].ID))
    72  		case 2:
    73  			require.Equal(t, "doc-2", string(batch.PendingDocs()[0].ID))
    74  		default:
    75  			require.FailNow(t, "should never get here")
    76  		}
    77  		numCalls++
    78  	})
    79  	require.Equal(t, 3, numCalls)
    80  }
    81  
    82  func TestWriteBatchForEachUnmarkedBatchByBlockStartMore(t *testing.T) {
    83  	ctrl := gomock.NewController(t)
    84  	defer ctrl.Finish()
    85  
    86  	blockSize := time.Hour
    87  	now := xtime.Now().Truncate(blockSize)
    88  	tn := func(n int64) xtime.UnixNano {
    89  		nDur := time.Duration(n)
    90  		return now.Add(nDur * blockSize).Add(nDur * time.Minute)
    91  	}
    92  	d := func(n int64) doc.Metadata {
    93  		return doc.Metadata{
    94  			ID: []byte(fmt.Sprintf("doc-%d", n)),
    95  		}
    96  	}
    97  	batch := NewWriteBatch(WriteBatchOptions{
    98  		IndexBlockSize: blockSize,
    99  	})
   100  	for _, v := range []struct {
   101  		nTime int64
   102  		nDoc  int64
   103  	}{
   104  		{0, 0},
   105  		{1, 3},
   106  		{0, 1},
   107  		{1, 4},
   108  		{0, 2},
   109  	} {
   110  		batch.Append(WriteBatchEntry{
   111  			Timestamp:     tn(v.nTime),
   112  			OnIndexSeries: doc.NewMockOnIndexSeries(ctrl),
   113  		}, d(v.nDoc))
   114  	}
   115  
   116  	numCalls := 0
   117  	batch.ForEachUnmarkedBatchByBlockStart(func(
   118  		blockStart xtime.UnixNano,
   119  		batch *WriteBatch,
   120  	) {
   121  		switch numCalls {
   122  		case 0:
   123  			require.Equal(t, 3, batch.Len())
   124  			require.Equal(t, "doc-0", string(batch.PendingDocs()[0].ID))
   125  			require.Equal(t, "doc-1", string(batch.PendingDocs()[1].ID))
   126  			require.Equal(t, "doc-2", string(batch.PendingDocs()[2].ID))
   127  		case 1:
   128  			require.Equal(t, 2, batch.Len())
   129  			require.Equal(t, "doc-3", string(batch.PendingDocs()[0].ID))
   130  			require.Equal(t, "doc-4", string(batch.PendingDocs()[1].ID))
   131  		default:
   132  			require.FailNow(t, "should never get here")
   133  		}
   134  		numCalls++
   135  	})
   136  	require.Equal(t, 2, numCalls)
   137  }