github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitree/bdb/freelist_bitmap_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 bdb
    16  
    17  import (
    18  	"bytes"
    19  	"encoding/binary"
    20  	"fmt"
    21  	"testing"
    22  	"unsafe"
    23  
    24  	"github.com/RoaringBitmap/roaring/roaring64"
    25  	"github.com/stretchr/testify/require"
    26  	"github.com/zuoyebang/bitalosdb/internal/consts"
    27  )
    28  
    29  func Test_freelist_bitmap(t *testing.T) {
    30  	rb := roaring64.NewBitmap()
    31  	for i := pgid(10); i > pgid(0); i-- {
    32  		rb.Add(uint64(i))
    33  	}
    34  
    35  	rbLen := rb.GetSerializedSizeInBytes()
    36  
    37  	buf := make([]byte, 4096)
    38  	p := (*page)(unsafe.Pointer(&buf[0]))
    39  	data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p))
    40  
    41  	bitmapLenBuf := unsafeByteSlice(data, 0, 0, bitmapLenSize)
    42  	binary.LittleEndian.PutUint64(bitmapLenBuf, rbLen)
    43  
    44  	var c []byte
    45  	data = unsafeAdd(data, bitmapLenSize)
    46  	unsafeSlice(unsafe.Pointer(&c), data, int(rbLen))
    47  
    48  	var rbBuf bytes.Buffer
    49  	_, err := rb.WriteTo(&rbBuf)
    50  	require.NoError(t, err)
    51  
    52  	fmt.Println("write bitmapArray", rb.ToArray())
    53  	fmt.Println("rbLen", rbLen, len(c), len(rbBuf.Bytes()))
    54  
    55  	copy(c, rbBuf.Bytes())
    56  
    57  	var ids []pgid
    58  	idx := 0
    59  	data = unsafeIndex(unsafe.Pointer(p), unsafe.Sizeof(*p), unsafe.Sizeof(ids[0]), idx)
    60  	bLenBuf := unsafeByteSlice(data, 0, 0, bitmapLenSize)
    61  	bitmapLen := binary.LittleEndian.Uint64(bLenBuf)
    62  
    63  	fmt.Println("bitmapLen", bitmapLen)
    64  
    65  	data = unsafeAdd(data, bitmapLenSize)
    66  	bitmapData := unsafeByteSlice(data, 0, 0, int(bitmapLen))
    67  
    68  	buf1 := new(bytes.Buffer)
    69  	buf1.Write(bitmapData)
    70  	rb1 := roaring64.NewBitmap()
    71  	_, err = rb1.ReadFrom(buf1)
    72  	require.NoError(t, err)
    73  
    74  	bitmapArray := rb1.ToArray()
    75  	idsCopy := *(*[]pgid)(unsafe.Pointer(&bitmapArray))
    76  	fmt.Println("read bitmapArray", idsCopy)
    77  }
    78  
    79  func Test_freelist_largeCount(t *testing.T) {
    80  	f := newFreelist(consts.BdbFreelistMapType)
    81  
    82  	buf := make([]byte, 4096)
    83  	p := (*page)(unsafe.Pointer(&buf[0]))
    84  
    85  	p.flags |= freelistPageFlag
    86  
    87  	p.count = 0xFFFF
    88  	data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p))
    89  	pgidCount := unsafeByteSlice(data, 0, 0, freelistLargeSize)
    90  	binary.LittleEndian.PutUint64(pgidCount, uint64(1234567))
    91  	data = unsafeAdd(data, freelistLargeSize)
    92  
    93  	rb := roaring64.NewBitmap()
    94  	for i := pgid(10); i > pgid(0); i-- {
    95  		rb.Add(uint64(i))
    96  	}
    97  	rbLen := rb.GetSerializedSizeInBytes()
    98  	err := f.copyallBitmap(data, rb, rbLen)
    99  	require.NoError(t, err)
   100  
   101  	if (p.flags & freelistPageFlag) == 0 {
   102  		panic(fmt.Sprintf("invalid freelist page: %d, page type is %s", p.id, p.typ()))
   103  	}
   104  	var idx, count = 0, int(p.count)
   105  	if count == 0xFFFF {
   106  		idx = 1
   107  		c := *(*pgid)(unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)))
   108  		count = int(c)
   109  		if count < 0 {
   110  			panic(fmt.Sprintf("leading element count %d overflows int", c))
   111  		}
   112  	}
   113  
   114  	fmt.Println("readFromBitmap", idx, count)
   115  
   116  	var ids []pgid
   117  	var data1 unsafe.Pointer
   118  	data1 = unsafeIndex(unsafe.Pointer(p), unsafe.Sizeof(*p), unsafe.Sizeof(ids[0]), idx)
   119  	bitmapLenBuf := unsafeByteSlice(data1, 0, 0, bitmapLenSize)
   120  	bitmapLen := binary.LittleEndian.Uint64(bitmapLenBuf)
   121  
   122  	data1 = unsafeAdd(data1, bitmapLenSize)
   123  	bitmapData := unsafeByteSlice(data1, 0, 0, int(bitmapLen))
   124  
   125  	buf1 := new(bytes.Buffer)
   126  	buf1.Write(bitmapData)
   127  	rb1 := roaring64.NewBitmap()
   128  	if _, err := rb1.ReadFrom(buf1); err != nil {
   129  		panic(fmt.Sprintf("read freelist from bitmap. err: %s", err))
   130  	}
   131  
   132  	bitmapArray := rb1.ToArray()
   133  	idsCopy := *(*[]pgid)(unsafe.Pointer(&bitmapArray))
   134  	fmt.Println("readFromBitmap", idsCopy)
   135  }