@@ -177,7 +177,6 @@ bool PolicyAcross::validate(std::vector<LocalityEntry> const& solutionSet,
177
177
// Choose new servers from "least utilized" alsoServers and append the new servers to results
178
178
// fromserverse are the servers that have already been chosen and
179
179
// that should be excluded from being selected as replicas.
180
- // fromServers are the servers that must have;
181
180
// alsoServers are the servers you can choose.
182
181
bool PolicyAcross::selectReplicas (Reference<LocalitySet>& fromServers,
183
182
std::vector<LocalityEntry> const & alsoServers,
@@ -189,15 +188,17 @@ bool PolicyAcross::selectReplicas(Reference<LocalitySet>& fromServers,
189
188
int resultsInit = results.size ();
190
189
191
190
// Clear the member variables
191
+ AttribValue firstUsedValue, secondUsedValue;
192
192
_usedValues.clear ();
193
193
_newResults.clear ();
194
194
_addedResults.resize (_arena, 0 );
195
-
196
195
for (auto & alsoServer : alsoServers) {
197
196
auto value = fromServers->getValueViaGroupKey (alsoServer, groupIndexKey);
198
197
if (value.present ()) {
199
- if (!_usedValues.contains (value.get ())) {
200
- // _selected is a set of processes that have the same indexKey and indexValue (value)
198
+ auto lowerBound = std::lower_bound (_usedValues.begin (), _usedValues.end (), value.get ());
199
+ if ((firstUsedValue != value.get () && secondUsedValue != value.get ()) &&
200
+ ((lowerBound == _usedValues.end ()) || (*lowerBound != value.get ()))) {
201
+ // _selected is a set of processes that have the same indexKey and indexValue (value)
201
202
_selected = fromServers->restrict (indexKey, value.get ());
202
203
if (_selected->size ()) {
203
204
// Pass only the also array item which are valid for the value
@@ -211,7 +212,13 @@ bool PolicyAcross::selectReplicas(Reference<LocalitySet>& fromServers,
211
212
}
212
213
if (count >= _count)
213
214
break ;
214
- _usedValues.insert (value.get ());
215
+ if (firstUsedValue._id == -1 ) {
216
+ firstUsedValue = AttribValue (value.get ());
217
+ } else if (secondUsedValue._id == -1 ) {
218
+ secondUsedValue = AttribValue (value.get ());
219
+ } else {
220
+ _usedValues.insert (lowerBound, value.get ());
221
+ }
215
222
}
216
223
}
217
224
}
@@ -256,14 +263,22 @@ bool PolicyAcross::selectReplicas(Reference<LocalitySet>& fromServers,
256
263
auto & entry = mutableArray[recordIndex];
257
264
auto value = fromServers->getValueViaGroupKey (entry, groupIndexKey);
258
265
if (value.present ()) {
259
- if (!_usedValues.contains (value.get ())) {
266
+ auto lowerBound = std::lower_bound (_usedValues.begin (), _usedValues.end (), value.get ());
267
+ if ((firstUsedValue != value.get () && secondUsedValue != value.get ()) &&
268
+ ((lowerBound == _usedValues.end ()) || (*lowerBound != value.get ()))) {
260
269
_selected = fromServers->restrict (indexKey, value.get ());
261
270
if (_selected->size ()) {
262
271
if (_policy->selectReplicas (_selected, emptyEntryArray, results)) {
263
272
count++;
264
273
if (count >= _count)
265
274
break ;
266
- _usedValues.insert (value.get ());
275
+ if (firstUsedValue._id == -1 ) {
276
+ firstUsedValue = AttribValue (value.get ());
277
+ } else if (secondUsedValue._id == -1 ) {
278
+ secondUsedValue = AttribValue (value.get ());
279
+ } else {
280
+ _usedValues.insert (lowerBound, value.get ());
281
+ }
267
282
}
268
283
}
269
284
}
0 commit comments