-
Notifications
You must be signed in to change notification settings - Fork 83
/
file_system.go
184 lines (165 loc) · 6.19 KB
/
file_system.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
// Licensed to Apache Software Foundation (ASF) under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Apache Software Foundation (ASF) licenses this file to you 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. See the License for the
// specific language governing permissions and limitations
// under the License.
// Package fs (file system) is an independent component to operate file and directory.
package fs
import (
"io"
"github.com/apache/skywalking-banyandb/pkg/logger"
)
const moduleName string = "filesystem"
// Mode contains permission of file and directory.
type Mode uint64
// SeqWriter allows writing data to a file in a sequential way.
type SeqWriter interface {
io.Writer
Path() string
Close() error
}
// Writer allows writing data to a file.
type Writer interface {
// Append mode, which adds new data to the end of a file.
Write(buffer []byte) (int, error)
// SequentialWrite mode, which supports appending consecutive buffers to the end of the file.
SequentialWrite() SeqWriter
// Returns the absolute path of the file.
Path() string
// Close File.
Close() error
}
// SeqReader allows reading data from a file in a sequential way.
type SeqReader interface {
io.Reader
Path() string
Close() error
}
// Reader allows reading data from a file.
type Reader interface {
// Read the entire file at a specified offset.
Read(offset int64, buffer []byte) (int, error)
// Read the entire file using sequential read.
SequentialRead() SeqReader
// Returns the absolute path of the file.
Path() string
// Close File.
Close() error
}
// Closer allows closing a file.
type Closer interface {
// Returns the absolute path of the file.
Path() string
// Close File.
Close() error
}
// File operation interface.
type File interface {
Writer
Reader
// Vector Append mode, which supports appending consecutive buffers to the end of the file.
Writev(iov *[][]byte) (int, error)
// Reading contiguous regions of a file and dispersing them into discontinuous buffers.
Readv(offset int64, iov *[][]byte) (int, error)
// Get the file written data's size and return an error if the file does not exist. The unit of file size is Byte.
Size() (int64, error)
// Returns the absolute path of the file.
Path() string
// Close File.
Close() error
}
// FileSystem operation interface.
type FileSystem interface {
// MkdirIfNotExist creates a new directory with the specified name and permission if it does not exist.
// If the directory exists, it will do nothing.
MkdirIfNotExist(path string, permission Mode)
// MkdirPanicIfExist creates a new directory with the specified name and permission if it does not exist.
// If the directory exists, it will panic.
MkdirPanicIfExist(path string, permission Mode)
// ReadDir reads the directory named by dirname and returns a list of directory entries sorted by filename.
ReadDir(dirname string) []DirEntry
// Create and open the file by specified name and mode.
CreateFile(name string, permission Mode) (File, error)
// Create and open lock file by specified name and mode.
CreateLockFile(name string, permission Mode) (File, error)
// Open the file by specified name and mode.
OpenFile(name string) (File, error)
// Flush mode, which flushes all data to one file.
Write(buffer []byte, name string, permission Mode) (int, error)
// Read the entire file using streaming read.
Read(name string) ([]byte, error)
// Delete the file.
DeleteFile(name string) error
// Delete the directory.
MustRMAll(path string)
// SyncPath the directory of file.
SyncPath(path string)
// MustGetFreeSpace returns the free space of the file system.
MustGetFreeSpace(path string) uint64
}
// DirEntry is the interface that wraps the basic information about a file or directory.
type DirEntry interface {
// Name returns the name of the file or directory.
Name() string
// IsDir reports whether the entry describes a directory.
IsDir() bool
}
// MustCreateFile creates a new file with the specified name and permission.
func MustCreateFile(fs FileSystem, path string, permission Mode) File {
f, err := fs.CreateFile(path, permission)
if err != nil {
logger.GetLogger().Panic().Err(err).Str("path", path).Msg("cannot create file")
}
return f
}
// MustFlush flushes all data to one file and panics if it cannot write all data.
func MustFlush(fs FileSystem, buffer []byte, name string, permission Mode) {
n, err := fs.Write(buffer, name, permission)
if err != nil {
logger.GetLogger().Panic().Err(err).Str("path", name).Msg("cannot write data")
}
if n != len(buffer) {
logger.GetLogger().Panic().Int("written", n).Int("expected", len(buffer)).Str("path", name).Msg("BUG: writer wrote wrong number of bytes")
}
}
// MustWriteData writes data to w and panics if it cannot write all data.
func MustWriteData(w SeqWriter, data []byte) {
if len(data) == 0 {
return
}
n, err := w.Write(data)
if err != nil {
logger.GetLogger().Panic().Err(err).Int("expected", len(data)).Str("path", w.Path()).Msg("cannot write data")
}
if n != len(data) {
logger.GetLogger().Panic().Int("written", n).Int("expected", len(data)).Str("path", w.Path()).Msg("BUG: writer wrote wrong number of bytes")
}
}
// MustReadData reads data from r and panics if it cannot read all data.
func MustReadData(r Reader, offset int64, buff []byte) {
n, err := r.Read(offset, buff)
if err != nil {
logger.GetLogger().Panic().Err(err).Str("path", r.Path()).Msg("cannot read data")
}
if n != len(buff) {
logger.GetLogger().Panic().Int("read", n).Int("expected", len(buff)).Str("path", r.Path()).Msg("BUG: reader read wrong number of bytes")
}
}
// MustClose closes c and panics if it cannot close.
func MustClose(c Closer) {
err := c.Close()
if err != nil {
logger.GetLogger().Panic().Err(err).Str("path", c.Path()).Msg("cannot close file")
}
}