github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/vfs/syncing_file_linux_test.go (about)

     1  // Copyright 2019 The LevelDB-Go and Pebble Authors. All rights reserved. Use
     2  // of this source code is governed by a BSD-style license that can be found in
     3  // the LICENSE file.
     4  
     5  //go:build linux && !arm
     6  // +build linux,!arm
     7  
     8  package vfs
     9  
    10  import (
    11  	"fmt"
    12  	"io/ioutil"
    13  	"os"
    14  	"syscall"
    15  	"testing"
    16  	"unsafe"
    17  )
    18  
    19  func TestSyncRangeSmokeTest(t *testing.T) {
    20  	testCases := []struct {
    21  		err      error
    22  		expected bool
    23  	}{
    24  		{nil, true},
    25  		{syscall.EINVAL, true},
    26  		{syscall.ENOSYS, false},
    27  	}
    28  	for i, c := range testCases {
    29  		t.Run("", func(t *testing.T) {
    30  			ok := syncRangeSmokeTest(uintptr(i),
    31  				func(fd int, off int64, n int64, flags int) (err error) {
    32  					if i != fd {
    33  						t.Fatalf("expected fd %d, but got %d", i, fd)
    34  					}
    35  					return c.err
    36  				})
    37  			if c.expected != ok {
    38  				t.Fatalf("expected %t, but got %t: %v", c.expected, ok, c.err)
    39  			}
    40  		})
    41  	}
    42  }
    43  
    44  func BenchmarkDirectIOWrite(b *testing.B) {
    45  	const targetSize = 16 << 20
    46  	const alignment = 4096
    47  
    48  	var wsizes []int
    49  	if testing.Verbose() {
    50  		wsizes = []int{4 << 10, 8 << 10, 16 << 10, 32 << 10}
    51  	} else {
    52  		wsizes = []int{4096}
    53  	}
    54  
    55  	for _, wsize := range wsizes {
    56  		b.Run(fmt.Sprintf("wsize=%d", wsize), func(b *testing.B) {
    57  			tmpf, err := ioutil.TempFile("", "bitalostable-db-syncing-file-")
    58  			if err != nil {
    59  				b.Fatal(err)
    60  			}
    61  			filename := tmpf.Name()
    62  			_ = tmpf.Close()
    63  			defer os.Remove(filename)
    64  
    65  			var f *os.File
    66  			var size int
    67  			buf := make([]byte, wsize+alignment)
    68  			if a := uintptr(unsafe.Pointer(&buf[0])) & uintptr(alignment-1); a != 0 {
    69  				buf = buf[alignment-a:]
    70  			}
    71  			buf = buf[:wsize]
    72  			init := true
    73  
    74  			b.SetBytes(int64(len(buf)))
    75  			b.ResetTimer()
    76  			for i := 0; i < b.N; i++ {
    77  				if f == nil {
    78  					b.StopTimer()
    79  					f, err = os.OpenFile(filename, syscall.O_DIRECT|os.O_RDWR, 0666)
    80  					if err != nil {
    81  						b.Fatal(err)
    82  					}
    83  					if init {
    84  						for size = 0; size < targetSize; size += len(buf) {
    85  							if _, err := f.WriteAt(buf, int64(size)); err != nil {
    86  								b.Fatal(err)
    87  							}
    88  						}
    89  					}
    90  					if err := f.Sync(); err != nil {
    91  						b.Fatal(err)
    92  					}
    93  					size = 0
    94  					b.StartTimer()
    95  				}
    96  				if _, err := f.WriteAt(buf, int64(size)); err != nil {
    97  					b.Fatal(err)
    98  				}
    99  				size += len(buf)
   100  				if size >= targetSize {
   101  					_ = f.Close()
   102  					f = nil
   103  				}
   104  			}
   105  			b.StopTimer()
   106  		})
   107  	}
   108  }