summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sackman <matthew@rabbitmq.com>2010-08-18 22:10:07 +0100
committerMatthew Sackman <matthew@rabbitmq.com>2010-08-18 22:10:07 +0100
commita3b6cd2e2747abcdac404ff95e35917c7c0efda7 (patch)
treeebbfc6025e4d5112f152ccacd6e70a51e597829d
parent88d681c1f724586b7036bfafb6effb660cd28bef (diff)
downloadrabbitmq-server-bug23142.tar.gz
Cope with removes overtaking writesbug23142
-rw-r--r--src/rabbit_msg_store.erl84
1 files changed, 47 insertions, 37 deletions
diff --git a/src/rabbit_msg_store.erl b/src/rabbit_msg_store.erl
index 94775e26..68e19f24 100644
--- a/src/rabbit_msg_store.erl
+++ b/src/rabbit_msg_store.erl
@@ -899,43 +899,53 @@ contains_message(Guid, From, State = #msstate { gc_active = GCActive }) ->
end
end.
-remove_message(Guid, State = #msstate { sum_valid_data = SumValid,
- file_summary_ets = FileSummaryEts,
- dedup_cache_ets = DedupCacheEts }) ->
- #msg_location { ref_count = RefCount, file = File,
- offset = Offset, total_size = TotalSize } =
- index_lookup(Guid, State),
- case RefCount of
- 1 ->
- %% don't remove from CUR_FILE_CACHE_ETS_NAME here because
- %% there may be further writes in the mailbox for the same
- %% msg.
- ok = remove_cache_entry(DedupCacheEts, Guid),
- [#file_summary { valid_total_size = ValidTotalSize,
- contiguous_top = ContiguousTop,
- locked = Locked }] =
- ets:lookup(FileSummaryEts, File),
- case Locked of
- true ->
- add_to_pending_gc_completion({remove, Guid}, State);
- false ->
- ok = index_delete(Guid, State),
- ContiguousTop1 = lists:min([ContiguousTop, Offset]),
- ValidTotalSize1 = ValidTotalSize - TotalSize,
- true = ets:update_element(
- FileSummaryEts, File,
- [{#file_summary.valid_total_size, ValidTotalSize1},
- {#file_summary.contiguous_top, ContiguousTop1}]),
- State1 = delete_file_if_empty(File, State),
- State1 #msstate { sum_valid_data = SumValid - TotalSize }
- end;
- _ when 1 < RefCount ->
- ok = decrement_cache(DedupCacheEts, Guid),
- %% only update field, otherwise bad interaction with concurrent GC
- ok = index_update_fields(Guid,
- {#msg_location.ref_count, RefCount - 1},
- State),
- State
+remove_message(Guid, State = #msstate { cur_file_cache_ets = CurFileCacheEts,
+ sum_valid_data = SumValid,
+ file_summary_ets = FileSummaryEts,
+ dedup_cache_ets = DedupCacheEts }) ->
+ case index_lookup(Guid, State) of
+ not_found ->
+ true = 0 =< ets:update_counter(CurFileCacheEts, Guid, {3, -1}),
+ State;
+ #msg_location { ref_count = RefCount, file = File,
+ offset = Offset, total_size = TotalSize } ->
+ case RefCount of
+ 1 ->
+ %% don't remove from CUR_FILE_CACHE_ETS_NAME here
+ %% because there may be further writes in the
+ %% mailbox for the same msg.
+ ok = remove_cache_entry(DedupCacheEts, Guid),
+ [#file_summary { valid_total_size = ValidTotalSize,
+ contiguous_top = ContiguousTop,
+ locked = Locked }] =
+ ets:lookup(FileSummaryEts, File),
+ case Locked of
+ true ->
+ add_to_pending_gc_completion({remove, Guid},
+ State);
+ false ->
+ ok = index_delete(Guid, State),
+ ContiguousTop1 = lists:min([ContiguousTop, Offset]),
+ ValidTotalSize1 = ValidTotalSize - TotalSize,
+ true = ets:update_element(
+ FileSummaryEts, File,
+ [{#file_summary.valid_total_size,
+ ValidTotalSize1},
+ {#file_summary.contiguous_top,
+ ContiguousTop1}]),
+ State1 = delete_file_if_empty(File, State),
+ State1 #msstate {
+ sum_valid_data = SumValid - TotalSize }
+ end;
+ _ when 1 < RefCount ->
+ ok = decrement_cache(DedupCacheEts, Guid),
+ %% only update field, otherwise bad interaction
+ %% with concurrent GC
+ ok = index_update_fields(
+ Guid, {#msg_location.ref_count, RefCount - 1},
+ State),
+ State
+ end
end.
add_to_pending_gc_completion(