]> gitweb.fperrin.net Git - Dictionary.git/commitdiff
go
authorThad Hughes <thad.hughes@gmail.com>
Tue, 12 Oct 2010 23:54:32 +0000 (16:54 -0700)
committerThad Hughes <thad.hughes@gmail.com>
Tue, 12 Oct 2010 23:54:32 +0000 (16:54 -0700)
12 files changed:
src/com/hughes/android/dictionary/Dictionary.java
src/com/hughes/android/dictionary/DictionaryActivity.java
src/com/hughes/android/dictionary/DictionaryActivityTest.java
src/com/hughes/android/dictionary/DictionaryListActivity.java
src/com/hughes/android/dictionary/engine/Dictionary.java
src/com/hughes/android/dictionary/engine/Entry.java
src/com/hughes/android/dictionary/engine/EntrySource.java
src/com/hughes/android/dictionary/engine/Index.java
src/com/hughes/android/dictionary/engine/Language.java [moved from src/com/hughes/android/dictionary/Language.java with 78% similarity]
src/com/hughes/android/dictionary/engine/PairEntry.java
src/com/hughes/android/dictionary/engine/RowBase.java
src/com/hughes/android/dictionary/engine/TokenRow.java

index c0a35880879a86649be99a2841f092f8f95e7be5..5de8d3262508a3b105f1776c93d4d6817fd1c79c 100755 (executable)
@@ -6,6 +6,7 @@ import java.util.ArrayList;
 import java.util.List;\r
 import java.util.concurrent.atomic.AtomicBoolean;\r
 \r
+import com.hughes.android.dictionary.engine.Language;\r
 import com.hughes.util.CachingList;\r
 import com.hughes.util.raf.RAFList;\r
 import com.hughes.util.raf.RAFFactory;\r
index d6a6ff10d7a0cb0a0fc24ad7f195adb7455f0df1..5c272c55a803a82c283454f3b93fedadf5bae73d 100644 (file)
@@ -50,6 +50,7 @@ import android.widget.Toast;
 import com.hughes.android.dictionary.Dictionary.IndexEntry;
 import com.hughes.android.dictionary.Dictionary.LanguageData;
 import com.hughes.android.dictionary.Dictionary.Row;
+import com.hughes.android.dictionary.engine.Language;
 import com.ibm.icu.text.Collator;
 
 public class DictionaryActivity extends ListActivity {
index 1ac9e8b0d630dcc59a07ffb220f22dddc655cf9d..dc0325b09f94ba140e55dcfa2bbab3313d469db3 100755 (executable)
@@ -1,5 +1,7 @@
 package com.hughes.android.dictionary;\r
 \r
+import com.hughes.android.dictionary.engine.Language;\r
+\r
 import android.test.ActivityInstrumentationTestCase2;\r
 \r
 public class DictionaryActivityTest extends ActivityInstrumentationTestCase2<DictionaryActivity> {\r
index faeb8fe47e2be94ee9de0d6046b5bb57dd52697f..1f9936aff11b67db2392157c04bf23e122166400 100644 (file)
@@ -18,7 +18,6 @@ import android.view.View.OnFocusChangeListener;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.EditText;
-import android.widget.ListView;
 import android.widget.TableLayout;
 import android.widget.TextView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
index 1472d310623de67fcc369d96c3f28bc7351e4947..26dae916630924bb595104949c0431d05f0f616c 100644 (file)
@@ -14,6 +14,8 @@ import com.hughes.util.raf.RAFSerializable;
 
 public class Dictionary implements RAFSerializable<Dictionary> {
   
+  static final int CACHE_SIZE = 5000;
+  
   // persisted
   final String dictInfo;
   final List<PairEntry> pairEntries;
@@ -31,17 +33,10 @@ public class Dictionary implements RAFSerializable<Dictionary> {
 
   public Dictionary(final RandomAccessFile raf) throws IOException {
     dictInfo = raf.readUTF();
-
-    sources = RAFList.create(raf, EntrySource.SERIALIZER, raf.getFilePointer());
-
-    // TODO: caching
-    pairEntries = RAFList.create(raf, PairEntry.SERIALIZER, raf.getFilePointer());
-
-    // TODO: caching
-    textEntries = RAFList.create(raf, TextEntry.SERIALIZER, raf.getFilePointer());
-
-    final List<Index> rawIndices = RAFList.create(raf, indexSerializer, raf.getFilePointer());
-    indices = CachingList.create(rawIndices, rawIndices.size());
+    sources = CachingList.createFullyCached(RAFList.create(raf, EntrySource.SERIALIZER, raf.getFilePointer()));
+    pairEntries = CachingList.create(RAFList.create(raf, PairEntry.SERIALIZER, raf.getFilePointer()), CACHE_SIZE);
+    textEntries = CachingList.create(RAFList.create(raf, TextEntry.SERIALIZER, raf.getFilePointer()), CACHE_SIZE);
+    indices = CachingList.createFullyCached(RAFList.create(raf, indexSerializer, raf.getFilePointer()));
   }
   
   public void print(final PrintStream out) {
index 9efd1f535d5eef63d0a2a0cfde4c430845b72249..8be07f3f1db1262a57167ae80f13450ba91be68c 100644 (file)
@@ -3,6 +3,4 @@ package com.hughes.android.dictionary.engine;
 
 public abstract class Entry {
   
-  EntrySource entrySource;
-    
 }
index 914cf8f5f7578c34678d27a0c83eb6a673f03112..391e8cec218b89a29900eb29ba39ea6b351be307 100644 (file)
@@ -18,6 +18,12 @@ public class EntrySource extends IndexedObject implements Serializable {
     this.name = name;
   }
   
+  @Override
+  public String toString() {
+    return name;
+  }
+
+
   public static RAFListSerializer<EntrySource> SERIALIZER = new RAFListSerializer<EntrySource>() {
 
     @Override
@@ -30,8 +36,7 @@ public class EntrySource extends IndexedObject implements Serializable {
     @Override
     public void write(RandomAccessFile raf, EntrySource t) throws IOException {
       raf.writeUTF(t.name);
-    }
-    
+    }    
   };
   
 }
index 49536003bf29502a9e953302139d271b65bf9002..e2c2fee96e145fff7ec15caff0b71a17be031bd9 100644 (file)
@@ -9,14 +9,19 @@ import java.io.RandomAccessFile;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.hughes.android.dictionary.Language;
+import com.hughes.util.CachingList;
 import com.hughes.util.raf.RAFList;
 import com.hughes.util.raf.RAFSerializable;
 import com.hughes.util.raf.RAFSerializer;
 import com.hughes.util.raf.UniformRAFList;
+import com.ibm.icu.text.Collator;
 
 public final class Index implements RAFSerializable<Index> {
+  
+  static final int CACHE_SIZE = 5000;
+  
   final Dictionary dict;
   
   final String shortName;
@@ -53,9 +58,8 @@ public final class Index implements RAFSerializable<Index> {
     if (sortLanguage == null) {
       throw new IOException("Unsupported language: " + languageCode);
     }
-    // TODO: caching
-    sortedIndexEntries = RAFList.create(raf, IndexEntry.SERIALIZER, raf.getFilePointer());
-    rows = UniformRAFList.create(raf, new RowBase.Serializer(this), raf.getFilePointer());
+    sortedIndexEntries = CachingList.create(RAFList.create(raf, IndexEntry.SERIALIZER, raf.getFilePointer()), CACHE_SIZE);
+    rows = CachingList.create(UniformRAFList.create(raf, new RowBase.Serializer(this), raf.getFilePointer()), CACHE_SIZE);
   }
   
   public void print(final PrintStream out) {
@@ -102,8 +106,62 @@ public final class Index implements RAFSerializable<Index> {
     
     public void write(RandomAccessFile raf) throws IOException {
       raf.writeUTF(token);
-      raf.write(startRow);
+      raf.writeInt(startRow);
+    }
+
+    public String toString() {
+      return token + "@" + startRow;
+    }
+}
+  
+
+  private TokenRow sortedIndexToToken(final int sortedIndex) {
+    final IndexEntry indexEntry = sortedIndexEntries.get(sortedIndex);
+    return (TokenRow) rows.get(indexEntry.startRow);
+  }
+
+  public TokenRow find(String token, final AtomicBoolean interrupted) {
+    token = sortLanguage.textNorm(token, true);
+
+    int start = 0;
+    int end = sortedIndexEntries.size();
+    
+    final Collator sortCollator = sortLanguage.getSortCollator();
+    while (start < end) {
+      final int mid = (start + end) / 2;
+      if (interrupted.get()) {
+        return sortedIndexToToken(mid);
+      }
+      final IndexEntry midEntry = sortedIndexEntries.get(mid);
+
+      final int comp = sortCollator.compare(token, sortLanguage.textNorm(midEntry.token, true));
+      if (comp == 0) {
+        final int result = windBack(token, mid, sortCollator, interrupted);
+        return sortedIndexToToken(result);
+      } else if (comp < 0) {
+//        Log.d("THAD", "Upper bound: " + midEntry);
+        end = mid;
+      } else {
+//        Log.d("THAD", "Lower bound: " + midEntry);
+        start = mid + 1;
+      }
+    }
+    int result = Math.min(start, sortedIndexEntries.size() - 1);
+    result = windBack(token, result, sortCollator, interrupted);
+    if (result > 0 && sortCollator.compare(sortLanguage.textNorm(sortedIndexEntries.get(result).token, true), token) > 0) {
+      result = windBack(sortLanguage.textNorm(sortedIndexEntries.get(result - 1).token, true), result, sortCollator, interrupted);
+    }
+    return sortedIndexToToken(result);
+  }
+  
+  private final int windBack(final String token, int result, final Collator sortCollator, final AtomicBoolean interrupted) {
+    while (result > 0 && sortCollator.compare(sortLanguage.textNorm(sortedIndexEntries.get(result - 1).token, true), token) >= 0) {
+      --result;
+      if (interrupted.get()) {
+        return result;
+      }
     }
+    return result;
   }
 
 }
\ No newline at end of file
similarity index 78%
rename from src/com/hughes/android/dictionary/Language.java
rename to src/com/hughes/android/dictionary/engine/Language.java
index 9732efad221f93378fa017e3578f3e276d5c6cbc..b4d8558358a86a91ff4513fa2381c5fe6d13727f 100755 (executable)
@@ -1,4 +1,4 @@
-package com.hughes.android.dictionary;\r
+package com.hughes.android.dictionary.engine;\r
 \r
 import java.util.Comparator;\r
 import java.util.LinkedHashMap;\r
@@ -26,21 +26,21 @@ public class Language {
 \r
     this.sortComparator = new Comparator<String>() {\r
       public int compare(final String s1, final String s2) {\r
-        return getSortCollator().compare(textNorm(s1), textNorm(s2));\r
+        return getSortCollator().compare(textNorm(s1, false), textNorm(s2, false));\r
       }\r
     };\r
 \r
     this.findComparator = new Comparator<String>() {\r
       public int compare(final String s1, final String s2) {\r
-        return getFindCollator().compare(textNorm(s1), textNorm(s2));\r
+        return getFindCollator().compare(textNorm(s1, false), textNorm(s2, false));\r
       }\r
     };\r
     \r
     symbolToLangauge.put(symbol.toLowerCase(), this);\r
   }\r
 \r
-  public String textNorm(final String s) {\r
-    return s;\r
+  public String textNorm(final String s, final boolean toLower) {\r
+    return toLower ? s.toLowerCase() : s;\r
   }\r
 \r
   @Override\r
@@ -78,8 +78,12 @@ public class Language {
 \r
   public static final Language de = new Language(Locale.GERMAN) {\r
     @Override\r
-    public String textNorm(String token) {\r
+    public String textNorm(String token, final boolean toLower) {\r
+      if (toLower) {\r
+        token = token.toLowerCase();\r
+      }\r
       boolean sub = false;\r
+      // This is meant to be fast: occurrences of ae, oe, ue are probably rare.\r
       for (int ePos = token.indexOf('e', 1); ePos != -1; ePos = token.indexOf(\r
           'e', ePos + 1)) {\r
         final char pre = Character.toLowerCase(token.charAt(ePos - 1));\r
@@ -91,6 +95,7 @@ public class Language {
       if (!sub) {\r
         return token;\r
       }\r
+      \r
       token = token.replaceAll("ae", "ä");\r
       token = token.replaceAll("oe", "ö");\r
       token = token.replaceAll("ue", "ü");\r
@@ -98,6 +103,11 @@ public class Language {
       token = token.replaceAll("Ae", "Ä");\r
       token = token.replaceAll("Oe", "Ö");\r
       token = token.replaceAll("Ue", "Ü");\r
+\r
+      token = token.replaceAll("AE", "Ä");\r
+      token = token.replaceAll("OE", "Ö");\r
+      token = token.replaceAll("UE", "Ü");\r
+      \r
       return token;   \r
     }\r
   };\r
index 55c32d0dbb8d8d0d90902b5f4fcc64f4a63158e1..1557c9bcaacf49f43f7e4ca41347ac0c3785100e 100644 (file)
@@ -17,7 +17,7 @@ public class PairEntry extends Entry implements RAFSerializable<PairEntry> {
       this.lang2 = lang2;
     }
     public String toString() {
-      return lang1 + "\t" + lang2;
+      return lang1 + " :: " + lang2;
     }
   }
   
@@ -35,7 +35,7 @@ public class PairEntry extends Entry implements RAFSerializable<PairEntry> {
   }
   @Override
   public void write(RandomAccessFile raf) throws IOException {
-    // TODO: this couls be a short.
+    // TODO: this could be a short.
     raf.writeInt(pairs.length);
     for (int i = 0; i < pairs.length; ++i) {
       raf.writeUTF(pairs[i].lang1);
@@ -82,7 +82,8 @@ public class PairEntry extends Entry implements RAFSerializable<PairEntry> {
     public void print(PrintStream out) {
       final PairEntry pairEntry = getEntry();
       for (int i = 0; i < pairEntry.pairs.length; ++i) {
-        out.println((i == 0 ? "  " : "    ") + pairEntry.pairs[i]);
+        out.print((i == 0 ? "  " : "    ") + pairEntry.pairs[i]);
+        out.println();
       }
     }
   }
index 61ff4e078d464e26dcd0130109683199924be44f..d62edf16a49ac550df3a7866c52962e124f19ee0 100644 (file)
@@ -48,7 +48,9 @@ public abstract class RowBase extends IndexedObject {
           for (++r; r <= index(); ++r) {
             index.rows.get(r).setTokenRow(candidate);
           }
+          break;
         }
+        --r;
       }
       assert tokenRow != null;
     }
index 06a1aa8a891ee272561534a6023937b09e507c21..0488f0aa491390b52ec8801646cfddb8dd9f77d7 100644 (file)
@@ -13,6 +13,10 @@ public class TokenRow extends RowBase {
   TokenRow(final int referenceIndex, final int thisRowIndex, final Index index) {
     super(referenceIndex, thisRowIndex, index);
   }
+  
+  public String toString() {
+    return getToken() + "@" + referenceIndex;
+  }
 
   @Override
   public TokenRow getTokenRow(final boolean search) {