From: thadh Date: Mon, 23 Feb 2009 08:30:14 +0000 (-0800) Subject: addingList X-Git-Url: http://gitweb.fperrin.net/?a=commitdiff_plain;h=7e07e08f91b2ecca4d12eb2a39da2828079408ab;p=Dictionary.git addingList --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 640d31d..577a753 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -4,7 +4,7 @@ android:versionCode="1" android:versionName="1.0.0"> - diff --git a/src/com/hughes/android/dictionary/Dictionary.java b/src/com/hughes/android/dictionary/Dictionary.java index 1e01bc9..ec0d0f6 100755 --- a/src/com/hughes/android/dictionary/Dictionary.java +++ b/src/com/hughes/android/dictionary/Dictionary.java @@ -1,233 +1,61 @@ -package com.hughes.android.dictionary; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicBoolean; - -import android.app.AlertDialog; -import android.app.ListActivity; -import android.os.Bundle; -import android.os.Handler; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Log; -import android.view.ContextMenu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.MenuItem.OnMenuItemClickListener; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.AdapterView.OnItemLongClickListener; - -import com.hughes.util.FileUtil; - -public class Dictionary extends ListActivity { - - public static final String INDEX_FORMAT = "%s_index_%d"; - private File dictionaryFile = new File("/sdcard/dict-de-en.txt"); - private File wordList = new File("/sdcard/wordList.txt"); - - private RandomAccessFile dictionaryRaf; - private final Index[] indexes = new Index[2]; - private final byte lang = Entry.LANG1; - - final Handler uiHandler = new Handler(); - - private final Object mutex = new Object(); - private Executor searchExecutor = Executors.newSingleThreadExecutor(); - private SearchOperation searchOperation = null; - private List entries = Collections.emptyList(); - private DictionaryListAdapter dictionaryListAdapter = new DictionaryListAdapter(); - private int selectedItem = -1; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - Log.d("THAD", "onCreate"); - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - - EditText searchText = (EditText) findViewById(R.id.SearchText); - searchText.addTextChangedListener(new DictionaryTextWatcher()); - - setListAdapter(dictionaryListAdapter); - - try { - loadIndex(); - } catch (Exception e) { - throw new RuntimeException(e); - } - onSearchTextChange(""); - - registerForContextMenu(getListView()); - getListView().setOnItemLongClickListener((new OnItemLongClickListener() { - public boolean onItemLongClick(AdapterView arg0, View arg1, int arg2, - long arg3) { - selectedItem = arg2; - return false; - } - })); - } - - private void loadIndex() throws IOException, ClassNotFoundException { - Log.d("THAD", "enter loadIndex"); - indexes[0] = new Index(String.format(INDEX_FORMAT, dictionaryFile - .getAbsolutePath(), Entry.LANG1)); - dictionaryRaf = new RandomAccessFile(dictionaryFile, "r"); - Log.d("THAD", "exit loadIndex"); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - if (selectedItem == -1) { - return; - } - final MenuItem addToWordlist = menu.add("Add to wordlist."); - addToWordlist.setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - final String rawText = entries.get(selectedItem).getRawText(); - Log.d("THAD", "Writing : " - + rawText); - try { - final OutputStream out = new FileOutputStream(wordList, true); - out.write((rawText + "\n").getBytes()); - out.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - return false; - } - }); - } - - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - Log.d("THAD", "Clicked: " + entries.get(position).getRawText()); - selectedItem = position; - openContextMenu(getListView()); - } - - void onSearchTextChange(final String searchText) { - Log.d("THAD", "onSearchTextChange: " + searchText); - synchronized (mutex) { - if (searchOperation != null) { - searchOperation.interrupted.set(true); - } - searchOperation = new SearchOperation(searchText); - } - searchExecutor.execute(searchOperation); - } - - private final class SearchOperation implements Runnable { - final String searchText; - final int count = 100; - final AtomicBoolean interrupted = new AtomicBoolean(false); - - public SearchOperation(final String searchText) { - this.searchText = searchText.toLowerCase(); // TODO: better - } - - public void run() { - Log.d("THAD", "SearchOperation: " + searchText); - final List newEntries = new ArrayList(count); - try { - final Index.Node node = indexes[lang].lookup(searchText); - final Set entryOffsets = new LinkedHashSet(count); - node.getDescendantEntryOffsets(entryOffsets, count); - for (final int entryOffset : entryOffsets) { - if (interrupted.get()) { - Log.d("THAD", "Interrupted while parsing entries."); - return; - } - final String line = FileUtil.readLine(dictionaryRaf, entryOffset); - final Entry entry = new Entry(line); - newEntries.add(entry); - } - } catch (IOException e) { - Log.e("THAD", "Search failure.", e); - } - - synchronized (mutex) { - if (interrupted.get()) { - return; - } - entries = newEntries; - } - - uiHandler.post(new Runnable() { - public void run() { - synchronized (mutex) { - dictionaryListAdapter.notifyDataSetChanged(); - if (entries.size() > 0) { - setSelection(0); - } - } - } - }); - } - } - - private class DictionaryListAdapter extends BaseAdapter { - - public int getCount() { - synchronized (mutex) { - return entries.size(); - } - } - - public Object getItem(int position) { - synchronized (mutex) { - assert position < entries.size(); - return entries.get(position).getFormattedEntry(lang); - } - } - - public long getItemId(int position) { - return position; - } - - public View getView(final int position, final View convertView, - final ViewGroup parent) { - TextView result = null; - if (convertView instanceof TextView) { - result = (TextView) convertView; - } else { - result = new TextView(parent.getContext()); - } - result.setText((String) getItem(position)); - return result; - } - - } - - private class DictionaryTextWatcher implements TextWatcher { - public void afterTextChanged(Editable searchText) { - onSearchTextChange(searchText.toString()); - } - - public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, - int arg3) { - } - - public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { - } - } - -} \ No newline at end of file +package com.hughes.android.dictionary; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +import com.hughes.util.FileUtil; +import com.hughes.util.LRUCacheMap; + +public final class Dictionary { + + public static final String INDEX_FORMAT = "%s_index_%d"; + + private final byte lang; + private final File dictionaryFile; + private final RandomAccessFile dictionaryRaf; + private final Index index; + + private final LRUCacheMap positionToRow = new LRUCacheMap(2000); + + public Dictionary(final String dictionaryFileName, final byte lang) + throws IOException { + this.lang = lang; + this.dictionaryFile = new File(dictionaryFileName); + + dictionaryRaf = new RandomAccessFile(dictionaryFile, "r"); + index = new Index(String.format(INDEX_FORMAT, dictionaryFile + .getAbsolutePath(), lang)); + } + + public int numRows() { + return index.root.getDescendantCount(); + } + + public Row getRow(final int position) throws IOException { + Row row = positionToRow.get(position); + if (row == null) { + final Object o = index.root.getDescendant(position); + if (o instanceof Integer) { + final Entry entry = new Entry(FileUtil.readLine(dictionaryRaf, (Integer) o)); + row = new Row(entry.getFormattedEntry(lang), false); + } else if (o instanceof String) { + row = new Row((String) o, true); + } else { + throw new RuntimeException(o.toString()); + } + positionToRow.put(position, row); + } + return row; + } + + public static class Row { + final String text; + final boolean isWord; + public Row(final String text, final boolean isWord) { + this.text = text; + this.isWord = isWord; + } + } + +} diff --git a/src/com/hughes/android/dictionary/Entry.java b/src/com/hughes/android/dictionary/Entry.java index d04722f..0c4cd60 100755 --- a/src/com/hughes/android/dictionary/Entry.java +++ b/src/com/hughes/android/dictionary/Entry.java @@ -45,7 +45,7 @@ public final class Entry { return text; } - public Object getFormattedEntry(final byte lang) { + public String getFormattedEntry(final byte lang) { return getAllText(lang) + "\n" + getAllText(OtherLang(lang)); } diff --git a/src/com/hughes/android/dictionary/Index.java b/src/com/hughes/android/dictionary/Index.java index 3970f22..9981a9f 100755 --- a/src/com/hughes/android/dictionary/Index.java +++ b/src/com/hughes/android/dictionary/Index.java @@ -110,26 +110,57 @@ public final class Index { tokenToOffsets.put(token, offsets); } + // TODO: move this up, and defer the loading of the other stuff until it's needed. descendantTokenCount = file.readInt(); descendantEntryCount = file.readInt(); } + @Override + public String toString() { + return String.format("%s(%d,%d)", nodeHandle.normalizedToken, getThisCount(), getDescendantCount()); + } + public int getDescendantCount() { return descendantEntryCount + descendantTokenCount; } + + public int getThisCount() { + int count = tokenToOffsets.size(); + for (final int[] offsets : tokenToOffsets.values()) { + count += offsets.length; + } + return count; + } - public Object getDescendant(final int position) throws IOException { - if (position < getDescendantCount()) { - return null; + public Object getDescendant(int position) throws IOException { + assert position < getDescendantCount(); + +// System.out.println("getD: " + this + ", " + position); + if (position < getThisCount()) { + for (final Map.Entry tokenEntry : tokenToOffsets.entrySet()) { + if (position == 0) { + return tokenEntry.getKey(); + } + --position; + if (position < tokenEntry.getValue().length) { + return tokenEntry.getValue()[position]; + } + position -= tokenEntry.getValue().length; + } + assert false; } + position -= getThisCount(); + + for (final Map.Entry childEntry : children.entrySet()) { final Node child = childEntry.getValue().getNode(); if (position < child.getDescendantCount()) { - - } else { - position -= child.getDescendantCount(); + return child.getDescendant(position); } + position -= child.getDescendantCount(); } + assert false; + return null; } public void getDescendantEntryOffsets(final Set entryOffsets, int maxSize) throws IOException {