random_score function - Added the index name and shard id to the randomization, and improved the PRNG itself
Closes #3559
This commit is contained in:
parent
109e2944f2
commit
4b3a883111
|
@ -64,9 +64,10 @@ public class RandomScoreFunction implements ScoreFunction {
|
|||
return exp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Algorithm based on {@link java.util.Random} except this one is not
|
||||
* thread safe
|
||||
* Algorithm largely based on {@link java.util.Random} except this one is not
|
||||
* thread safe and it incorporates the doc id on next();
|
||||
*/
|
||||
static class PRNG {
|
||||
|
||||
|
@ -84,15 +85,20 @@ public class RandomScoreFunction implements ScoreFunction {
|
|||
|
||||
public float random(int doc) {
|
||||
if (doc == 0) {
|
||||
doc = -17;
|
||||
}
|
||||
return nextFloat() * (doc ^ 0xCAFEBAB);
|
||||
doc = 0xCAFEBAB;
|
||||
}
|
||||
|
||||
public float nextFloat() {
|
||||
long rand = doc;
|
||||
rand |= rand << 32;
|
||||
rand ^= rand;
|
||||
return nextFloat(rand);
|
||||
}
|
||||
|
||||
public float nextFloat(long rand) {
|
||||
seed = (seed * multiplier + addend) & mask;
|
||||
int r = (int)(seed >>> 24);
|
||||
return r / ((float)(1 << 24));
|
||||
rand ^= seed;
|
||||
double result = rand / (double)(1L << 54);
|
||||
return (float) result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,15 +24,14 @@ package org.elasticsearch.index.query.functionscore.random;
|
|||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.lucene.search.function.RandomScoreFunction;
|
||||
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
|
||||
import org.elasticsearch.common.lucene.search.function.ScriptScoreFunction;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
import org.elasticsearch.index.query.QueryParsingException;
|
||||
import org.elasticsearch.index.query.functionscore.ScoreFunctionParser;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -73,6 +72,17 @@ public class RandomScoreFunctionParser implements ScoreFunctionParser {
|
|||
seed = parseContext.nowInMillis();
|
||||
}
|
||||
|
||||
ShardId shardId = SearchContext.current().indexShard().shardId();
|
||||
seed = salt(seed, shardId.index().name(), shardId.id());
|
||||
|
||||
return new RandomScoreFunction(seed);
|
||||
}
|
||||
|
||||
public static long salt(long seed, String index, int shardId) {
|
||||
long salt = index.hashCode();
|
||||
salt = salt << 32;
|
||||
salt |= shardId;
|
||||
return salt^seed;
|
||||
}
|
||||
|
||||
}
|
|
@ -107,15 +107,19 @@ public class RandomScoreFunctionTests extends AbstractSharedClusterTest {
|
|||
|
||||
int filled = 0;
|
||||
int maxRepeat = 0;
|
||||
int sumRepeat = 0;
|
||||
for (int i = 0; i < matrix.length; i++) {
|
||||
int value = matrix[i];
|
||||
sumRepeat += value;
|
||||
maxRepeat = Math.max(maxRepeat, value);
|
||||
if (value > 0) {
|
||||
filled++;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.println("max repeat: " + maxRepeat);
|
||||
System.out.println("avg repeat: " + sumRepeat / (double)filled);
|
||||
System.out.println("distribution: " + filled/(double)count);
|
||||
|
||||
int percentile50 = filled / 2;
|
||||
|
|
Loading…
Reference in New Issue