18
18
use std:: collections:: { HashMap , HashSet } ;
19
19
20
20
use bytes:: Bytes ;
21
- use futures:: lock:: Mutex ;
22
21
23
22
use crate :: io:: { FileWrite , OutputFile } ;
24
23
use crate :: puffin:: blob:: Blob ;
25
24
use crate :: puffin:: compression:: CompressionCodec ;
26
25
use crate :: puffin:: metadata:: { BlobMetadata , FileMetadata , Flag } ;
27
26
use crate :: Result ;
28
27
29
- struct WriterState {
28
+ /// Puffin writer
29
+ pub ( crate ) struct PuffinWriter {
30
30
writer : Box < dyn FileWrite > ,
31
31
is_header_written : bool ,
32
32
num_bytes_written : u64 ,
33
- }
34
-
35
- /// Puffin writer
36
- pub ( crate ) struct PuffinWriter {
37
- writer_state : Mutex < WriterState > ,
38
33
written_blobs_metadata : Vec < BlobMetadata > ,
39
34
properties : HashMap < String , String > ,
40
35
footer_compression_codec : CompressionCodec ,
@@ -56,14 +51,10 @@ impl PuffinWriter {
56
51
CompressionCodec :: None
57
52
} ;
58
53
59
- let initial_state = WriterState {
54
+ Ok ( Self {
60
55
writer : output_file. writer ( ) . await ?,
61
56
is_header_written : false ,
62
57
num_bytes_written : 0 ,
63
- } ;
64
-
65
- Ok ( Self {
66
- writer_state : Mutex :: new ( initial_state) ,
67
58
written_blobs_metadata : Vec :: new ( ) ,
68
59
properties,
69
60
footer_compression_codec,
@@ -77,14 +68,12 @@ impl PuffinWriter {
77
68
blob : Blob ,
78
69
compression_codec : CompressionCodec ,
79
70
) -> Result < ( ) > {
80
- let mut writer_state = self . writer_state . lock ( ) . await ;
81
-
82
- PuffinWriter :: write_header_once ( & mut writer_state) . await ?;
71
+ self . write_header_once ( ) . await ?;
83
72
84
- let offset = writer_state . num_bytes_written ;
73
+ let offset = self . num_bytes_written ;
85
74
let compressed_bytes: Bytes = compression_codec. compress ( blob. data ) ?. into ( ) ;
86
75
let length = compressed_bytes. len ( ) . try_into ( ) ?;
87
- PuffinWriter :: write ( & mut writer_state , compressed_bytes) . await ?;
76
+ self . write ( compressed_bytes) . await ?;
88
77
self . written_blobs_metadata . push ( BlobMetadata {
89
78
r#type : blob. r#type ,
90
79
fields : blob. fields ,
@@ -100,26 +89,25 @@ impl PuffinWriter {
100
89
}
101
90
102
91
/// Finalizes the Puffin file
103
- pub ( crate ) async fn close ( & mut self ) -> Result < ( ) > {
104
- let mut writer_state = self . writer_state . lock ( ) . await ;
105
- PuffinWriter :: write_header_once ( & mut writer_state) . await ?;
106
- self . write_footer ( & mut writer_state) . await ?;
107
- writer_state. writer . close ( ) . await ?;
92
+ pub ( crate ) async fn close ( mut self ) -> Result < ( ) > {
93
+ self . write_header_once ( ) . await ?;
94
+ self . write_footer ( ) . await ?;
95
+ self . writer . close ( ) . await ?;
108
96
Ok ( ( ) )
109
97
}
110
98
111
- async fn write ( writer_state : & mut WriterState , bytes : Bytes ) -> Result < ( ) > {
99
+ async fn write ( & mut self , bytes : Bytes ) -> Result < ( ) > {
112
100
let length = bytes. len ( ) ;
113
- writer_state . writer . write ( bytes) . await ?;
114
- writer_state . num_bytes_written += length as u64 ;
101
+ self . writer . write ( bytes) . await ?;
102
+ self . num_bytes_written += length as u64 ;
115
103
Ok ( ( ) )
116
104
}
117
105
118
- async fn write_header_once ( writer_state : & mut WriterState ) -> Result < ( ) > {
119
- if !writer_state . is_header_written {
106
+ async fn write_header_once ( & mut self ) -> Result < ( ) > {
107
+ if !self . is_header_written {
120
108
let bytes = Bytes :: copy_from_slice ( & FileMetadata :: MAGIC ) ;
121
- PuffinWriter :: write ( writer_state , bytes) . await ?;
122
- writer_state . is_header_written = true ;
109
+ self . write ( bytes) . await ?;
110
+ self . is_header_written = true ;
123
111
}
124
112
Ok ( ( ) )
125
113
}
@@ -143,7 +131,7 @@ impl PuffinWriter {
143
131
result
144
132
}
145
133
146
- async fn write_footer ( & self , writer_state : & mut WriterState ) -> Result < ( ) > {
134
+ async fn write_footer ( & mut self ) -> Result < ( ) > {
147
135
let mut footer_payload_bytes = self . footer_payload_bytes ( ) ?;
148
136
let footer_payload_bytes_length = u32:: to_le_bytes ( footer_payload_bytes. len ( ) . try_into ( ) ?) ;
149
137
@@ -154,7 +142,7 @@ impl PuffinWriter {
154
142
footer_bytes. extend ( self . flags_bytes ( ) ) ;
155
143
footer_bytes. extend ( & FileMetadata :: MAGIC ) ;
156
144
157
- PuffinWriter :: write ( writer_state , footer_bytes. into ( ) ) . await
145
+ self . write ( footer_bytes. into ( ) ) . await
158
146
}
159
147
}
160
148
@@ -178,50 +166,6 @@ mod tests {
178
166
use crate :: puffin:: writer:: PuffinWriter ;
179
167
use crate :: Result ;
180
168
181
- #[ tokio:: test]
182
- async fn test_throws_error_if_attempt_to_add_blob_after_closing ( ) {
183
- let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
184
-
185
- let file_name = "temp_puffin.bin" ;
186
- let full_path = format ! ( "{}/{}" , temp_dir. path( ) . to_str( ) . unwrap( ) , file_name) ;
187
-
188
- let file_io = FileIOBuilder :: new_fs_io ( ) . build ( ) . unwrap ( ) ;
189
- let output_file = file_io. new_output ( full_path) . unwrap ( ) ;
190
- let mut writer = PuffinWriter :: new ( & output_file, HashMap :: new ( ) , false )
191
- . await
192
- . unwrap ( ) ;
193
- writer. close ( ) . await . unwrap ( ) ;
194
-
195
- assert_eq ! (
196
- writer
197
- . add( blob_0( ) , CompressionCodec :: None )
198
- . await
199
- . unwrap_err( )
200
- . to_string( ) ,
201
- "Unexpected => Failure in doing io operation, source: Unexpected (persistent) at => writer has been closed or aborted" ,
202
- )
203
- }
204
-
205
- #[ tokio:: test]
206
- async fn test_throws_error_if_attempt_to_close_multiple_times ( ) {
207
- let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
208
-
209
- let file_name = "temp_puffin.bin" ;
210
- let full_path = format ! ( "{}/{}" , temp_dir. path( ) . to_str( ) . unwrap( ) , file_name) ;
211
-
212
- let file_io = FileIOBuilder :: new_fs_io ( ) . build ( ) . unwrap ( ) ;
213
- let output_file = file_io. new_output ( full_path) . unwrap ( ) ;
214
- let mut writer = PuffinWriter :: new ( & output_file, HashMap :: new ( ) , false )
215
- . await
216
- . unwrap ( ) ;
217
- writer. close ( ) . await . unwrap ( ) ;
218
-
219
- assert_eq ! (
220
- writer. close( ) . await . unwrap_err( ) . to_string( ) ,
221
- "Unexpected => Failure in doing io operation, source: Unexpected (persistent) at => writer has been closed or aborted" ,
222
- )
223
- }
224
-
225
169
async fn write_puffin_file (
226
170
temp_dir : & TempDir ,
227
171
blobs : Vec < ( Blob , CompressionCodec ) > ,
0 commit comments