github.com/turingchain2020/turingchain@v1.1.21/common/db/go_level_db_test.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package db
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"testing"
    14  
    15  	"github.com/turingchain2020/turingchain/common"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  // leveldb迭代器测试
    22  func TestGoLevelDBIterator(t *testing.T) {
    23  	dir, err := ioutil.TempDir("", "goleveldb")
    24  	require.NoError(t, err)
    25  	t.Log(dir)
    26  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
    27  	require.NoError(t, err)
    28  	defer leveldb.Close()
    29  	testDBIterator(t, leveldb)
    30  }
    31  
    32  func TestGoLevelDBIteratorAll(t *testing.T) {
    33  	dir, err := ioutil.TempDir("", "goleveldb")
    34  	require.NoError(t, err)
    35  	t.Log(dir)
    36  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
    37  	require.NoError(t, err)
    38  	defer leveldb.Close()
    39  	testDBIteratorAllKey(t, leveldb)
    40  }
    41  
    42  func TestGoLevelDBIteratorReserverExample(t *testing.T) {
    43  	dir, err := ioutil.TempDir("", "goleveldb")
    44  	require.NoError(t, err)
    45  	t.Log(dir)
    46  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
    47  	require.NoError(t, err)
    48  	defer leveldb.Close()
    49  	testDBIteratorReserverExample(t, leveldb)
    50  }
    51  
    52  func TestGoLevelDBIteratorDel(t *testing.T) {
    53  	dir, err := ioutil.TempDir("", "goleveldb")
    54  	require.NoError(t, err)
    55  	t.Log(dir)
    56  
    57  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
    58  	require.NoError(t, err)
    59  	defer leveldb.Close()
    60  
    61  	testDBIteratorDel(t, leveldb)
    62  }
    63  
    64  func TestLevelDBBatch(t *testing.T) {
    65  	dir, err := ioutil.TempDir("", "goleveldb")
    66  	require.NoError(t, err)
    67  	t.Log(dir)
    68  
    69  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
    70  	require.NoError(t, err)
    71  	defer leveldb.Close()
    72  	testBatch(t, leveldb)
    73  }
    74  
    75  func TestLevelDBTransaction(t *testing.T) {
    76  	dir, err := ioutil.TempDir("", "goleveldb")
    77  	require.NoError(t, err)
    78  	t.Log(dir)
    79  
    80  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
    81  	require.NoError(t, err)
    82  	defer leveldb.Close()
    83  	testTransaction(t, leveldb)
    84  }
    85  
    86  // leveldb边界测试
    87  func TestGoLevelDBBoundary(t *testing.T) {
    88  	dir, err := ioutil.TempDir("", "goleveldb")
    89  	require.NoError(t, err)
    90  	t.Log(dir)
    91  
    92  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
    93  	require.NoError(t, err)
    94  	defer leveldb.Close()
    95  
    96  	testDBBoundary(t, leveldb)
    97  }
    98  
    99  func BenchmarkLevelDBBatchWrites(b *testing.B) {
   100  	dir, err := ioutil.TempDir("", "example")
   101  	assert.Nil(b, err)
   102  	defer os.RemoveAll(dir)
   103  	db, err := NewGoLevelDB("goleveldb", dir, 100)
   104  	assert.Nil(b, err)
   105  	batch := db.NewBatch(true)
   106  	b.ResetTimer()
   107  	for i := 0; i < b.N; i++ {
   108  		b.StopTimer()
   109  		key := string(common.GetRandBytes(20, 64))
   110  		value := fmt.Sprintf("v%d", i)
   111  		b.StartTimer()
   112  		batch.Set([]byte(key), []byte(value))
   113  		if i > 0 && i%10000 == 0 {
   114  			err := batch.Write()
   115  			assert.Nil(b, err)
   116  			batch = db.NewBatch(true)
   117  		}
   118  	}
   119  	err = batch.Write()
   120  	assert.Nil(b, err)
   121  	b.StopTimer()
   122  }
   123  
   124  func BenchmarkLevelDBBatchWrites1k(b *testing.B) {
   125  	benchmarkBatchWrites(b, 1)
   126  }
   127  
   128  func BenchmarkLevelDBBatchWrites16k(b *testing.B) {
   129  	benchmarkBatchWrites(b, 16)
   130  }
   131  
   132  func BenchmarkLevelDBBatchWrites256k(b *testing.B) {
   133  	benchmarkBatchWrites(b, 256)
   134  }
   135  
   136  func BenchmarkLevelDBBatchWrites1M(b *testing.B) {
   137  	benchmarkBatchWrites(b, 1024)
   138  }
   139  
   140  //func BenchmarkLevelDBBatchWrites4M(b *testing.B) {
   141  //	benchmarkBatchWrites(b, 1024*4)
   142  //}
   143  
   144  func benchmarkBatchWrites(b *testing.B, size int) {
   145  	dir, err := ioutil.TempDir("", "example")
   146  	assert.Nil(b, err)
   147  	defer os.RemoveAll(dir)
   148  	db, err := NewGoLevelDB("goleveldb", dir, 100)
   149  	assert.Nil(b, err)
   150  	batch := db.NewBatch(true)
   151  	b.ResetTimer()
   152  	for i := 0; i < b.N; i++ {
   153  		b.StopTimer()
   154  		key := common.GetRandBytes(20, 64)
   155  		value := common.GetRandBytes(size*1024, size*1024)
   156  		b.StartTimer()
   157  		batch.Set(key, value)
   158  		if i > 0 && i%100 == 0 {
   159  			err := batch.Write()
   160  			assert.Nil(b, err)
   161  			batch = db.NewBatch(true)
   162  		}
   163  	}
   164  	err = batch.Write()
   165  	assert.Nil(b, err)
   166  	b.StopTimer()
   167  }
   168  
   169  func BenchmarkLevelDBRandomReads1K(b *testing.B) {
   170  	benchmarkLevelDBRandomReads(b, 1)
   171  }
   172  
   173  func BenchmarkLevelDBRandomReads16K(b *testing.B) {
   174  	benchmarkLevelDBRandomReads(b, 16)
   175  }
   176  
   177  func BenchmarkLevelDBRandomReads256K(b *testing.B) {
   178  	benchmarkLevelDBRandomReads(b, 256)
   179  }
   180  
   181  func BenchmarkLevelDBRandomReads1M(b *testing.B) {
   182  	benchmarkLevelDBRandomReads(b, 1024)
   183  }
   184  
   185  func benchmarkLevelDBRandomReads(b *testing.B, size int) {
   186  	dir, err := ioutil.TempDir("", "example")
   187  	assert.Nil(b, err)
   188  	defer os.RemoveAll(dir)
   189  	db, err := NewGoLevelDB("goleveldb", dir, 100)
   190  	assert.Nil(b, err)
   191  	batch := db.NewBatch(true)
   192  	var keys [][]byte
   193  	for i := 0; i < 32*1024/size; i++ {
   194  		key := common.GetRandBytes(20, 64)
   195  		value := common.GetRandBytes(size*1024, size*1024)
   196  		batch.Set(key, value)
   197  		keys = append(keys, key)
   198  		if batch.ValueSize() > 1<<20 {
   199  			err := batch.Write()
   200  			assert.Nil(b, err)
   201  			batch = db.NewBatch(true)
   202  		}
   203  	}
   204  	if batch.ValueSize() > 0 {
   205  		err = batch.Write()
   206  		assert.Nil(b, err)
   207  	}
   208  
   209  	//开始rand 读取
   210  	db.Close()
   211  	db, err = NewGoLevelDB("goleveldb", dir, 1)
   212  	assert.Nil(b, err)
   213  	b.ResetTimer()
   214  	for i := 0; i < b.N; i++ {
   215  		index := RandInt() % len(keys)
   216  		key := keys[index]
   217  		_, err := db.Get(key)
   218  		assert.Nil(b, err)
   219  	}
   220  	b.StopTimer()
   221  }
   222  
   223  func BenchmarkLevelDBRandomReadsWrites(b *testing.B) {
   224  	numItems := int64(1000000)
   225  	internal := map[int64]int64{}
   226  	for i := 0; i < int(numItems); i++ {
   227  		internal[int64(i)] = int64(0)
   228  	}
   229  	dir := fmt.Sprintf("test_%x", RandStr(12))
   230  	defer os.RemoveAll(dir)
   231  	db, err := NewGoLevelDB("goleveldb", dir, 1000)
   232  	if err != nil {
   233  		b.Fatal(err.Error())
   234  		return
   235  	}
   236  	for i := 0; i < b.N; i++ {
   237  		// Write something
   238  		{
   239  			idx := (int64(RandInt()) % numItems)
   240  			internal[idx]++
   241  			val := internal[idx]
   242  			idxBytes := int642Bytes(idx)
   243  			valBytes := int642Bytes(val)
   244  			//fmt.Printf("Set %X -> %X\n", idxBytes, valBytes)
   245  			db.Set(
   246  				idxBytes,
   247  				valBytes,
   248  			)
   249  		}
   250  	}
   251  
   252  	b.ResetTimer()
   253  	for i := 0; i < b.N; i++ {
   254  		// Read something
   255  		{
   256  			idx := (int64(RandInt()) % numItems)
   257  			val := internal[idx]
   258  			idxBytes := int642Bytes(idx)
   259  			valBytes, _ := db.Get(idxBytes)
   260  			//fmt.Printf("Get %X -> %X\n", idxBytes, valBytes)
   261  			if val == 0 {
   262  				if !bytes.Equal(valBytes, nil) {
   263  					b.Errorf("Expected %v for %v, got %X",
   264  						nil, idx, valBytes)
   265  					break
   266  				}
   267  			} else {
   268  				if len(valBytes) != 8 {
   269  					b.Errorf("Expected length 8 for %v, got %X",
   270  						idx, valBytes)
   271  					break
   272  				}
   273  				valGot := bytes2Int64(valBytes)
   274  				if val != valGot {
   275  					b.Errorf("Expected %v for %v, got %v",
   276  						val, idx, valGot)
   277  					break
   278  				}
   279  			}
   280  		}
   281  	}
   282  	b.StopTimer()
   283  	db.Close()
   284  }
   285  
   286  func int642Bytes(i int64) []byte {
   287  	buf := make([]byte, 8)
   288  	binary.BigEndian.PutUint64(buf, uint64(i))
   289  	return buf
   290  }
   291  
   292  func bytes2Int64(buf []byte) int64 {
   293  	return int64(binary.BigEndian.Uint64(buf))
   294  }
   295  
   296  // leveldb返回值测试
   297  func TestGoLevelDBResult(t *testing.T) {
   298  	dir, err := ioutil.TempDir("", "goleveldb")
   299  	require.NoError(t, err)
   300  	t.Log(dir)
   301  
   302  	leveldb, err := NewGoLevelDB("goleveldb", dir, 128)
   303  	require.NoError(t, err)
   304  	defer leveldb.Close()
   305  
   306  	testDBIteratorResult(t, leveldb)
   307  }