|
10 | 10 | -export([erase/1, init/1, reset_state/1, recover/4, |
11 | 11 | bounds/2, next_segment_boundary/1, info/1, |
12 | 12 | terminate/3, delete_and_terminate/1, |
13 | | - publish/7, ack/2, read/3, |
| 13 | + publish/7, ack/2, tune_read/2, read/3, |
14 | 14 | sync/1, needs_sync/1]). |
15 | 15 |
|
16 | 16 | %% Recovery. Unlike other functions in this module, these |
@@ -1067,6 +1067,52 @@ bounds(State = #qi{ segments = Segments }, NextSeqIdHint) -> |
1067 | 1067 | %% The next_segment_boundary/1 function is used internally when |
1068 | 1068 | %% reading. It should not be called from rabbit_variable_queue. |
1069 | 1069 |
|
| 1070 | +%% @todo OK so segment boundaries are still good but we need |
| 1071 | +%% to be smarter about them. The queue can give the |
| 1072 | +%% read it is about to do and the index can decide to |
| 1073 | +%% lower or increase the limit to match segments (so |
| 1074 | +%% if we are close to a segment we increase otherwise |
| 1075 | +%% we lower, based on how many reads are requested). |
| 1076 | + |
| 1077 | +-spec tune_read(rabbit_variable_queue:seq_id(), rabbit_variable_queue:seq_id()) |
| 1078 | + -> rabbit_variable_queue:seq_id(). |
| 1079 | + |
| 1080 | +tune_read(FromSeqId, ToSeqId) |
| 1081 | + when FromSeqId =:= ToSeqId -> |
| 1082 | + %% Nothing will be read as From is inclusive but To is exclusive. |
| 1083 | + ToSeqId; |
| 1084 | +tune_read(FromSeqId, ToSeqId) -> |
| 1085 | + %% How much we are reading. |
| 1086 | + ReqCount = ToSeqId - FromSeqId, |
| 1087 | + %% How much remains in the current segment. |
| 1088 | + NextSeqId = next_segment_boundary(FromSeqId), |
| 1089 | + RemCount = NextSeqId - FromSeqId, |
| 1090 | + %% How much we are willing to accept as extra messages to read. |
| 1091 | + Threshold = max(1, ReqCount div 7), |
| 1092 | + if |
| 1093 | + %% There are messages remaining in the segment, and the number |
| 1094 | + %% of messages remaining is less than the threshold: read up |
| 1095 | + %% to the end of the segment (To is exclusive). |
| 1096 | + (RemCount >= ReqCount) andalso (RemCount - ReqCount =< Threshold) -> |
| 1097 | + NextSeqId; |
| 1098 | + %% There are messages remaining in the segment but the number |
| 1099 | + %% of messages remaining is more than we are willing to read: |
| 1100 | + %% only read what was originally requested. |
| 1101 | + (RemCount >= ReqCount) -> |
| 1102 | + ToSeqId; |
| 1103 | + %% We are requested to read past the end of the current segment. |
| 1104 | + %% This would require us to read from two different segments, |
| 1105 | + %% which we only want to do if this involves a good number of |
| 1106 | + %% messages. If this number is below the threshold, we reduce |
| 1107 | + %% the number of messages to read. |
| 1108 | + (ReqCount - RemCount =< Threshold) -> |
| 1109 | + NextSeqId; |
| 1110 | + %% Otherwise we cross over into the next segment, meaning we |
| 1111 | + %% only read what was originally requested. |
| 1112 | + true -> |
| 1113 | + ToSeqId |
| 1114 | + end. |
| 1115 | + |
1070 | 1116 | -spec next_segment_boundary(SeqId) -> SeqId when SeqId::rabbit_variable_queue:seq_id(). |
1071 | 1117 |
|
1072 | 1118 | next_segment_boundary(SeqId) -> |
|
0 commit comments