ss: Bug 454057: Use serialization to write the list of attributes to disk
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 10 Apr 2015 20:20:11 +0000 (16:20 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Mon, 13 Apr 2015 17:05:02 +0000 (13:05 -0400)
Simplify the writing of the Attribute Tree to disk by using the
fact that ArrayList is Serializable.

This makes the file format less portable, but the previous method
used String.getBytes(), which is also JVM-dependant. A proper
inter-operable (and more efficient) format could be implemented
at some point once the need arises.

Change-Id: I8622b0975852ed3e022a210dbd720eb4d0fe90f4
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-on: https://git.eclipse.org/r/45682
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
Tested-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-by: Hudson CI
org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/AttributeTree.java
org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTree.java

index ad3682c18a540e5b43a6ad4a633de3d9b37d74c4..330c6ad830e8830de99a86b31bf1ae0339d80cf1 100644 (file)
@@ -18,12 +18,14 @@ package org.eclipse.tracecompass.internal.statesystem.core;
 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
 
 import java.io.BufferedInputStream;
-import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.PrintWriter;
-import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -75,70 +77,29 @@ public final class AttributeTree {
      */
     public AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
         this(ss);
-        DataInputStream in = new DataInputStream(new BufferedInputStream(fis));
-
-        /* Message for exceptions, shouldn't be externalized */
-        final String errorMessage = "The attribute tree file section is either invalid or corrupted."; //$NON-NLS-1$
-
-        ArrayList<String[]> list = new ArrayList<>();
-        byte[] curByteArray;
-        String curFullString;
-        String[] curStringArray;
-        int res, remain, size;
-        int expectedSize = 0;
-        int total = 0;
+        ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(fis));
 
         /* Read the header of the Attribute Tree file (or file section) */
-        res = in.readInt(); /* Magic number */
+        int res = ois.readInt(); /* Magic number */
         if (res != ATTRIB_TREE_MAGIC_NUMBER) {
-            throw new IOException(errorMessage);
-        }
-
-        /* Expected size of the section */
-        expectedSize = in.readInt();
-        if (expectedSize < 12) {
-            throw new IOException(errorMessage);
+            throw new IOException("The attribute tree file section is either invalid or corrupted."); //$NON-NLS-1$
         }
 
-        /* How many entries we have to read */
-        remain = in.readInt();
-        total += 12;
-
-        /* Read each entry */
-        for (; remain > 0; remain--) {
-            /* Read the first byte = the size of the entry */
-            size = in.readByte();
-            curByteArray = new byte[size];
-            res = in.read(curByteArray);
-            if (res != size) {
-                throw new IOException(errorMessage);
-            }
 
-            /*
-             * Go buffer -> byteArray -> String -> String[] -> insert in list.
-             * bleh
-             */
-            curFullString = new String(curByteArray);
-            curStringArray = curFullString.split("/"); //$NON-NLS-1$
-            list.add(curStringArray);
-
-            /* Read the 0'ed confirmation byte */
-            res = in.readByte();
-            if (res != 0) {
-                throw new IOException(errorMessage);
-            }
-            total += curByteArray.length + 2;
-        }
-
-        if (total != expectedSize) {
-            throw new IOException(errorMessage);
+        ArrayList<String[]> attribList;
+        try {
+            @SuppressWarnings("unchecked")
+            ArrayList<String[]> list = (ArrayList<String[]>) ois.readObject();
+            attribList = list;
+        } catch (ClassNotFoundException e) {
+            throw new IOException("Unrecognizable attribute list"); //$NON-NLS-1$
         }
 
         /*
          * Now we have 'list', the ArrayList of String arrays representing all
          * the attributes. Simply create attributes the normal way from them.
          */
-        for (String[] attrib : list) {
+        for (String[] attrib : attribList) {
             this.getQuarkAndAdd(-1, attrib);
         }
     }
@@ -150,52 +111,27 @@ public final class AttributeTree {
      *            The file to write to
      * @param pos
      *            The position (in bytes) in the file where to write
-     * @return The total number of bytes written.
      */
-    public int writeSelf(File file, long pos) {
-        int total = 0;
-        byte[] curByteArray;
-
-        try (RandomAccessFile raf = new RandomAccessFile(file, "rw");) { //$NON-NLS-1$
-            raf.seek(pos);
-
-            /* Write the almost-magic number */
-            raf.writeInt(ATTRIB_TREE_MAGIC_NUMBER);
-
-            /* Placeholder for the total size of the section... */
-            raf.writeInt(-8000);
-
-            /* Write the number of entries */
-            raf.writeInt(this.attributeList.size());
-            total += 12;
-
-            /* Write the attributes themselves */
-            for (Attribute entry : this.attributeList) {
-                curByteArray = entry.getFullAttributeName().getBytes();
-                if (curByteArray.length > Byte.MAX_VALUE) {
-                    throw new IOException("Attribute with name \"" //$NON-NLS-1$
-                            + Arrays.toString(curByteArray) + "\" is too long."); //$NON-NLS-1$
+    public void writeSelf(File file, long pos) {
+        try (FileOutputStream fos = new FileOutputStream(file, true);
+                FileChannel fc = fos.getChannel();) {
+            fc.position(pos);
+            try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
+
+                /* Write the almost-magic number */
+                oos.writeInt(ATTRIB_TREE_MAGIC_NUMBER);
+
+                /* Compute the serialized list of attributes and write it */
+                List<String[]> list = new ArrayList<>(attributeList.size());
+                for (Attribute entry : this.attributeList) {
+                    list.add(entry.getFullAttribute());
                 }
-                /* Write the first byte = size of the array */
-                raf.writeByte((byte) curByteArray.length);
-
-                /* Write the array itself */
-                raf.write(curByteArray);
-
-                /* Write the 0'ed byte */
-                raf.writeByte((byte) 0);
-
-                total += curByteArray.length + 2;
+                oos.writeObject(list);
             }
-
-            /* Now go back and write the actual size of this section */
-            raf.seek(pos + 4);
-            raf.writeInt(total);
-
         } catch (IOException e) {
             e.printStackTrace();
         }
-        return total;
+
     }
 
     /**
index e00629f4c83e0b28ae7dc1ec835efa38afc213fe..8057e4ae0a062b7e19f7d6cc183f08279407da05 100644 (file)
@@ -48,7 +48,7 @@ public class HistoryTree {
     private static final int HISTORY_FILE_MAGIC_NUMBER = 0x05FFA900;
 
     /** File format version. Increment when breaking compatibility. */
-    private static final int FILE_VERSION = 4;
+    private static final int FILE_VERSION = 5;
 
     // ------------------------------------------------------------------------
     // Tree-specific configuration
This page took 0.030948 seconds and 5 git commands to generate.