-
Notifications
You must be signed in to change notification settings - Fork 0
/
ioengine.go
194 lines (160 loc) · 5.94 KB
/
ioengine.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Copyright 2019 shimingyah.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// ee the License for the specific language governing permissions and
// limitations under the License.
package ioengine
import (
"errors"
"os"
)
// IOMode specifies disk I/O mode, default StandardIO.
type IOMode int
const (
// StandardIO indicates that disk I/O using standard buffered I/O
StandardIO IOMode = iota
// MMap indicates that disk I/O using memory mapped
MMap
// DIO indicates that disk I/O using Direct I/O
DIO
// AIO indicates that disk I/O using Async I/O by libaio or io_uring
AIO
)
// FileLockMode specifies file lock mode, default None.
type FileLockMode int
const (
// None indicates that open file without file lock
None FileLockMode = iota
// ReadWrite indicates that open file with file rwlock
ReadWrite
// ReadOnly indicates that open file with file rlock
ReadOnly
)
// AIOMode specifies aio mode, default Libaio.
type AIOMode int
const (
// Libaio linux kernel disk async IO solution
Libaio AIOMode = iota
// IOUring linux kernel new async IO with v5.1
IOUring
)
// Options are params for creating IOEngine.
type Options struct {
// IOEngine io mode
IOEngine IOMode
// Flag the file open mode
Flag int
// Perm the file perm
Perm os.FileMode
// FileLock file lock mode, default none
FileLock FileLockMode
// MmapSize mmap file size in memory
MmapSize int
// MmapWritable whether to allow mmap write
// if true, it will be use mmap write instead of standardIO write, not implemented yet.
MmapWritable bool
// AIO async IO mode, defaul libaio, the io_uring isn't implemented yet.
AIO AIOMode
// AIOQueueDepth libaio max events, it's also use to control client IO number.
AIOQueueDepth int
// AIOTimeout unit ms, libaio timeout, 0 means no timeout.
AIOTimeout int
}
// DefaultOptions is recommended options, you can modify these to suit your needs.
var DefaultOptions = Options{
IOEngine: StandardIO,
Flag: os.O_RDWR | os.O_CREATE | os.O_SYNC,
Perm: 0644,
FileLock: None,
MmapSize: 1<<30 - 1,
MmapWritable: false,
AIO: Libaio,
AIOQueueDepth: 1024,
AIOTimeout: 0,
}
// File a unified common file operation interface
type File interface {
// Fd returns the Unix fd or Windows handle referencing the open file.
// The fd is valid only until f.Close is called or f is garbage collected.
Fd() uintptr
// Stat returns the FileInfo structure describing file.
// The MMap mode returns the native file state instead of the memory slice.
Stat() (os.FileInfo, error)
// Read reads up to len(b) bytes from the File.
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns io.EOF.
Read(b []byte) (int, error)
// ReadAt reads len(b) bytes from the File starting at byte offset off.
// It returns the number of bytes read and the error, if any.
// ReadAt always returns a non-nil error when n < len(b).
// At end of file, that error is io.EOF.
ReadAt(b []byte, off int64) (int, error)
// Write writes len(b) bytes to the File.
// It returns the number of bytes written and an error, if any.
// Write returns a non-nil error when n != len(b).
Write(b []byte) (int, error)
// WriteAt writes len(b) bytes to the File starting at byte offset off.
// It returns the number of bytes written and an error, if any.
// WriteAt returns a non-nil error when n != len(b).
WriteAt(b []byte, off int64) (int, error)
// WriteAtv write multiple discrete discontinuous mem block
// on AIO mode, it's impled by pwritev syscall
// on other mode, it's impled by multi call pwrite syscall
WriteAtv(bs [][]byte, off int64) (int, error)
// Append write data at the end of file
// We do not guarantee atomicity of concurrent append writes.
// Note: we should avoid O_APPEND here due to ta the following bug:
// POSIX requires that opening a file with the O_APPEND flag should
// have no affect on the location at which pwrite() writes data.
// However, on Linux, if a file is opened with O_APPEND, pwrite()
// appends data to the end of the file, regardless of the value of
// offset. on darwin, there is no this Bug.
// More info here: https://linux.die.net/man/2/pwrite
Append(bs [][]byte) (int, error)
// Seek sets the offset for the next Read or Write on file to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means
// relative to the current offset, and 2 means relative to the end.
// It returns the new offset and an error, if any.
// The behavior of Seek on a file opened with O_APPEND is not specified.
Seek(offset int64, whence int) (int64, error)
// Truncate changes the size of the file.
// It does not change the I/O offset.
// If there is an error, it will be of type *PathError.
Truncate(size int64) error
// FLock the lock is suggested and exclusive
FLock() error
// FUnlock unlock the file lock
// it will be atomic release when file close.
FUnlock() error
// Sync commits the current contents of the file to stable storage.
// Typically, this means flushing the file system's in-memory copy
// of recently written data to disk.
Sync() error
// Close closes the File, rendering it unusable for I/O.
Close() error
// Option return IO engine options
Option() Options
}
// Open opens the named file for reading
func Open(name string, opt Options) (File, error) {
switch opt.IOEngine {
case StandardIO:
return newFileIO(name, opt)
case MMap:
return newMemoryMap(name, opt)
case DIO:
return newDirectIO(name, opt)
case AIO:
return newAsyncIO(name, opt)
default:
return nil, errors.New("Unsupported IO Engine")
}
}