@@ -177,7 +177,6 @@ bool PolicyAcross::validate(std::vector<LocalityEntry> const& solutionSet,
177177// Choose new servers from "least utilized" alsoServers and append the new servers to results
178178// fromserverse are the servers that have already been chosen and
179179// that should be excluded from being selected as replicas.
180- // fromServers are the servers that must have;
181180// alsoServers are the servers you can choose.
182181bool PolicyAcross::selectReplicas (Reference<LocalitySet>& fromServers,
183182 std::vector<LocalityEntry> const & alsoServers,
@@ -189,15 +188,17 @@ bool PolicyAcross::selectReplicas(Reference<LocalitySet>& fromServers,
189188 int resultsInit = results.size ();
190189
191190 // Clear the member variables
191+ AttribValue firstUsedValue, secondUsedValue;
192192 _usedValues.clear ();
193193 _newResults.clear ();
194194 _addedResults.resize (_arena, 0 );
195-
196195 for (auto & alsoServer : alsoServers) {
197196 auto value = fromServers->getValueViaGroupKey (alsoServer, groupIndexKey);
198197 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)
201202 _selected = fromServers->restrict (indexKey, value.get ());
202203 if (_selected->size ()) {
203204 // Pass only the also array item which are valid for the value
@@ -211,7 +212,13 @@ bool PolicyAcross::selectReplicas(Reference<LocalitySet>& fromServers,
211212 }
212213 if (count >= _count)
213214 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+ }
215222 }
216223 }
217224 }
@@ -256,14 +263,22 @@ bool PolicyAcross::selectReplicas(Reference<LocalitySet>& fromServers,
256263 auto & entry = mutableArray[recordIndex];
257264 auto value = fromServers->getValueViaGroupKey (entry, groupIndexKey);
258265 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 ()))) {
260269 _selected = fromServers->restrict (indexKey, value.get ());
261270 if (_selected->size ()) {
262271 if (_policy->selectReplicas (_selected, emptyEntryArray, results)) {
263272 count++;
264273 if (count >= _count)
265274 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+ }
267282 }
268283 }
269284 }
0 commit comments