]> gitweb.fperrin.net Git - Dictionary.git/blob - src/com/hughes/android/dictionary/engine/RowBase.java
Added multiword search to dictionary.
[Dictionary.git] / src / com / hughes / android / dictionary / engine / RowBase.java
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package com.hughes.android.dictionary.engine;
16
17 import java.io.IOException;
18 import java.io.PrintStream;
19 import java.io.RandomAccessFile;
20 import java.util.List;
21
22 import com.hughes.util.IndexedObject;
23 import com.hughes.util.raf.RAFListSerializer;
24 import com.ibm.icu.text.Transliterator;
25
26 public abstract class RowBase extends IndexedObject {
27   /**
28    * the Index owning this RowBase.
29    */
30   public final Index index;
31   
32   /**
33    * Where this RowBase points to.
34    */
35   public final int referenceIndex;
36
37   /**
38    * the TokenRow above this RowBase, populated on demand.
39    */
40   private TokenRow tokenRow = null;
41   
42   RowBase(final RandomAccessFile raf, final int thisRowIndex, final Index index) throws IOException {
43     super(thisRowIndex);
44     this.index = index;
45     this.referenceIndex = raf.readInt();  // what this points to.
46   }
47
48   public RowBase(final int referenceIndex, final int thisRowIndex, final Index index) {
49     super(thisRowIndex);
50     this.index = index;
51     this.referenceIndex = referenceIndex;
52   }
53
54   /**
55    * @return the TokenRow that this row is "filed under".
56    */
57   public TokenRow getTokenRow(final boolean search) {
58     if (tokenRow == null && search) {
59       int r = index() - 1;
60       int rUp = index() + 1;
61       while (r >= 0) {
62         final RowBase row = index.rows.get(r);
63         final TokenRow candidate = row.getTokenRow(false);
64         if (candidate != null) {
65           for (++r; r <= index(); ++r) {
66             index.rows.get(r).setTokenRow(candidate);
67           }
68           break;
69         }
70         if (rUp < index.rows.size()) {
71           final RowBase rowUp = index.rows.get(rUp);
72           TokenRow candidateUp = rowUp.getTokenRow(false);
73           if (candidateUp != null) {
74             // Did we hit the next set of TokenRows?
75             if (candidateUp.index() > this.index()) {  
76               final int tokenIndex = index.sortedIndexEntries.get(candidateUp.referenceIndex - 1).startRow;
77               candidateUp = (TokenRow) index.rows.get(tokenIndex);
78             }
79             for (--rUp; rUp >= index(); --rUp) {
80               index.rows.get(rUp).setTokenRow(candidateUp);
81             }
82             break;
83           }
84           rUp++;
85         }
86         --r;
87       }
88       assert tokenRow != null;
89     }
90     return tokenRow;
91   }
92   
93   public void setTokenRow(TokenRow tokenRow) {
94     assert this.tokenRow == null;
95     assert tokenRow != null;
96     this.tokenRow = tokenRow;
97   }
98
99   public abstract void print(PrintStream out);
100
101   public abstract String getRawText(final boolean compact);
102   
103   public abstract RowMatchType matches(final List<String> searchTokens, final Transliterator normalizer, boolean swapPairEntries);
104
105   // RowBase must manage "disk-based" polymorphism.  All other polymorphism is
106   // dealt with in the normal manner.
107   static class Serializer implements RAFListSerializer<RowBase> {
108     
109     final Index index;
110     
111     Serializer(final Index index) {
112       this.index = index;
113     }
114
115     @Override
116     public RowBase read(RandomAccessFile raf, final int listIndex) throws IOException {
117       final byte rowType = raf.readByte();
118       if (rowType == 0) {
119         return new PairEntry.Row(raf, listIndex, index);
120       } else if (rowType == 1 || rowType == 3) {
121         return new TokenRow(raf, listIndex, index, rowType == 1);
122       } else if (rowType == 2) {
123         return new TextEntry.Row(raf, listIndex, index);
124       }
125       throw new RuntimeException("Invalid rowType:" + rowType);
126     }
127
128     @Override
129     public void write(RandomAccessFile raf, RowBase t) throws IOException {
130       if (t instanceof PairEntry.Row) {
131         raf.writeByte(0);
132       } else if (t instanceof TokenRow) {
133         final TokenRow tokenRow = (TokenRow) t;
134         raf.writeByte(tokenRow.hasMainEntry ? 1 : 3);
135       } else if (t instanceof TextEntry.Row) {
136         raf.writeByte(2);
137       }
138       raf.writeInt(t.referenceIndex);
139     }
140   }
141   
142 }