summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2015-01-20 14:55:12 +0000
committerSimon MacMullen <simon@rabbitmq.com>2015-01-20 14:55:12 +0000
commit7d794dd70df7c0be0809d89ada7884230189968c (patch)
treef39f6547b3c70d633b946467c15f00c053b01237 /src
parentf4381b01abe5f3e24439adcff49bbe76c7b08abd (diff)
downloadrabbitmq-server-git-7d794dd70df7c0be0809d89ada7884230189968c.tar.gz
Improve the performance of determine_persist_to/2, stop it being a hotspot.
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_variable_queue.erl28
-rw-r--r--src/truncate.erl2
2 files changed, 24 insertions, 6 deletions
diff --git a/src/rabbit_variable_queue.erl b/src/rabbit_variable_queue.erl
index d772d69bcc..57fad266b4 100644
--- a/src/rabbit_variable_queue.erl
+++ b/src/rabbit_variable_queue.erl
@@ -320,11 +320,13 @@
%% betas, the IO_BATCH_SIZE sets the number of betas that we must be
%% due to write indices for before we do any work at all.
-define(IO_BATCH_SIZE, 2048). %% next power-of-2 after ?CREDIT_DISC_BOUND
+-define(HEADER_GUESS_SIZE, 100). %% see determine_persist_to/2
-define(PERSISTENT_MSG_STORE, msg_store_persistent).
-define(TRANSIENT_MSG_STORE, msg_store_transient).
-define(QUEUE, lqueue).
-include("rabbit.hrl").
+-include("rabbit_framing.hrl").
%%----------------------------------------------------------------------------
@@ -1404,17 +1406,33 @@ maybe_write_to_disk(ForceMsg, ForceIndex, MsgStatus,
maybe_write_index_to_disk(ForceIndex, MsgStatus1, IndexState),
{MsgStatus2, State #vqstate { index_state = IndexState1 }}.
-determine_persist_to(Msg, #message_properties{size = Size}) ->
+determine_persist_to(#basic_message{
+ content = #content{properties = Props,
+ properties_bin = PropsBin}},
+ #message_properties{size = BodySize}) ->
{ok, IndexMaxSize} = application:get_env(
rabbit, queue_index_embed_msgs_below),
%% The >= is so that you can set the env to 0 and never persist
%% to the index.
%%
- %% We avoid invoking exceeds_size/2 if the message is large
- %% anyway.
- case Size >= IndexMaxSize of
+ %% We want this to be fast, so we avoid size(term_to_binary())
+ %% here, or using the term size estimation from truncate.erl, both
+ %% of which are too slow. So instead, if the message body size
+ %% goes over the limit then we avoid any other checks.
+ %%
+ %% If it doesn't we need to decide if the properties will push
+ %% it past the limit. If we have the encoded properties (usual
+ %% case) we can just check their size. If we don't (message came
+ %% via the direct client), we make a guess based on the number of
+ %% headers.
+ case BodySize >= IndexMaxSize of
true -> msg_store;
- false -> case truncate:exceeds_size(Msg, IndexMaxSize) of
+ false -> Est = case is_binary(PropsBin) of
+ true -> BodySize + size(PropsBin);
+ false -> #'P_basic'{headers = Hs} = Props,
+ length(Hs) * ?HEADER_GUESS_SIZE + BodySize
+ end,
+ case Est >= IndexMaxSize of
true -> msg_store;
false -> queue_index
end
diff --git a/src/truncate.erl b/src/truncate.erl
index 952ed2443c..1b4d957d0b 100644
--- a/src/truncate.erl
+++ b/src/truncate.erl
@@ -20,7 +20,7 @@
-record(params, {content, struct, content_dec, struct_dec}).
--export([log_event/2, term/2, exceeds_size/2]).
+-export([log_event/2, term/2]).
%% exported for testing
-export([test/0]).