github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/manifest_test.go (about)

     1  // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package bitpage
    16  
    17  import (
    18  	"os"
    19  	"testing"
    20  
    21  	"github.com/stretchr/testify/require"
    22  )
    23  
    24  func TestManifest_Open(t *testing.T) {
    25  	testInitDir()
    26  	defer os.RemoveAll(testDir)
    27  
    28  	opts := testInitOpts()
    29  	bpage := &Bitpage{
    30  		dirname: testDir,
    31  		opts:    opts,
    32  	}
    33  	require.NoError(t, openManifest(bpage))
    34  
    35  	freelistNum := pageMetadataNum
    36  	require.Equal(t, freelistNum, bpage.meta.getPagesFreelistLen())
    37  
    38  	for i := 1; i <= 100; i++ {
    39  		pageNum := bpage.meta.getNextPageNum()
    40  		bpage.meta.newPagemetaItem(pageNum)
    41  	}
    42  	require.Equal(t, PageNum(100), bpage.meta.getCurrentPageNum())
    43  
    44  	freelistNum -= 100
    45  	require.Equal(t, freelistNum, bpage.meta.getPagesFreelistLen())
    46  	require.Equal(t, 100, len(bpage.meta.mu.pagemetaMap))
    47  
    48  	num := 10
    49  
    50  	for pageNum, pmItem := range bpage.meta.mu.pagemetaMap {
    51  		require.Equal(t, pageNum, pmItem.pageNum)
    52  		require.Equal(t, FileNum(1), pmItem.nextStFileNum)
    53  		require.Equal(t, FileNum(0), pmItem.curAtFileNum)
    54  		require.Equal(t, FileNum(1), pmItem.minUnflushedStFileNum)
    55  		require.Equal(t, uint8(0), pmItem.splitState)
    56  		for j := 0; j < num; j++ {
    57  			fn := bpage.meta.getNextStFileNum(pageNum)
    58  			require.Equal(t, pmItem.nextStFileNum, fn+FileNum(1))
    59  		}
    60  		for j := 0; j < num; j++ {
    61  			fn := bpage.meta.getNextAtFileNum(pageNum)
    62  			require.Equal(t, pmItem.curAtFileNum+FileNum(1), fn)
    63  			bpage.meta.setNextArrayTableFileNum(pageNum)
    64  		}
    65  		bpage.meta.setSplitState(pageNum, 1)
    66  	}
    67  
    68  	for i := 1; i <= 10; i++ {
    69  		pn := PageNum(i)
    70  		bpage.meta.freePagemetaItem(pn)
    71  		require.Equal(t, (*pagemetaItem)(nil), bpage.meta.getPagemetaItem(pn))
    72  	}
    73  
    74  	freelistNum += 10
    75  	require.Equal(t, freelistNum, bpage.meta.getPagesFreelistLen())
    76  
    77  	require.NoError(t, bpage.meta.close())
    78  
    79  	require.NoError(t, openManifest(bpage))
    80  	require.Equal(t, freelistNum, bpage.meta.getPagesFreelistLen())
    81  	require.Equal(t, PageNum(100), bpage.meta.getCurrentPageNum())
    82  	for i := 11; i <= 100; i++ {
    83  		pageNum := PageNum(i)
    84  		pmItem := bpage.meta.getPagemetaItem(pageNum)
    85  		require.Equal(t, pageNum, pmItem.pageNum)
    86  		require.Equal(t, FileNum(num+1), pmItem.nextStFileNum)
    87  		require.Equal(t, FileNum(num), pmItem.curAtFileNum)
    88  		require.Equal(t, uint8(1), pmItem.splitState)
    89  		for j := 0; j < num; j++ {
    90  			fn := bpage.meta.getNextStFileNum(pageNum)
    91  			require.Equal(t, pmItem.nextStFileNum, fn+FileNum(1))
    92  		}
    93  		for j := 0; j < num; j++ {
    94  			fn := bpage.meta.getNextAtFileNum(pageNum)
    95  			require.Equal(t, pmItem.curAtFileNum+FileNum(1), fn)
    96  			bpage.meta.setNextArrayTableFileNum(pageNum)
    97  		}
    98  	}
    99  
   100  	for i := 1; i <= 100; i++ {
   101  		pageNum := bpage.meta.getNextPageNum()
   102  		bpage.meta.newPagemetaItem(pageNum)
   103  	}
   104  	require.Equal(t, PageNum(200), bpage.meta.getCurrentPageNum())
   105  	for i := 101; i <= 200; i++ {
   106  		pageNum := PageNum(i)
   107  		pmItem := bpage.meta.getPagemetaItem(pageNum)
   108  		require.Equal(t, pageNum, pmItem.pageNum)
   109  		require.Equal(t, FileNum(1), pmItem.nextStFileNum)
   110  		require.Equal(t, FileNum(0), pmItem.curAtFileNum)
   111  		require.Equal(t, FileNum(1), pmItem.minUnflushedStFileNum)
   112  		require.Equal(t, uint8(0), pmItem.splitState)
   113  		bpage.meta.setSplitState(pageNum, 2)
   114  		for j := 0; j < num; j++ {
   115  			fn := bpage.meta.getNextStFileNum(pageNum)
   116  			require.Equal(t, pmItem.nextStFileNum, fn+FileNum(1))
   117  		}
   118  		for j := 0; j < num; j++ {
   119  			fn := bpage.meta.getNextAtFileNum(pageNum)
   120  			require.Equal(t, pmItem.curAtFileNum+FileNum(1), fn)
   121  			bpage.meta.setNextArrayTableFileNum(pageNum)
   122  		}
   123  		require.Equal(t, uint8(2), bpage.meta.getSplitState(pageNum))
   124  	}
   125  }
   126  
   127  func TestManifest_Write(t *testing.T) {
   128  	testInitDir()
   129  	defer os.RemoveAll(testDir)
   130  
   131  	opts := testInitOpts()
   132  	bpage := &Bitpage{
   133  		dirname: testDir,
   134  		opts:    opts,
   135  	}
   136  
   137  	writeMeta := func(index int) {
   138  		require.NoError(t, openManifest(bpage))
   139  		defer func() {
   140  			require.NoError(t, bpage.meta.close())
   141  		}()
   142  
   143  		start := (index - 1) * 100
   144  		end := start + 100
   145  		for i := start + 1; i <= end; i++ {
   146  			pageNum := bpage.meta.getNextPageNum()
   147  			pmItem := bpage.meta.newPagemetaItem(pageNum)
   148  			for j := 0; j < 10; j++ {
   149  				fn := bpage.meta.getNextStFileNum(pageNum)
   150  				require.Equal(t, pmItem.nextStFileNum, fn+FileNum(1))
   151  			}
   152  			for j := 0; j < 10; j++ {
   153  				fn := bpage.meta.getNextAtFileNum(pageNum)
   154  				require.Equal(t, pmItem.curAtFileNum+FileNum(1), fn)
   155  				bpage.meta.setNextArrayTableFileNum(pageNum)
   156  			}
   157  			require.Equal(t, uint8(0), pmItem.splitState)
   158  			bpage.meta.setSplitState(pageNum, 2)
   159  		}
   160  		require.Equal(t, PageNum(index*100), bpage.meta.getCurrentPageNum())
   161  		require.Equal(t, index*100, len(bpage.meta.mu.pagemetaMap))
   162  	}
   163  
   164  	for i := 1; i <= 100; i++ {
   165  		writeMeta(i)
   166  	}
   167  
   168  	require.NoError(t, openManifest(bpage))
   169  	require.Equal(t, PageNum(100*100), bpage.meta.getCurrentPageNum())
   170  	require.Equal(t, pageMetadataNum-100*100, bpage.meta.getPagesFreelistLen())
   171  	for pn := PageNum(1); pn <= PageNum(100*100); pn++ {
   172  		pmItem := bpage.meta.getPagemetaItem(pn)
   173  		require.Equal(t, pn, pmItem.pageNum)
   174  		require.Equal(t, FileNum(10), pmItem.curAtFileNum)
   175  		require.Equal(t, FileNum(11), pmItem.nextStFileNum)
   176  		require.Equal(t, uint8(2), pmItem.splitState)
   177  	}
   178  	require.NoError(t, bpage.meta.close())
   179  }
   180  
   181  func TestManifest_PagemetaFull(t *testing.T) {
   182  	testInitDir()
   183  	defer os.RemoveAll(testDir)
   184  
   185  	opts := testInitOpts()
   186  	bpage := &Bitpage{
   187  		dirname: testDir,
   188  		opts:    opts,
   189  	}
   190  	require.NoError(t, openManifest(bpage))
   191  	for i := 1; i <= pageMetadataNum; i++ {
   192  		pageNum := bpage.meta.getNextPageNum()
   193  		pmItem := bpage.meta.newPagemetaItem(pageNum)
   194  		stFileNum := bpage.meta.getNextStFileNum(pageNum)
   195  		require.Equal(t, pmItem.nextStFileNum, stFileNum+FileNum(1))
   196  		atFileNum := bpage.meta.getNextAtFileNum(pageNum)
   197  		require.Equal(t, pmItem.curAtFileNum+FileNum(1), atFileNum)
   198  		bpage.meta.setNextArrayTableFileNum(pageNum)
   199  	}
   200  	for i := 1; i <= 1000; i++ {
   201  		bpage.meta.freePagemetaItem(PageNum(i))
   202  	}
   203  	for i := 1; i <= 1000; i++ {
   204  		pageNum := bpage.meta.getNextPageNum()
   205  		pmItem := bpage.meta.newPagemetaItem(pageNum)
   206  		stFileNum := bpage.meta.getNextStFileNum(pageNum)
   207  		require.Equal(t, pmItem.nextStFileNum, stFileNum+FileNum(1))
   208  		atFileNum := bpage.meta.getNextAtFileNum(pageNum)
   209  		require.Equal(t, pmItem.curAtFileNum+FileNum(1), atFileNum)
   210  		bpage.meta.setNextArrayTableFileNum(pageNum)
   211  	}
   212  	require.Equal(t, pageMetadataNum, len(bpage.meta.mu.pagemetaMap))
   213  	require.NoError(t, bpage.meta.close())
   214  
   215  	require.NoError(t, openManifest(bpage))
   216  	require.Equal(t, pageMetadataNum, len(bpage.meta.mu.pagemetaMap))
   217  	for pageNum, pmItem := range bpage.meta.mu.pagemetaMap {
   218  		require.Equal(t, pageNum, pmItem.pageNum)
   219  		require.Equal(t, FileNum(2), pmItem.nextStFileNum)
   220  		require.Equal(t, FileNum(1), pmItem.curAtFileNum)
   221  	}
   222  	require.NoError(t, bpage.meta.close())
   223  }