diff --git a/src/hanoidb_nursery.erl b/src/hanoidb_nursery.erl index 9d222ba..40b4f82 100644 --- a/src/hanoidb_nursery.erl +++ b/src/hanoidb_nursery.erl @@ -178,7 +178,7 @@ lookup(Key, #nursery{cache=Cache}) -> %% @end -spec finish(Nursery::#nursery{}, TopLevel::pid()) -> ok. finish(#nursery{ dir=Dir, cache=Cache, log_file=LogFile, merge_done=DoneMerge, - count=Count, config=Config }=Nursery, TopLevel) -> + count=Count, config=Config }, TopLevel) -> hanoidb_util:ensure_expiry(Config), @@ -264,19 +264,36 @@ ensure_space(Nursery, NeededRoom, Top) -> flush(Nursery, Top) end. -transact(Spec, Nursery=#nursery{ log_file=File, cache=Cache0, total_size=TotalSize }, Top) -> +transact(Spec, Nursery=#nursery{ log_file=File, cache=Cache0, total_size=TotalSize, config=Config }, Top) -> Nursery1 = ensure_space(Nursery, length(Spec), Top), - TStamp = hanoidb_util:tstamp(), - Data = hanoidb_util:crc_encapsulate_transaction(Spec, TStamp), + Expiry = + case hanoidb:get_opt(expiry_secs, Config) of + 0 -> + infinity; + DatabaseExpiryTime -> + hanoidb_util:expiry_time(DatabaseExpiryTime) + end, + + Data = hanoidb_util:crc_encapsulate_transaction(Spec, Expiry), ok = file:write(File, Data), Nursery2 = do_sync(File, Nursery1), Cache2 = lists:foldl(fun({put, Key, Value}, Cache) -> - gb_trees:enter(Key, {Value, TStamp}, Cache); + case Expiry of + infinity -> + gb_trees:enter(Key, Value, Cache); + _ -> + gb_trees:enter(Key, {Value, Expiry}, Cache) + end; ({delete, Key}, Cache) -> - gb_trees:enter(Key, {?TOMBSTONE, TStamp}, Cache) + case Expiry of + infinity -> + gb_trees:enter(Key, ?TOMBSTONE, Cache); + _ -> + gb_trees:enter(Key, {?TOMBSTONE, Expiry}, Cache) + end end, Cache0, Spec), @@ -344,7 +361,7 @@ is_expired({_Value, TStamp}) -> is_expired(Bin) when is_binary(Bin) -> false. -get_value({Value, TStamp}) when is_integer(TStamp) -> +get_value({Value, TStamp}) when is_integer(TStamp); TStamp =:= infinity -> Value; get_value(Value) when Value =:= ?TOMBSTONE; is_binary(Value) -> Value. diff --git a/src/hanoidb_util.erl b/src/hanoidb_util.erl index 9c08677..be6add6 100644 --- a/src/hanoidb_util.erl +++ b/src/hanoidb_util.erl @@ -146,6 +146,8 @@ decode_index_node(Level, Data) -> {ok, {node, Level, KVList}}. +crc_encapsulate_kv_entry(Key, {Value, infinity}) -> + crc_encapsulate_kv_entry(Key, Value); crc_encapsulate_kv_entry(Key, {?TOMBSTONE, TStamp}) -> % crc_encapsulate( [?TAG_DELETED2, <> | Key] ); crc_encapsulate_kv_entry(Key, ?TOMBSTONE) -> @@ -158,12 +160,12 @@ crc_encapsulate_kv_entry(Key, {Pos,Len}) when Len < 16#ffffffff -> crc_encapsulate( [?TAG_POSLEN32, <>, Key] ). -crc_encapsulate_transaction(TransactionSpec, TStamp) -> +crc_encapsulate_transaction(TransactionSpec, Expiry) -> crc_encapsulate([?TAG_TRANSACT | lists:map(fun({delete, Key}) -> - crc_encapsulate_kv_entry(Key, {?TOMBSTONE, TStamp}); + crc_encapsulate_kv_entry(Key, {?TOMBSTONE, Expiry}); ({put, Key, Value}) -> - crc_encapsulate_kv_entry(Key, {Value, TStamp}) + crc_encapsulate_kv_entry(Key, {Value, Expiry}) end, TransactionSpec)]). @@ -239,7 +241,10 @@ expiry_time(ExpirySecs) when ExpirySecs > 0 -> -spec has_expired(pos_integer()) -> true|false. has_expired(Expiration) when Expiration > 0 -> - Expiration < tstamp(). + Expiration < tstamp(); +has_expired(infinity) -> + false. + ensure_expiry(Opts) -> case hanoidb:get_opt(expiry_secs, Opts) of