Fix 2i/transact w/new expiry code

The new expiry code changed per-entry time stamp
from being the write-time to be the expiry-time.
This change in semantics was not reflected in the
code pertaining to hanoidb:transact, and so all
entries written with 2i would be immediately
expired.
This commit is contained in:
Kresten Krab Thorup 2012-09-10 00:07:38 +02:00
parent ef64425af3
commit eab04ff91f
2 changed files with 33 additions and 11 deletions

View file

@ -178,7 +178,7 @@ lookup(Key, #nursery{cache=Cache}) ->
%% @end %% @end
-spec finish(Nursery::#nursery{}, TopLevel::pid()) -> ok. -spec finish(Nursery::#nursery{}, TopLevel::pid()) -> ok.
finish(#nursery{ dir=Dir, cache=Cache, log_file=LogFile, merge_done=DoneMerge, 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), hanoidb_util:ensure_expiry(Config),
@ -264,19 +264,36 @@ ensure_space(Nursery, NeededRoom, Top) ->
flush(Nursery, Top) flush(Nursery, Top)
end. 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), Nursery1 = ensure_space(Nursery, length(Spec), Top),
TStamp = hanoidb_util:tstamp(), Expiry =
Data = hanoidb_util:crc_encapsulate_transaction(Spec, TStamp), 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), ok = file:write(File, Data),
Nursery2 = do_sync(File, Nursery1), Nursery2 = do_sync(File, Nursery1),
Cache2 = lists:foldl(fun({put, Key, Value}, Cache) -> 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) -> ({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, end,
Cache0, Cache0,
Spec), Spec),
@ -344,7 +361,7 @@ is_expired({_Value, TStamp}) ->
is_expired(Bin) when is_binary(Bin) -> is_expired(Bin) when is_binary(Bin) ->
false. false.
get_value({Value, TStamp}) when is_integer(TStamp) -> get_value({Value, TStamp}) when is_integer(TStamp); TStamp =:= infinity ->
Value; Value;
get_value(Value) when Value =:= ?TOMBSTONE; is_binary(Value) -> get_value(Value) when Value =:= ?TOMBSTONE; is_binary(Value) ->
Value. Value.

View file

@ -146,6 +146,8 @@ decode_index_node(Level, Data) ->
{ok, {node, Level, KVList}}. {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_kv_entry(Key, {?TOMBSTONE, TStamp}) -> %
crc_encapsulate( [?TAG_DELETED2, <<TStamp:32>> | Key] ); crc_encapsulate( [?TAG_DELETED2, <<TStamp:32>> | Key] );
crc_encapsulate_kv_entry(Key, ?TOMBSTONE) -> 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, <<Pos:64/unsigned, Len:32/unsigned>>, Key] ). crc_encapsulate( [?TAG_POSLEN32, <<Pos:64/unsigned, Len:32/unsigned>>, Key] ).
crc_encapsulate_transaction(TransactionSpec, TStamp) -> crc_encapsulate_transaction(TransactionSpec, Expiry) ->
crc_encapsulate([?TAG_TRANSACT | crc_encapsulate([?TAG_TRANSACT |
lists:map(fun({delete, Key}) -> lists:map(fun({delete, Key}) ->
crc_encapsulate_kv_entry(Key, {?TOMBSTONE, TStamp}); crc_encapsulate_kv_entry(Key, {?TOMBSTONE, Expiry});
({put, Key, Value}) -> ({put, Key, Value}) ->
crc_encapsulate_kv_entry(Key, {Value, TStamp}) crc_encapsulate_kv_entry(Key, {Value, Expiry})
end, end,
TransactionSpec)]). TransactionSpec)]).
@ -239,7 +241,10 @@ expiry_time(ExpirySecs) when ExpirySecs > 0 ->
-spec has_expired(pos_integer()) -> true|false. -spec has_expired(pos_integer()) -> true|false.
has_expired(Expiration) when Expiration > 0 -> has_expired(Expiration) when Expiration > 0 ->
Expiration < tstamp(). Expiration < tstamp();
has_expired(infinity) ->
false.
ensure_expiry(Opts) -> ensure_expiry(Opts) ->
case hanoidb:get_opt(expiry_secs, Opts) of case hanoidb:get_opt(expiry_secs, Opts) of