X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=src%2Fcom%2Fhughes%2Fandroid%2Fdictionary%2Fengine%2FDictionary.java;h=6539bc9b0f0a52afce3eae135fa681bf527ddc53;hb=2a18ab8b97ba0254a0655d595f05c492eb0eecd4;hp=57ae6e73cd5f6c41ed392fa7d2f050eaa4b76251;hpb=f8329ca5a93f93c26bc9f014a831da876f32867d;p=Dictionary.git diff --git a/src/com/hughes/android/dictionary/engine/Dictionary.java b/src/com/hughes/android/dictionary/engine/Dictionary.java index 57ae6e7..6539bc9 100644 --- a/src/com/hughes/android/dictionary/engine/Dictionary.java +++ b/src/com/hughes/android/dictionary/engine/Dictionary.java @@ -14,37 +14,40 @@ package com.hughes.android.dictionary.engine; -import com.hughes.android.dictionary.DictionaryInfo; -import com.hughes.util.CachingList; -import com.hughes.util.StringUtil; -import com.hughes.util.raf.RAFList; -import com.hughes.util.raf.RAFListSerializer; -import com.hughes.util.raf.RAFSerializable; - import java.io.DataInput; import java.io.DataOutput; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.io.RandomAccessFile; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.hughes.android.dictionary.DictionaryInfo; +import com.hughes.util.CachingList; +import com.hughes.util.DataInputBuffer; +import com.hughes.util.raf.RAFList; +import com.hughes.util.raf.RAFListSerializer; +import com.hughes.util.raf.RAFSerializable; + public class Dictionary implements RAFSerializable { - static final int CACHE_SIZE = 5000; + private static final int CACHE_SIZE = 5000; - static final int CURRENT_DICT_VERSION = 7; - static final String END_OF_DICTIONARY = "END OF DICTIONARY"; + private static final int CURRENT_DICT_VERSION = 7; + private static final String END_OF_DICTIONARY = "END OF DICTIONARY"; // persisted final int dictFileVersion; - final long creationMillis; + public final long creationMillis; public final String dictInfo; public final List pairEntries; public final List textEntries; public final List htmlEntries; + public final List htmlData; public final List sources; public final List indices; @@ -57,50 +60,56 @@ public class Dictionary implements RAFSerializable { this.dictFileVersion = CURRENT_DICT_VERSION; this.creationMillis = System.currentTimeMillis(); this.dictInfo = dictInfo; - pairEntries = new ArrayList(); - textEntries = new ArrayList(); - htmlEntries = new ArrayList(); - sources = new ArrayList(); - indices = new ArrayList(); + pairEntries = new ArrayList<>(); + textEntries = new ArrayList<>(); + htmlEntries = new ArrayList<>(); + htmlData = null; + sources = new ArrayList<>(); + indices = new ArrayList<>(); } - public Dictionary(final RandomAccessFile raf) throws IOException { - dictFileVersion = raf.readInt(); + public Dictionary(final FileChannel ch) throws IOException { + MappedByteBuffer wholefile = ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size()); + DataInputBuffer in = new DataInputBuffer(wholefile, 0); + dictFileVersion = in.readInt(); if (dictFileVersion < 0 || dictFileVersion > CURRENT_DICT_VERSION) { throw new IOException("Invalid dictionary version: " + dictFileVersion); } - creationMillis = raf.readLong(); - dictInfo = raf.readUTF(); + creationMillis = in.readLong(); + dictInfo = in.readUTF(); // Load the sources, then seek past them, because reading them later // disrupts the offset. try { - final RAFList rafSources = RAFList.create(raf, new EntrySource.Serializer( - this), raf.getFilePointer(), dictFileVersion); - sources = new ArrayList(rafSources); - raf.seek(rafSources.getEndOffset()); + final RAFList rafSources = RAFList.create(in, new EntrySource.Serializer( + this), dictFileVersion, dictInfo + " sources: "); + sources = new ArrayList<>(rafSources); + ch.position(rafSources.getEndOffset()); pairEntries = CachingList.create( - RAFList.create(raf, new PairEntry.Serializer(this), raf.getFilePointer(), dictFileVersion, dictFileVersion >= 7 ? 64 : 1, dictFileVersion >= 7), - CACHE_SIZE); + RAFList.create(in, new PairEntry.Serializer(this), dictFileVersion, dictInfo + " pairs: "), + CACHE_SIZE, false); textEntries = CachingList.create( - RAFList.create(raf, new TextEntry.Serializer(this), raf.getFilePointer(), dictFileVersion), - CACHE_SIZE); + RAFList.create(in, new TextEntry.Serializer(this), dictFileVersion, dictInfo + " text: "), + CACHE_SIZE, true); if (dictFileVersion >= 5) { htmlEntries = CachingList.create( - RAFList.create(raf, new HtmlEntry.Serializer(this), raf.getFilePointer(), dictFileVersion), - CACHE_SIZE); + RAFList.create(in, new HtmlEntry.Serializer(this), dictFileVersion, dictInfo + " html: "), + CACHE_SIZE, false); } else { htmlEntries = Collections.emptyList(); } - indices = CachingList.createFullyCached(RAFList.create(raf, indexSerializer, - raf.getFilePointer(), dictFileVersion)); + if (dictFileVersion >= 7) { + htmlData = RAFList.create(in, new HtmlEntry.DataDeserializer(), dictFileVersion, dictInfo + " html: "); + } else { + htmlData = null; + } + indices = CachingList.createFullyCached(RAFList.create(in, new IndexSerializer(), + dictFileVersion, dictInfo + " index: ")); } catch (RuntimeException e) { - final IOException ioe = new IOException("RuntimeException loading dictionary"); - ioe.initCause(e); - throw ioe; + throw new IOException("RuntimeException loading dictionary", e); } - final String end = raf.readUTF(); + final String end = in.readUTF(); if (!end.equals(END_OF_DICTIONARY)) { throw new IOException("Dictionary seems corrupt: " + end); } @@ -109,6 +118,7 @@ public class Dictionary implements RAFSerializable { @Override public void write(DataOutput out) throws IOException { RandomAccessFile raf = (RandomAccessFile)out; + if (dictFileVersion < 7) throw new RuntimeException("write function cannot write formats older than v7!"); raf.writeInt(dictFileVersion); raf.writeLong(creationMillis); raf.writeUTF(dictInfo); @@ -118,32 +128,33 @@ public class Dictionary implements RAFSerializable { RAFList.write(raf, pairEntries, new PairEntry.Serializer(this), 64, true); System.out.println("text start: " + raf.getFilePointer()); RAFList.write(raf, textEntries, new TextEntry.Serializer(this)); - System.out.println("html start: " + raf.getFilePointer()); - RAFList.write(raf, htmlEntries, new HtmlEntry.Serializer(this)); + System.out.println("html index start: " + raf.getFilePointer()); + RAFList.write(raf, htmlEntries, new HtmlEntry.Serializer(this), 64, true); + System.out.println("html data start: " + raf.getFilePointer()); + assert htmlData == null; + RAFList.write(raf, htmlEntries, new HtmlEntry.DataSerializer(), 128, true); System.out.println("indices start: " + raf.getFilePointer()); - RAFList.write(raf, indices, indexSerializer); + RAFList.write(raf, indices, new IndexSerializer()); System.out.println("end: " + raf.getFilePointer()); raf.writeUTF(END_OF_DICTIONARY); } - private final RAFListSerializer indexSerializer = new RAFListSerializer() { + private final class IndexSerializer implements RAFListSerializer { @Override public Index read(DataInput raf, final int readIndex) throws IOException { - return new Index(Dictionary.this, raf); + return new Index(Dictionary.this, (DataInputBuffer)raf); } @Override public void write(DataOutput raf, Index t) throws IOException { t.write(raf); } - }; + } final RAFListSerializer htmlEntryIndexSerializer = new RAFListSerializer() { @Override - public void write(DataOutput raf, HtmlEntry t) throws IOException { - if (t.index() == -1) - throw new IndexOutOfBoundsException(); - raf.writeInt(t.index()); + public void write(DataOutput raf, HtmlEntry t) { + assert false; } @Override @@ -179,14 +190,17 @@ public class Dictionary implements RAFSerializable { RandomAccessFile raf = null; try { raf = new RandomAccessFile(file, "r"); - final Dictionary dict = new Dictionary(raf); + final Dictionary dict = new Dictionary(raf.getChannel()); final DictionaryInfo dictionaryInfo = dict.getDictionaryInfo(); dictionaryInfo.uncompressedFilename = file.getName(); dictionaryInfo.uncompressedBytes = file.length(); raf.close(); return dictionaryInfo; } catch (IOException e) { - return null; + final DictionaryInfo dictionaryInfo = new DictionaryInfo(); + dictionaryInfo.uncompressedFilename = file.getName(); + dictionaryInfo.uncompressedBytes = file.length(); + return dictionaryInfo; } finally { if (raf != null) { try {