82
82
83
83
-type errno_atom () :: atom (). % POSIX errno as atom
84
84
85
+
85
86
-spec init () ->
86
87
ok | {error , any ()}.
87
- -spec keydir_new () -> {ok , reference ()}.
88
- -spec keydir_new (string ()) ->
89
- {ok , reference ()} |
90
- {ready , reference ()} | {not_ready , reference ()} |
91
- {error , not_ready }.
92
- -spec maybe_keydir_new (string ()) ->
93
- {ready , reference ()} |
94
- {error , not_ready }.
95
- -spec keydir_mark_ready (reference ()) ->
96
- ok .
97
- -spec keydir_put (reference (), binary (), integer (), integer (),
98
- integer (), integer (), integer ()) ->
99
- ok | already_exists .
100
- -spec keydir_put (reference (), binary (), integer (), integer (),
101
- integer (), integer (), integer (), boolean ()) ->
102
- ok | already_exists .
103
- -spec keydir_put (reference (), binary (), integer (), integer (),
104
- integer (), integer (), integer (), integer (), integer ()) ->
105
- ok | already_exists .
106
- -spec keydir_put_int (reference (), binary (), integer (), integer (),
107
- binary (), integer (), 0 | 1 , integer (), integer (), binary ()) ->
108
- ok | already_exists .
109
- -spec keydir_get (reference (), binary ()) ->
110
- not_found | # bitcask_entry {}.
111
- -spec keydir_get (reference (), binary (), integer ()) ->
112
- not_found | # bitcask_entry {}.
113
- -spec keydir_get_int (reference (), binary (), integer ()) ->
114
- not_found | # bitcask_entry {}.
115
- -spec keydir_remove (reference (), binary ()) ->
116
- ok | already_exists .
117
- -spec keydir_remove (reference (), binary (), integer (), integer (), integer ()) ->
118
- ok | already_exists .
119
- -spec keydir_copy (reference ()) ->
120
- {ok , reference ()}.
121
- -spec keydir_itr (reference (), integer (), integer ()) ->
122
- ok | out_of_date | {error , iteration_in_process }.
123
- -spec keydir_itr_next (reference ()) ->
124
- # bitcask_entry {} |
125
- {error , iteration_not_started } | allocation_error | not_found .
126
- -spec keydir_itr_release (reference ()) ->
127
- ok .
128
- -spec increment_file_id (reference ()) ->
129
- {ok , non_neg_integer ()}.
130
- -spec increment_file_id (reference (), non_neg_integer ()) ->
131
- {ok , non_neg_integer ()}.
132
- -spec keydir_fold (reference (), fun ((any (), any ()) -> any ()), any (),
133
- integer (), integer ()) ->
134
- any () | {error , any ()}.
135
- -spec keydir_info (reference ()) ->
136
- {integer (), integer (),
137
- [{integer (), integer (), integer (), integer (), integer (),
138
- integer (), integer (), integer ()}],
139
- {integer (), integer (), boolean (), 'undefined' |integer ()},
140
- non_neg_integer ()}.
141
- -spec keydir_release (reference ()) ->
142
- ok .
143
- -spec keydir_trim_fstats (reference (), [integer ()]) ->
144
- {ok , integer ()} | {error , atom ()}.
145
- -spec update_fstats (reference (), non_neg_integer (), non_neg_integer (),
146
- integer (), integer (), integer (), integer (), integer () ) ->
147
- ok .
148
- -spec set_pending_delete (reference (), non_neg_integer ()) ->
149
- ok .
150
- -spec lock_acquire (string (), integer ()) ->
151
- {ok , reference ()} | {error , atom ()}.
152
- -spec lock_release (reference ()) ->
153
- ok .
154
- -spec lock_readdata (reference ()) ->
155
- {ok , binary ()} |
156
- {fstat_error , integer ()} | {error , allocation_error } |
157
- {pread_error , integer ()}.
158
- -spec lock_writedata (reference (), binary ()) ->
159
- ok |
160
- {ftruncate_error , errno_atom ()} | {pwrite_error , errno_atom ()} |
161
- {error , lock_not_writable }.
162
-
163
88
init () ->
164
89
case code :priv_dir (bitcask ) of
165
90
{error , bad_name } ->
@@ -170,7 +95,7 @@ init() ->
170
95
SoName = filename :join (" ../priv" , " bitcask" )
171
96
end ;
172
97
Dir ->
173
- SoName = filename :join (Dir , " bitcask" )
98
+ SoName = filename :join (Dir , " bitcask" )
174
99
end ,
175
100
erlang :load_nif (SoName , 0 ).
176
101
@@ -182,31 +107,50 @@ set_pulse_pid(_Pid) ->
182
107
% % ===================================================================
183
108
% % Internal functions
184
109
% % ===================================================================
185
- % %
110
+ % %
186
111
% % Most of the functions below are actually defined in c_src/bitcask_nifs.c
187
112
% % See that file for the real functionality of the bitcask_nifs module.
188
113
% % The definitions here are only to satisfy trivial static analysis.
189
- % %
114
+ % %
190
115
191
116
117
+ -spec keydir_new () -> {ok , reference ()}.
192
118
keydir_new () ->
193
119
erlang :nif_error ({error , not_loaded }).
194
120
121
+ -spec keydir_new (string ()) ->
122
+ {ok , reference ()} |
123
+ {ready , reference ()} | {not_ready , reference ()} |
124
+ {error , not_ready }.
195
125
keydir_new (Name ) when is_list (Name ) ->
196
126
erlang :nif_error ({error , not_loaded }).
197
127
128
+ -spec maybe_keydir_new (string ()) ->
129
+ {ready , reference ()} |
130
+ {error , not_ready }.
198
131
maybe_keydir_new (Name ) when is_list (Name ) ->
199
132
erlang :nif_error ({error , not_loaded }).
200
133
134
+ -spec keydir_mark_ready (reference ()) ->
135
+ ok .
201
136
keydir_mark_ready (_Ref ) ->
202
137
erlang :nif_error ({error , not_loaded }).
203
138
139
+ -spec keydir_put (reference (), binary (), integer (), integer (),
140
+ integer (), integer (), integer ()) ->
141
+ ok | already_exists .
204
142
keydir_put (Ref , Key , FileId , TotalSz , Offset , Tstamp , NowSec ) ->
205
143
keydir_put (Ref , Key , FileId , TotalSz , Offset , Tstamp , NowSec , false ).
206
144
145
+ -spec keydir_put (reference (), binary (), integer (), integer (),
146
+ integer (), integer (), integer (), boolean ()) ->
147
+ ok | already_exists .
207
148
keydir_put (Ref , Key , FileId , TotalSz , Offset , Tstamp , NowSec , NewestPutB ) ->
208
149
keydir_put (Ref , Key , FileId , TotalSz , Offset , Tstamp , NowSec , NewestPutB , 0 , 0 ).
209
150
151
+ -spec keydir_put (reference (), binary (), integer (), integer (),
152
+ integer (), integer (), integer (), integer (), integer ()) ->
153
+ ok | already_exists .
210
154
keydir_put (Ref , Key , FileId , TotalSz , Offset , Tstamp , NowSec , OldFileId , OldOffset ) ->
211
155
keydir_put (Ref , Key , FileId , TotalSz , Offset , Tstamp , NowSec , false ,
212
156
OldFileId , OldOffset ).
@@ -219,51 +163,71 @@ keydir_put(Ref, Key, FileId, TotalSz, Offset, Tstamp, NowSec, NewestPutB,
219
163
end ,
220
164
OldFileId , <<OldOffset :64 /unsigned -native >>).
221
165
166
+ -spec keydir_put_int (reference (), binary (), integer (), integer (),
167
+ binary (), integer (), 0 | 1 , integer (), integer (), binary ()) ->
168
+ ok | already_exists .
222
169
keydir_put_int (_Ref , _Key , _FileId , _TotalSz , _Offset , _Tstamp , _NowSec ,
223
170
_NewestPutI , _OldFileId , _OldOffset ) ->
224
171
erlang :nif_error ({error , not_loaded }).
225
172
173
+ -spec keydir_get (reference (), binary ()) ->
174
+ not_found | # bitcask_entry {}.
226
175
keydir_get (Ref , Key ) ->
227
176
keydir_get (Ref , Key , 16#ffffffffffffffff ).
228
177
178
+ -spec keydir_get (reference (), binary (), integer ()) ->
179
+ not_found | # bitcask_entry {}.
229
180
keydir_get (Ref , Key , Epoch ) ->
230
181
case keydir_get_int (Ref , Key , Epoch ) of
231
182
E when is_record (E , bitcask_entry ) ->
232
183
<<Offset :64 /unsigned -native >> = E # bitcask_entry .offset ,
233
184
E # bitcask_entry {offset = Offset };
234
- _ ->
185
+ _ ->
235
186
not_found
236
187
end .
237
188
189
+ -spec keydir_get_int (reference (), binary (), integer ()) ->
190
+ not_found | # bitcask_entry {}.
238
191
keydir_get_int (_Ref , _Key , _Epoch ) ->
239
192
erlang :nif_error ({error , not_loaded }).
240
193
241
194
keydir_get_epoch (_Ref ) ->
242
195
erlang :nif_error ({error , not_loaded }).
243
196
197
+ -spec keydir_remove (reference (), binary ()) ->
198
+ ok | already_exists .
244
199
keydir_remove (Ref , Key ) ->
245
200
keydir_remove (Ref , Key , bitcask_time :tstamp ()).
246
201
247
202
keydir_remove (_Ref , _Key , _TStamp ) ->
248
203
erlang :nif_error ({error , not_loaded }).
249
204
205
+ -spec keydir_remove (reference (), binary (), integer (), integer (), integer ()) ->
206
+ ok | already_exists .
250
207
keydir_remove (Ref , Key , Tstamp , FileId , Offset ) ->
251
- keydir_remove_int (Ref , Key , Tstamp , FileId , <<Offset :64 /unsigned -native >>,
208
+ keydir_remove_int (Ref , Key , Tstamp , FileId , <<Offset :64 /unsigned -native >>,
252
209
bitcask_time :tstamp ()).
253
210
254
211
keydir_remove_int (_Ref , _Key , _Tstamp , _FileId , _Offset , _TStamp ) ->
255
212
erlang :nif_error ({error , not_loaded }).
256
213
214
+ -spec keydir_copy (reference ()) ->
215
+ {ok , reference ()}.
257
216
keydir_copy (_Ref ) ->
258
217
erlang :nif_error ({error , not_loaded }).
259
218
219
+ -spec keydir_itr (reference (), integer (), integer ()) ->
220
+ ok | out_of_date | {error , iteration_in_process }.
260
221
keydir_itr (Ref , MaxAge , MaxPuts ) ->
261
222
TS = bitcask_time :tstamp (),
262
223
keydir_itr_int (Ref , TS , MaxAge , MaxPuts ).
263
224
264
225
keydir_itr_int (_Ref , _Ts , _MaxAge , _MaxPuts ) ->
265
226
erlang :nif_error ({error , not_loaded }).
266
227
228
+ -spec keydir_itr_next (reference ()) ->
229
+ # bitcask_entry {} |
230
+ {error , iteration_not_started } | allocation_error | not_found .
267
231
keydir_itr_next (Ref ) ->
268
232
case keydir_itr_next_int (Ref ) of
269
233
E when is_record (E , bitcask_entry ) ->
@@ -276,15 +240,24 @@ keydir_itr_next(Ref) ->
276
240
keydir_itr_next_int (_Ref ) ->
277
241
erlang :nif_error ({error , not_loaded }).
278
242
243
+ -spec keydir_itr_release (reference ()) ->
244
+ ok .
279
245
keydir_itr_release (_Ref ) ->
280
246
erlang :nif_error ({error , not_loaded }).
281
247
248
+ -spec increment_file_id (reference ()) ->
249
+ {ok , non_neg_integer ()}.
282
250
increment_file_id (_Ref ) ->
283
251
erlang :nif_error ({error , not_loaded }).
284
252
253
+ -spec increment_file_id (reference (), non_neg_integer ()) ->
254
+ {ok , non_neg_integer ()}.
285
255
increment_file_id (_Ref , _ConditionalFileId ) ->
286
256
erlang :nif_error ({error , not_loaded }).
287
257
258
+ -spec keydir_fold (reference (), fun ((any (), any ()) -> any ()), any (),
259
+ integer (), integer ()) ->
260
+ any () | {error , any ()}.
288
261
keydir_fold (Ref , Fun , Acc0 , MaxAge , MaxPuts ) ->
289
262
FrozenFun = fun () -> keydir_fold_cont (keydir_itr_next (Ref ), Ref , Fun , Acc0 ) end ,
290
263
keydir_frozen (Ref , FrozenFun , MaxAge , MaxPuts ).
@@ -308,7 +281,7 @@ keydir_frozen(Ref, FrozenFun, MaxAge, MaxPuts) ->
308
281
{error , Reason } ->
309
282
{error , Reason }
310
283
end .
311
-
284
+
312
285
% % Wait for any pending interation to complete
313
286
keydir_wait_pending (Ref ) ->
314
287
% % Create an iterator, passing a zero timestamp to force waiting for
@@ -357,44 +330,71 @@ keydir_wait_ready() ->
357
330
end .
358
331
-endif .
359
332
333
+ -spec keydir_info (reference ()) ->
334
+ {integer (), integer (),
335
+ [{integer (), integer (), integer (), integer (), integer (),
336
+ integer (), integer (), integer ()}],
337
+ {integer (), integer (), boolean (), 'undefined' |integer ()},
338
+ non_neg_integer ()}.
360
339
keydir_info (_Ref ) ->
361
340
erlang :nif_error ({error , not_loaded }).
362
341
342
+ -spec keydir_release (reference ()) ->
343
+ ok .
363
344
keydir_release (_Ref ) ->
364
345
erlang :nif_error ({error , not_loaded }).
365
346
347
+ -spec keydir_trim_fstats (reference (), [integer ()]) ->
348
+ {ok , integer ()} | {error , atom ()}.
366
349
keydir_trim_fstats (_Ref , _IDList ) ->
367
350
erlang :nif_error ({error , not_loaded }).
368
351
352
+ -spec update_fstats (reference (), non_neg_integer (), non_neg_integer (),
353
+ integer (), integer (), integer (), integer (), integer () ) ->
354
+ ok .
369
355
update_fstats (_Ref , _FileId , _Tstamp ,
370
356
_LiveKeyIncr , _TotalKeyIncr ,
371
357
_LiveIncr , _TotalIncr , _ShouldCreate ) ->
372
358
erlang :nif_error ({error , not_loaded }).
373
359
360
+ -spec set_pending_delete (reference (), non_neg_integer ()) ->
361
+ ok .
374
362
set_pending_delete (_Ref , _FileId ) ->
375
363
erlang :nif_error ({error , not_loaded }).
376
364
365
+ -spec lock_acquire (string (), integer ()) ->
366
+ {ok , reference ()} | {error , atom ()}.
377
367
lock_acquire (Filename , IsWriteLock ) ->
378
368
bitcask_bump :big (),
379
369
lock_acquire_int (Filename , IsWriteLock ).
380
370
381
371
lock_acquire_int (_Filename , _IsWriteLock ) ->
382
372
erlang :nif_error ({error , not_loaded }).
383
373
374
+ -spec lock_release (reference ()) ->
375
+ ok .
384
376
lock_release (Ref ) ->
385
377
bitcask_bump :big (),
386
378
lock_release_int (Ref ).
387
379
388
380
lock_release_int (_Ref ) ->
389
381
erlang :nif_error ({error , not_loaded }).
390
382
383
+ -spec lock_readdata (reference ()) ->
384
+ {ok , binary ()} |
385
+ {fstat_error , integer ()} | {error , allocation_error } |
386
+ {pread_error , integer ()}.
391
387
lock_readdata (Ref ) ->
392
388
bitcask_bump :big (),
393
389
lock_readdata_int (Ref ).
394
390
395
391
lock_readdata_int (_Ref ) ->
396
392
erlang :nif_error ({error , not_loaded }).
397
393
394
+ -spec lock_writedata (reference (), binary ()) ->
395
+ ok |
396
+ {ftruncate_error , errno_atom ()} | {pwrite_error , errno_atom ()} |
397
+ {error , lock_not_writable }.
398
398
lock_writedata (Ref , Data ) ->
399
399
bitcask_bump :big (),
400
400
lock_writedata_int (Ref , Data ).
@@ -610,7 +610,7 @@ keydir_del_while_pending_test2() ->
610
610
ok = keydir_put (Ref1 , Key , 0 , 1234 , 0 , T , bitcask_time :tstamp ()),
611
611
keydir_mark_ready (Ref1 ),
612
612
? assertEqual (# bitcask_entry {key = Key , file_id = 0 , total_sz = 1234 ,
613
- offset = <<0 :64 /unsigned -native >>, tstamp = T },
613
+ offset = <<0 :64 /unsigned -native >>, tstamp = T },
614
614
keydir_get_int (Ref1 , Key , 16#ffffffffffffffff )),
615
615
{ready , Ref2 } = keydir_new (Name ),
616
616
try
@@ -623,7 +623,7 @@ keydir_del_while_pending_test2() ->
623
623
% % Keep iterating on Ref2 and check result is [Key]
624
624
Fun = fun (IterKey , Acc ) -> [IterKey | Acc ] end ,
625
625
? assertEqual ([# bitcask_entry {key = Key , file_id = 0 , total_sz = 1234 ,
626
- offset = 0 , tstamp = T }],
626
+ offset = 0 , tstamp = T }],
627
627
keydir_fold_cont (keydir_itr_next (Ref2 ), Ref2 , Fun , []))
628
628
after
629
629
% % End iteration
@@ -647,7 +647,7 @@ keydir_create_del_while_pending_test2() ->
647
647
% % Delete Key
648
648
ok = keydir_put (Ref1 , Key , 0 , 1234 , 0 , 1 , bitcask_time :tstamp ()),
649
649
? assertEqual (# bitcask_entry {key = Key , file_id = 0 , total_sz = 1234 ,
650
- offset = <<0 :64 /unsigned -native >>, tstamp = 1 },
650
+ offset = <<0 :64 /unsigned -native >>, tstamp = 1 },
651
651
keydir_get_int (Ref1 , Key , 16#ffffffffffffffff )),
652
652
? assertEqual (ok , keydir_remove (Ref1 , Key )),
653
653
? assertEqual (not_found , keydir_get (Ref1 , Key )),
@@ -682,7 +682,7 @@ keydir_del_put_while_pending_test2() ->
682
682
? assertEqual (ok , keydir_remove (Ref1 , Key )),
683
683
ok = keydir_put (Ref1 , Key , 0 , 1234 , 0 , T + 2 , bitcask_time :tstamp ()),
684
684
? assertEqual (# bitcask_entry {key = Key , file_id = 0 , total_sz = 1234 ,
685
- offset = <<0 :64 /unsigned -native >>, tstamp = T + 2 },
685
+ offset = <<0 :64 /unsigned -native >>, tstamp = T + 2 },
686
686
keydir_get_int (Ref1 , Key , T + 2 )),
687
687
688
688
% % Keep iterating on Ref2 and check result is [] it was started after iter
@@ -694,7 +694,7 @@ keydir_del_put_while_pending_test2() ->
694
694
end ,
695
695
% % Check key is still present
696
696
? assertEqual (# bitcask_entry {key = Key , file_id = 0 , total_sz = 1234 ,
697
- offset = <<0 :64 /unsigned -native >>, tstamp = T + 2 },
697
+ offset = <<0 :64 /unsigned -native >>, tstamp = T + 2 },
698
698
keydir_get_int (Ref1 , Key , 16#ffffffffffffffff )).
699
699
700
700
keydir_multi_put_during_itr_test_ () ->
@@ -742,7 +742,7 @@ put_till_frozen(R, Name) ->
742
742
% %?debugFmt("keydir still OK", []),
743
743
bitcask_nifs :keydir_itr_release (Ref2 ),
744
744
put_till_frozen (R , Name );
745
- out_of_date ->
745
+ out_of_date ->
746
746
% %?debugFmt("keydir now frozen", []),
747
747
bitcask_nifs :keydir_itr_release (Ref2 ),
748
748
ok
@@ -782,7 +782,7 @@ keydir_itr_many_pending_test2() ->
782
782
783
783
clear_recv_buffer (Ct ) ->
784
784
receive
785
- _ ->
785
+ _ ->
786
786
clear_recv_buffer (Ct + 1 )
787
787
after 0 ->
788
788
ok % %?debugFmt("cleared ~p msgs", [Ct])
0 commit comments