+ void setTokenRow(TokenRow tokenRow) {
+ assert this.tokenRow == null;
+ assert tokenRow != null;
+ this.tokenRow = tokenRow;
+ }
+
+ public abstract void print(PrintStream out);
+
+ public abstract String getRawText(final boolean compact);
+
+ public abstract RowMatchType matches(final List<String> searchTokens,
+ final Pattern orderedMatch, final Transliterator normalizer, boolean swapPairEntries);
+
+ // RowBase must manage "disk-based" polymorphism. All other polymorphism is
+ // dealt with in the normal manner.
+ static class Serializer implements RAFListSerializer<RowBase> {
+
+ final Index index;
+
+ Serializer(final Index index) {
+ this.index = index;
+ }
+
+ @Override
+ public RowBase read(DataInput raf, final int listIndex) throws IOException {
+ int rowType = raf.readUnsignedByte();
+ int extra = -1;
+ if (rowType >= 0x20) {
+ extra = rowType & 0x1f;
+ rowType = (rowType >> 5) - 1;
+ }
+ switch (rowType) {
+ case 0:
+ return new PairEntry.Row(raf, listIndex, index, extra);
+ case 1:
+ case 3:
+ return new TokenRow(raf, listIndex, index, /* hasMainEntry */rowType == 1, extra);
+ case 2:
+ return new TextEntry.Row(raf, listIndex, index, extra);
+ case 4:
+ return new HtmlEntry.Row(raf, listIndex, index, extra);
+ }
+ throw new RuntimeException("Invalid rowType:" + rowType);
+ }
+
+ @Override
+ public void write(DataOutput raf, RowBase t) throws IOException {
+ int type = 0;
+ if (t instanceof PairEntry.Row) {
+ type = 0;
+ } else if (t instanceof TokenRow) {
+ final TokenRow tokenRow = (TokenRow) t;
+ type = tokenRow.hasMainEntry ? 1 : 3;
+ } else if (t instanceof TextEntry.Row) {
+ type = 2;
+ } else if (t instanceof HtmlEntry.Row) {
+ type = 4;
+ }
+ assert t.referenceIndex < (1 << 21);
+ if ((t.referenceIndex >> 16) >= (1 << 5))
+ throw new RuntimeException("referenceIndex larger than supported max");
+ raf.writeByte(((type + 1) << 5) + (t.referenceIndex >> 16));
+ raf.writeShort(t.referenceIndex);
+ }
+ }
+
+ public static final class LengthComparator implements Comparator<RowBase> {
+
+ final boolean swapPairEntries;
+
+ public LengthComparator(boolean swapPairEntries) {
+ this.swapPairEntries = swapPairEntries;
+ }
+
+ @Override
+ public int compare(RowBase row1, RowBase row2) {
+ final int l1 = row1.getSideLength(swapPairEntries);
+ final int l2 = row2.getSideLength(swapPairEntries);
+ return l1 < l2 ? -1 : l1 == l2 ? 0 : 1;
+ }