forked from elastic/go-txfile
-
Notifications
You must be signed in to change notification settings - Fork 0
/
opts.go
138 lines (113 loc) · 4.46 KB
/
opts.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
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. 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 txfile
// Options provides common file options used when opening or creating a file.
type Options struct {
// Additional flags.
Flags Flag
// Configure file sync behavior
Sync SyncMode
// MaxSize sets the maximum file size in bytes. This should be a multiple of PageSize.
// If it's not a multiple of PageSize, the actual files maximum size is rounded downwards
// to the next multiple of PageSize.
// A value of 0 indicates the file can grow without limits.
MaxSize uint64
// PageSize sets the files page size on file creation. PageSize is ignored if
// the file already exists.
// If PageSize is not configured, the OSes main memory page size is selected.
PageSize uint32
// InitMetaArea configures the minimum amount of page in the meta area.
// The amount of pages is only allocated when the file is generated.
// The meta area grows by double the current meta area. To reduce the
// total amount of pages moved to meta area on grow, it is recommended that
// the value of InitMetaArea is a power of 2.
InitMetaArea uint32
// Prealloc disk space if MaxSize is set.
Prealloc bool
// Open file in readonly mode.
Readonly bool
Observer Observer
}
// Flag configures file opening behavior.
type Flag uint64
const (
// FlagWaitLock instructs the open function to block until the file lock could
// be acquired. By default open will return with an error if the lock file
// can not be generated, opened or locked.
FlagWaitLock Flag = 1 << iota
// FlagUnboundMaxSize configures the file max size to be unbound. This sets
// MaxSize to 0. If MaxSize and Prealloc is set, up to MaxSize bytes are
// preallocated on disk (truncate).
FlagUnboundMaxSize
// FlagUpdMaxSize updates the file max size setting. If not set, the max size
// setting is read from the file to be opened.
// The file will grow if MaxSize is larger then the current max size setting.
// If MaxSize is less then the file's max size value, the file is tried to
// shrink dynamically whenever pages are freed. Freed pages are returned via
// `Truncate`.
FlagUpdMaxSize
)
// SyncMode selects the file syncing behavior
type SyncMode uint8
const (
// SyncDefault lets the implementation choose the default syncing mode
SyncDefault SyncMode = iota
// SyncData prefers fdatasync if available. Still uses fsync (or similar) if
// implementation wants to enforce fsync.
SyncData
// SyncFull enforces fsync/or similar.
SyncFull
// SyncNone disable syncing. Do not use this in production environments, as
// this can easily cause file corruption.
SyncNone
)
// Validate checks if all fields in Options are consistent with the File implementation.
func (o *Options) Validate() error {
if o.Flags.check(FlagUpdMaxSize) {
if o.Readonly {
return errOf(InvalidConfig).
report("can not update max size on in readonly mode")
}
if !o.Flags.check(FlagUnboundMaxSize) && o.MaxSize > 0 && o.MaxSize < minRequiredFileSize {
return errOf(InvalidConfig).
reportf("max size must be at least %v bytes ", minRequiredFileSize)
}
}
if metaSz := o.InitMetaArea; metaSz > 0 && o.MaxSize > 0 && o.PageSize > 0 {
const headerPages = 2
totalPages := o.MaxSize / uint64(o.PageSize)
avail := totalPages - headerPages
if uint64(metaSz) >= avail {
return errOf(InvalidConfig).
reportf("meta area of %v pages exceeds the available pages %v", metaSz, avail)
}
}
if o.PageSize != 0 {
if !isPowerOf2(uint64(o.PageSize)) {
return errOf(InvalidConfig).
reportf("pageSize %v is not power of 2", o.PageSize)
}
if o.PageSize < minPageSize {
return errOf(InvalidConfig).
reportf("pageSize must be >= %v", minPageSize)
}
}
return nil
}
func (f Flag) check(check Flag) bool {
return (f & check) == check
}