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 }