github.com/iceber/iouring-go@v0.0.0-20230403020409-002cfd2e2a90/examples/cp/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"time"
     7  
     8  	"github.com/iceber/iouring-go"
     9  )
    10  
    11  const entries uint = 64
    12  const blockSize int64 = 32 * 1024
    13  
    14  func main() {
    15  	now := time.Now()
    16  
    17  	if len(os.Args) != 3 {
    18  		fmt.Printf("Usage: %s file1 file2\n", os.Args[0])
    19  		return
    20  	}
    21  
    22  	iour, err := iouring.New(entries)
    23  	if err != nil {
    24  		panic(fmt.Sprintf("new IOURing error: %v", err))
    25  	}
    26  	defer iour.Close()
    27  
    28  	src, err := os.Open(os.Args[1])
    29  	if err != nil {
    30  		fmt.Printf("Open src file failed: %v\n", err)
    31  		return
    32  	}
    33  	defer src.Close()
    34  
    35  	dest, err := os.Create(os.Args[2])
    36  	if err != nil {
    37  		fmt.Printf("create dest file failed: %v\n", err)
    38  		return
    39  	}
    40  	defer dest.Close()
    41  
    42  	if err := iour.RegisterFiles([]*os.File{src, dest}); err != nil {
    43  		panic(err)
    44  	}
    45  
    46  	stat, err := src.Stat()
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  	size := stat.Size()
    51  
    52  	var reads int
    53  	var writes int
    54  	var offset uint64
    55  
    56  	ch := make(chan iouring.Result, entries)
    57  	prepRequests := make([]iouring.PrepRequest, 0, entries)
    58  	for size > 0 {
    59  		if reads >= int(entries) {
    60  			break
    61  		}
    62  		readSize := size
    63  		if readSize > blockSize {
    64  			readSize = blockSize
    65  		}
    66  
    67  		b := make([]byte, readSize)
    68  		prepRequest := iouring.Pread(int(src.Fd()), b, offset).WithInfo(offset)
    69  		prepRequests = append(prepRequests, prepRequest)
    70  
    71  		size -= readSize
    72  		offset += uint64(readSize)
    73  		reads++
    74  	}
    75  
    76  	if _, err := iour.SubmitRequests(prepRequests, ch); err != nil {
    77  		panic(err)
    78  	}
    79  
    80  	for comp := 0; comp < reads+writes; comp++ {
    81  		result := <-ch
    82  		if err := result.Err(); err != nil {
    83  			panic(err)
    84  		}
    85  
    86  		if result.Opcode() == iouring.OpRead {
    87  			b, _ := result.GetRequestBuffer()
    88  			offset := result.GetRequestInfo().(uint64)
    89  			prep := iouring.Pwrite(int(dest.Fd()), b, offset)
    90  			if _, err := iour.SubmitRequest(prep, ch); err != nil {
    91  				panic(err)
    92  			}
    93  			writes++
    94  			continue
    95  		}
    96  
    97  		if size <= 0 {
    98  			continue
    99  		}
   100  
   101  		readSize := size
   102  		if readSize > blockSize {
   103  			readSize = blockSize
   104  		}
   105  
   106  		b, _ := result.GetRequestBuffer()
   107  		prepRequest := iouring.Pread(int(src.Fd()), b[:readSize], offset).WithInfo(offset)
   108  		if _, err := iour.SubmitRequest(prepRequest, ch); err != nil {
   109  			panic(err)
   110  		}
   111  		size -= readSize
   112  		offset += uint64(readSize)
   113  		reads++
   114  	}
   115  	fmt.Printf("cp successful: %v\n", time.Now().Sub(now))
   116  }