From 3d35b823cb64a505fab3e0c716362af2be349f7a Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Tue, 25 Jun 2013 19:04:25 -0600 Subject: [PATCH] Exactly index sortkey with Lucene Store sortkey as a long and implement the before and after operators as numeric range queries. This is a short-term hack until we have a better idea of how to handle pagination without relying on a made up string value stored on the change object. Change-Id: Ibf7a8be281da8cd9e7ccc08bba600bbc2e0e962c --- .../gerrit/lucene/LuceneChangeIndex.java | 16 +++++++++++ .../com/google/gerrit/server/ChangeUtil.java | 7 ++--- .../gerrit/server/index/ChangeField.java | 15 +++++++++- .../google/gerrit/server/index/FieldType.java | 4 +++ .../server/query/change/SortKeyPredicate.java | 28 +++++++++---------- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java index 7304e189a0..c46ce9b306 100644 --- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java +++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java @@ -44,6 +44,7 @@ import com.google.gerrit.server.query.QueryParseException; import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeDataSource; import com.google.gerrit.server.query.change.IndexRewriteImpl; +import com.google.gerrit.server.query.change.SortKeyPredicate; import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.ResultSet; @@ -52,6 +53,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.IntField; +import org.apache.lucene.document.LongField; import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -261,6 +263,8 @@ public class LuceneChangeIndex implements ChangeIndex, LifecycleListener { return exactQuery(p); } else if (p.getType() == FieldType.PREFIX) { return prefixQuery(p); + } else if (p instanceof SortKeyPredicate) { + return sortKeyQuery((SortKeyPredicate) p); } else { throw badFieldType(p.getType()); } @@ -285,6 +289,14 @@ public class LuceneChangeIndex implements ChangeIndex, LifecycleListener { return new TermQuery(intTerm(p.getOperator(), value)); } + private static Query sortKeyQuery(SortKeyPredicate p) { + return NumericRangeQuery.newLongRange( + p.getField().getName(), + p.getMinValue(), + p.getMaxValue(), + true, true); + } + private static Query timestampQuery(IndexPredicate p) throws QueryParseException { if (p instanceof TimestampRangePredicate) { @@ -442,6 +454,10 @@ public class LuceneChangeIndex implements ChangeIndex, LifecycleListener { for (Object value : values) { doc.add(new IntField(name, (Integer) value, store)); } + } else if (f.getType() == FieldType.LONG) { + for (Object value : values) { + doc.add(new LongField(name, (Long) value, store)); + } } else if (f.getType() == FieldType.TIMESTAMP) { for (Object v : values) { doc.add(new IntField(name, toIndexTime((Timestamp) v), store)); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java index ad6a1963da..6b88c34e6c 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java @@ -450,16 +450,15 @@ public class ChangeUtil { return r.toString(); } - public static Timestamp timeFromSortKey(String sortKey) { + public static long parseSortKey(String sortKey) { if ("z".equals(sortKey)) { - return new Timestamp(Long.MAX_VALUE); + return Long.MAX_VALUE; } String ts = sortKey.substring(0, 8); int i = 0; while (i < 8 && ts.charAt(i) == '0') i++; - long v = Long.parseLong(ts.substring(i), 16) * 60; - return new Timestamp((v + SORT_KEY_EPOCH) * 1000); + return Long.parseLong(ts.substring(i), 16); } public static void computeSortKey(final Change c) { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java index 8180b3bb66..726e239c67 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java @@ -19,6 +19,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gerrit.reviewdb.client.PatchSetApproval; import com.google.gerrit.reviewdb.client.PatchSet; +import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeQueryBuilder; import com.google.gerrit.server.query.change.ChangeStatusPredicate; @@ -43,7 +44,7 @@ import java.util.Set; */ public class ChangeField { /** Increment whenever making schema changes. */ - public static final int SCHEMA_VERSION = 5; + public static final int SCHEMA_VERSION = 6; /** Legacy change ID. */ public static final FieldDef CHANGE_ID = @@ -111,6 +112,18 @@ public class ChangeField { } }; + /** Sort key field, duplicates {@link #UPDATED}. */ + @Deprecated + public static final FieldDef SORTKEY = + new FieldDef.Single( + "sortkey", FieldType.LONG, true) { + @Override + public Long get(ChangeData input, FillArgs args) + throws OrmException { + return ChangeUtil.parseSortKey(input.change(args.db).getSortKey()); + } + }; + /** List of filenames modified in the current patch set. */ public static final FieldDef> FILE = new FieldDef.Repeatable( diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/FieldType.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/FieldType.java index ecc960b590..c31537ea01 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/index/FieldType.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/FieldType.java @@ -23,6 +23,10 @@ public class FieldType { public static final FieldType INTEGER = new FieldType("INTEGER"); + /** A single integer-valued field. */ + public static final FieldType LONG = + new FieldType("LONG"); + /** A single date/time-valued field. */ public static final FieldType TIMESTAMP = new FieldType("TIMESTAMP"); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java index a519504f5f..1aa17cfab7 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java @@ -18,18 +18,15 @@ import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.index.ChangeField; -import com.google.gerrit.server.index.TimestampRangePredicate; +import com.google.gerrit.server.index.IndexPredicate; import com.google.gwtorm.server.OrmException; import com.google.inject.Provider; -import java.sql.Timestamp; - -public abstract class SortKeyPredicate extends - TimestampRangePredicate { +public abstract class SortKeyPredicate extends IndexPredicate { protected final Provider dbProvider; SortKeyPredicate(Provider dbProvider, String name, String value) { - super(ChangeField.UPDATED, name, value); + super(ChangeField.SORTKEY, name, value); this.dbProvider = dbProvider; } @@ -38,19 +35,22 @@ public abstract class SortKeyPredicate extends return 1; } + public abstract long getMinValue(); + public abstract long getMaxValue(); + public static class Before extends SortKeyPredicate { Before(Provider dbProvider, String value) { super(dbProvider, "sortkey_before", value); } @Override - public Timestamp getMinTimestamp() { - return new Timestamp(0); + public long getMinValue() { + return 0; } @Override - public Timestamp getMaxTimestamp() { - return ChangeUtil.timeFromSortKey(getValue()); + public long getMaxValue() { + return ChangeUtil.parseSortKey(getValue()); } @Override @@ -66,13 +66,13 @@ public abstract class SortKeyPredicate extends } @Override - public Timestamp getMinTimestamp() { - return ChangeUtil.timeFromSortKey(getValue()); + public long getMinValue() { + return ChangeUtil.parseSortKey(getValue()); } @Override - public Timestamp getMaxTimestamp() { - return new Timestamp(Long.MAX_VALUE); + public long getMaxValue() { + return Long.MAX_VALUE; } @Override