Skip to content

Commit

Permalink
random_score function - Added the index name and shard id to the rand…
Browse files Browse the repository at this point in the history
…omization, and improved the PRNG itself

Closes #3559
  • Loading branch information
uboness committed Aug 23, 2013
1 parent 109e294 commit 4b3a883
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ public Explanation explainFactor(int docId) {
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 {

Expand All @@ -84,15 +85,20 @@ static class PRNG {

public float random(int doc) {
if (doc == 0) {
doc = -17;
doc = 0xCAFEBAB;
}
return nextFloat() * (doc ^ 0xCAFEBAB);

long rand = doc;
rand |= rand << 32;
rand ^= rand;
return nextFloat(rand);
}

public float nextFloat() {
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;
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@
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;

/**
*
Expand Down Expand Up @@ -73,6 +72,17 @@ public ScoreFunction parse(QueryParseContext parseContext, XContentParser parser
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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,19 @@ public void distribution() throws Exception {

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++;
}
}

This comment has been minimized.

Copy link
@dadoonet

dadoonet Aug 23, 2013

Member

Why not using ESLogger in tests?
It's not really a concern here because this test is marked as Ignore.

This comment has been minimized.

Copy link
@uboness

uboness Aug 23, 2013

Author Contributor

It's not a test but just a small script do show the distribution of the rand.... it's here so we won't need to write it again in case we change the prng


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;
Expand Down

0 comments on commit 4b3a883

Please sign in to comment.