@@ -24,43 +24,69 @@ import (
24
24
)
25
25
26
26
type _BlockWriter struct {
27
+ blockIdx int32
27
28
indexBlocks map [int32 ]_IndexBlock // map[blockIdx]block
28
29
29
30
fs * _FileSet
30
31
lease * _Lease
31
32
buffer * bpool.Buffer
32
33
33
- indexLeases map [uint64 ]struct {} //map[seq]struct
34
- dataLeases map [int64 ]uint32 // map[offset]size
35
- dataOffset int64
34
+ indexLeases map [uint64 ]struct {} //map[seq]struct
35
+ dataLeases map [int64 ]uint32 // map[offset]size
36
+ indexFile , dataFile * _File
37
+ offset , indexOffset , dataOffset int64
36
38
}
37
39
38
40
func newBlockWriter (fs * _FileSet , lease * _Lease , buf * bpool.Buffer ) (* _BlockWriter , error ) {
39
- w := & _BlockWriter {indexBlocks : make (map [int32 ]_IndexBlock ), fs : fs , lease : lease , buffer : buf }
41
+ w := & _BlockWriter {blockIdx : - 1 , indexBlocks : make (map [int32 ]_IndexBlock ), fs : fs , lease : lease , buffer : buf }
40
42
w .indexLeases = make (map [uint64 ]struct {})
41
43
w .dataLeases = make (map [int64 ]uint32 )
42
44
45
+ indexFile , err := fs .getFile (_FileDesc {fileType : typeIndex })
46
+ if err != nil {
47
+ return nil , err
48
+ }
49
+ w .indexFile = indexFile
50
+ w .indexOffset = indexFile .currSize ()
51
+ if w .indexOffset > 0 {
52
+ w .blockIdx = int32 (w .indexOffset / int64 (blockSize ))
53
+ // read final block from index file.
54
+ if w .indexOffset > int64 (w .blockIdx * blockSize ) {
55
+ r := newBlockReader (w .fs )
56
+ b , err := r .readIndexBlock (w .blockIdx )
57
+ if err != nil {
58
+ return nil , err
59
+ }
60
+ w .indexBlocks [w .blockIdx ] = b
61
+ }
62
+ }
63
+
43
64
dataFile , err := fs .getFile (_FileDesc {fileType : typeData })
44
65
if err != nil {
45
66
return nil , err
46
67
}
47
- w .dataOffset = dataFile .Size ()
68
+ w .dataFile = dataFile
69
+ w .offset = dataFile .currSize ()
70
+ w .dataOffset = dataFile .currSize ()
48
71
return w , nil
49
72
}
50
73
51
- func (w * _BlockWriter ) extend (size uint32 ) (int64 , error ) {
52
- indexFile , err := w . fs . getFile ( _FileDesc { fileType : typeIndex } )
53
- if err != nil {
54
- return 0 , err
74
+ func (w * _BlockWriter ) extend (upperSeq uint64 ) (int64 , error ) {
75
+ off := blockOffset ( blockIndex ( upperSeq ) )
76
+ if off <= w . indexFile . currSize () {
77
+ return w . indexFile . currSize (), nil
55
78
}
56
- return indexFile .extend (size )
79
+ return w . indexFile .extend (uint32 ( off - w . indexFile . currSize ()) )
57
80
}
58
81
59
82
func (w * _BlockWriter ) del (seq uint64 ) (_IndexEntry , error ) {
60
83
var delEntry _IndexEntry
61
84
bIdx := blockIndex (seq )
85
+ if bIdx > w .blockIdx {
86
+ return delEntry , nil // no entry in db to delete
87
+ }
62
88
r := newBlockReader (w .fs )
63
- b , err := r .readIndexBlock (seq )
89
+ b , err := r .readIndexBlock (bIdx )
64
90
if err != nil {
65
91
return _IndexEntry {}, err
66
92
}
@@ -89,7 +115,7 @@ func (w *_BlockWriter) del(seq uint64) (_IndexEntry, error) {
89
115
return delEntry , nil
90
116
}
91
117
92
- func (w * _BlockWriter ) append (e _IndexEntry , blockIdx int32 ) (err error ) {
118
+ func (w * _BlockWriter ) append (e _IndexEntry ) (err error ) {
93
119
var b _IndexBlock
94
120
var ok bool
95
121
if e .seq == 0 {
@@ -98,9 +124,9 @@ func (w *_BlockWriter) append(e _IndexEntry, blockIdx int32) (err error) {
98
124
bIdx := blockIndex (e .seq )
99
125
b , ok = w .indexBlocks [bIdx ]
100
126
if ! ok {
101
- if bIdx <= blockIdx {
127
+ if bIdx < w . blockIdx {
102
128
r := newBlockReader (w .fs )
103
- b , err = r .readIndexBlock (e . seq )
129
+ b , err = r .readIndexBlock (bIdx )
104
130
if err != nil {
105
131
return err
106
132
}
@@ -128,24 +154,20 @@ func (w *_BlockWriter) append(e _IndexEntry, blockIdx int32) (err error) {
128
154
if off != - 1 {
129
155
buf := make ([]byte , dataLen )
130
156
copy (buf , e .cache )
131
- dataFile , err := w .fs .getFile (_FileDesc {fileType : typeData })
132
- if err != nil {
133
- return err
134
- }
135
- if _ , err = dataFile .WriteAt (buf , off ); err != nil {
157
+ if _ , err = w .dataFile .WriteAt (buf , off ); err != nil {
136
158
return err
137
159
}
138
160
w .dataLeases [off ] = uint32 (dataLen )
139
161
} else {
140
- off = w .dataOffset
162
+ off = w .offset
141
163
offset , err := w .buffer .Extend (int64 (dataLen ))
142
164
if err != nil {
143
165
return err
144
166
}
145
167
if _ , err := w .buffer .WriteAt (e .cache , offset ); err != nil {
146
168
return err
147
169
}
148
- w .dataOffset += int64 (dataLen )
170
+ w .offset += int64 (dataLen )
149
171
}
150
172
e .msgOffset = off
151
173
@@ -166,20 +188,12 @@ func (w *_BlockWriter) append(e _IndexEntry, blockIdx int32) (err error) {
166
188
167
189
func (w * _BlockWriter ) write () error {
168
190
// write data blocks
169
- dataFile , err := w .fs .getFile (_FileDesc {fileType : typeData })
170
- if err != nil {
171
- return err
172
- }
173
- if _ , err := dataFile .write (w .buffer .Bytes ()); err != nil {
191
+ if _ , err := w .dataFile .write (w .buffer .Bytes ()); err != nil {
174
192
return err
175
193
}
176
194
177
195
// Reset buffer before reusing it.
178
196
w .buffer .Reset ()
179
- indexFile , err := w .fs .getFile (_FileDesc {fileType : typeIndex })
180
- if err != nil {
181
- return err
182
- }
183
197
for bIdx , b := range w .indexBlocks {
184
198
if ! b .leased || ! b .dirty {
185
199
continue
@@ -189,7 +203,7 @@ func (w *_BlockWriter) write() error {
189
203
}
190
204
off := blockOffset (bIdx )
191
205
buf := b .MarshalBinary ()
192
- if _ , err := indexFile .WriteAt (buf , off ); err != nil {
206
+ if _ , err := w . indexFile .WriteAt (buf , off ); err != nil {
193
207
return err
194
208
}
195
209
b .dirty = false
@@ -219,7 +233,7 @@ func (w *_BlockWriter) write() error {
219
233
return err
220
234
}
221
235
buf := b .MarshalBinary ()
222
- if _ , err := indexFile .WriteAt (buf , off ); err != nil {
236
+ if _ , err := w . indexFile .WriteAt (buf , off ); err != nil {
223
237
return err
224
238
}
225
239
b .dirty = false
@@ -240,7 +254,7 @@ func (w *_BlockWriter) write() error {
240
254
if err != nil {
241
255
return err
242
256
}
243
- if _ , err := indexFile .WriteAt (blockData , blockOff ); err != nil {
257
+ if _ , err := w . indexFile .WriteAt (blockData , blockOff ); err != nil {
244
258
return err
245
259
}
246
260
bufOff = w .buffer .Size ()
@@ -294,3 +308,21 @@ func (w *_BlockWriter) rollback() error {
294
308
}
295
309
return nil
296
310
}
311
+
312
+ func (w * _BlockWriter ) reset () error {
313
+ w .buffer .Reset ()
314
+
315
+ w .indexOffset = w .indexFile .currSize ()
316
+ w .blockIdx = int32 (w .indexOffset / int64 (blockSize ))
317
+
318
+ w .dataOffset = w .dataFile .currSize ()
319
+
320
+ return nil
321
+ }
322
+
323
+ func (w * _BlockWriter ) abort () error {
324
+ w .indexFile .truncate (w .indexOffset )
325
+ w .dataFile .truncate (w .dataOffset )
326
+
327
+ return w .rollback ()
328
+ }
0 commit comments