[jsword-svn] r1790 - trunk/jsword/src/main/java/org/crosswire/jsword/book/sword

dmsmith at www.crosswire.org dmsmith at www.crosswire.org
Wed Apr 9 20:13:11 MST 2008


Author: dmsmith
Date: 2008-04-09 20:13:09 -0700 (Wed, 09 Apr 2008)
New Revision: 1790

Added:
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/DataIndex.java
Modified:
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/IndexKey.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/RawLDBackend.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZLDBackend.java
Log:
Minor performance improvement to LD modules.

Added: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/DataIndex.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/DataIndex.java	                        (rev 0)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/DataIndex.java	2008-04-10 03:13:09 UTC (rev 1790)
@@ -0,0 +1,62 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2007
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
+ */
+package org.crosswire.jsword.book.sword;
+
+/**
+ * Data files are indexed by offset and size.
+ *
+ * @see gnu.lgpl.License for license details.<br>
+ *      The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class DataIndex
+{
+    /**
+     * This data index is defined by an offset into a file and the size of the data to retrieve.
+     * @param offset The position in the file to which to seek
+     * @param size The number of bytes to read from the file.
+     */
+    public DataIndex(int offset, int size)
+    {
+        this.offset = offset;
+        this.size = size;
+    }
+
+    /**
+     * @return the offset
+     */
+    public int getOffset()
+    {
+        return offset;
+    }
+
+    /**
+     * @return the size
+     */
+    public int getSize()
+    {
+        return size;
+    }
+
+    private int offset;
+    private int size;
+}
\ No newline at end of file

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/IndexKey.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/IndexKey.java	2008-04-09 21:48:06 UTC (rev 1789)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/IndexKey.java	2008-04-10 03:13:09 UTC (rev 1790)
@@ -35,12 +35,11 @@
     /**
      * Setup with the key name and positions of data in the file
      */
-    IndexKey(String text, int offset, int size, Key parent)
+    IndexKey(String text, DataIndex position, Key parent)
     {
         super(text, text, parent);
 
-        this.offset = offset;
-        this.size = size;
+        this.position = position;
     }
 
     /**
@@ -48,23 +47,31 @@
      */
     IndexKey(String text)
     {
-        this(text, -1, -1, null);
+        this(text, NULL_INDEX, null);
     }
 
     /**
+     * @return
+     */
+    public DataIndex getDataIndex()
+    {
+        return position;
+    }
+
+    /**
      * @return the offset
      */
     public int getOffset()
     {
-        return offset;
+        return position.getOffset();
     }
 
     /**
      * @param newOffset the offset to set
      */
-    public void setOffset(int newOffset)
+    public void setIndex(DataIndex newPosition)
     {
-        offset = newOffset;
+        position = newPosition;
     }
 
     /**
@@ -72,17 +79,9 @@
      */
     public int getSize()
     {
-        return size;
+        return position.getSize();
     }
 
-    /**
-     * @param newSize the size to set
-     */
-    public void setSize(int newSize)
-    {
-        size = newSize;
-    }
-
     /* (non-Javadoc)
      * @see java.lang.Object#clone()
      */
@@ -91,12 +90,18 @@
         return super.clone();
     }
 
-    private int offset;
-    private int size;
+    /**
+     * The position of the data in the data file.
+     */
+    private DataIndex position;
 
     /**
+     * A marker used for search.
+     */
+    private static final DataIndex NULL_INDEX = new DataIndex(-1, -1);
+
+    /**
      * Serialization ID
      */
     private static final long serialVersionUID = -2472601787934480762L;
-
 }

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/RawLDBackend.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/RawLDBackend.java	2008-04-09 21:48:06 UTC (rev 1789)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/RawLDBackend.java	2008-04-10 03:13:09 UTC (rev 1790)
@@ -58,12 +58,12 @@
     {
         super(sbmd);
         this.datasize = datasize;
+        this.entrysize = OFFSETSIZE + datasize;
 
         assert (datasize == 2 || datasize == 4);
 
         String path = getExpandedDataPath();
 
-
         idxFile = new File(path + SwordConstants.EXTENSION_INDEX);
         datFile = new File(path + SwordConstants.EXTENSION_DATA);
 
@@ -130,7 +130,6 @@
         checkActive();
 
         SwordBookMetaData bmd = getBookMetaData();
-        String charset = bmd.getBookCharset();
         Key reply = new DefaultKeyList(null, bmd.getName());
 
         boolean isDailyDevotional = bmd.getBookCategory().equals(BookCategory.DAILY_DEVOTIONS);
@@ -138,11 +137,10 @@
         Calendar greg = new GregorianCalendar();
         DateFormatter nameDF = DateFormatter.getDateInstance();
 
-        int entrysize = OFFSETSIZE + datasize;
         long entries;
         try
         {
-            entries = idxRaf.length() / entrysize;
+            entries = getEntryCount();
         }
         catch (IOException ex)
         {
@@ -150,43 +148,24 @@
             return reply;
         }
 
-        for (int entry = 0; entry < entries; entry++)
+        for (long entry = 0; entry < entries; entry++)
         {
             try
             {
                 // Read the offset and size for this key from the index
-                byte[] buffer = SwordUtil.readRAF(idxRaf, entry * entrysize, entrysize);
-                int offset = SwordUtil.decodeLittleEndian32(buffer, 0);
-                int size = -1;
-                switch (datasize)
-                {
-                case 2:
-                    size = SwordUtil.decodeLittleEndian16(buffer, 4);
-                    break;
-                case 4:
-                    size = SwordUtil.decodeLittleEndian32(buffer, 4);
-                    break;
-                default:
-                    assert false : datasize;
-                }
+                DataIndex index = getIndex(entry);
+                String rawData = getEntry(reply, index);
 
-                // Now read the data file for this key using the offset and size
-                byte[] data = SwordUtil.readRAF(datRaf, offset, size);
-
-                decipher(data);
-
-                int keyend = SwordUtil.findByte(data, SEPARATOR);
+                int keyend = rawData.indexOf(SEPARATOR);
                 if (keyend == -1)
                 {
-                    DataPolice.report("Failed to find keyname. offset=" + offset + " data='" + new String(data) + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    DataPolice.report("Failed to find keyname. offset=" + index.getOffset() + " data='" + rawData + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                     continue;
                 }
 
-                byte[] keydata = new byte[keyend];
-                System.arraycopy(data, 0, keydata, 0, keyend);
+                String keytitle = rawData.substring(0, keyend).trim();
 
-                String keytitle = SwordUtil.decode(reply, keydata, charset).trim();
-                // for some wierd reason plain text (i.e. SourceType=0) dicts
+                // for some weird reason plain text (i.e. SourceType=0) dicts
                 // all get \ added to the ends of the index entries.
                 if (keytitle.endsWith("\\")) //$NON-NLS-1$
                 {
@@ -202,7 +181,7 @@
                     keytitle = nameDF.format(greg.getTime());
                 }
 
-                Key key = new IndexKey(keytitle, offset, size, reply);
+                Key key = new IndexKey(keytitle, index, reply);
 
                 // remove duplicates, keeping later one.
                 // This occurs under some conditions:
@@ -228,6 +207,59 @@
         return reply;
     }
 
+    /**
+     * Get the number of entries in the Book.
+     * @return the number of entries in the Book
+     * @throws IOException 
+     */
+    public long getEntryCount() throws IOException
+    {
+        checkActive();
+        return idxRaf.length() / entrysize;
+    }
+
+    /**
+     * Get the Index (that is offset and size) for an entry.
+     * @param entry
+     * @return
+     * @throws IOException 
+     */
+    public DataIndex getIndex(long entry) throws IOException
+    {
+        // Read the offset and size for this key from the index
+        byte[] buffer = SwordUtil.readRAF(idxRaf, entry * entrysize, entrysize);
+        int offset = SwordUtil.decodeLittleEndian32(buffer, 0);
+        int size = -1;
+        switch (datasize)
+        {
+        case 2:
+            size = SwordUtil.decodeLittleEndian16(buffer, 4);
+            break;
+        case 4:
+            size = SwordUtil.decodeLittleEndian32(buffer, 4);
+            break;
+        default:
+            assert false : datasize;
+        }
+        return new DataIndex(offset, size);
+    }
+
+    /**
+     * Get the text for an indexed entry in the book.
+     * 
+     * @param index the entry to get
+     * @return the text for the entry.
+     * @throws IOException 
+     */
+    public String getEntry(Key reply, DataIndex index) throws IOException
+    {
+        // Now read the data file for this key using the offset and size
+        byte[] data = SwordUtil.readRAF(datRaf, index.getOffset(), index.getSize());
+
+        decipher(data);
+
+        return SwordUtil.decode(reply, data, getBookMetaData().getBookCharset()).trim();
+    }
     /*
      * (non-Javadoc)
      * @see org.crosswire.jsword.book.sword.AbstractBackend#getRawText(org.crosswire.jsword.passage.Key, java.lang.String)
@@ -237,8 +269,6 @@
     {
         checkActive();
 
-        String charset = getBookMetaData().getBookCharset();
-
         if (!(key instanceof IndexKey))
         {
             throw new BookException(Msg.BAD_KEY, new Object[] { ClassUtil.getShortClassName(key.getClass()), key.getName() });
@@ -248,19 +278,15 @@
 
         try
         {
-            byte[] data = SwordUtil.readRAF(datRaf, ikey.getOffset(), ikey.getSize());
+            String data = getEntry(ikey, ikey.getDataIndex());
 
-            int keyend = SwordUtil.findByte(data, SEPARATOR);
+            int keyend = data.indexOf(SEPARATOR);
             if (keyend == -1)
             {
                 throw new BookException(UserMsg.READ_FAIL);
             }
 
-            int remainder = data.length - (keyend + 1);
-            byte[] reply = new byte[remainder];
-            System.arraycopy(data, keyend + 1, reply, 0, remainder);
-
-            return SwordUtil.decode(key, reply, charset).trim();
+            return data.substring(keyend + 1);
         }
         catch (IOException ex)
         {
@@ -297,9 +323,14 @@
     /**
      * How many bytes in the size count in the index
      */
-    private int datasize = -1;
+    private int datasize;
 
     /**
+     * How many bytes for each entry in the index: either 6 or 8
+     */
+    private int entrysize;
+
+    /**
      * The data random access file
      */
     private RandomAccessFile datRaf;

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZLDBackend.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZLDBackend.java	2008-04-09 21:48:06 UTC (rev 1789)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZLDBackend.java	2008-04-10 03:13:09 UTC (rev 1790)
@@ -244,7 +244,7 @@
 
                 String keytitle = SwordUtil.decode(keys, keydata, charset).trim();
 
-                // for some wierd reason plain text (i.e. SourceType=0) dicts
+                // for some weird reason plain text (i.e. SourceType=0) dicts
                 // all get \ added to the ends of the index entries.
                 if (keytitle.endsWith("\\")) //$NON-NLS-1$
                 {
@@ -259,7 +259,7 @@
                     keytitle = nameDF.format(greg.getTime());
                 }
 
-                Key key = new IndexKey(keytitle, offset, size, keys);
+                Key key = new IndexKey(keytitle, new DataIndex(offset, size), keys);
 
                 // remove duplicates, keeping later one.
                 // This occurs under some conditions:




More information about the jsword-svn mailing list