Title: ArchivedArrayListSolution
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Solution to ArchivedArrayList Exercise


import java.util.*;
import java.io.*;

interface MyRecord
{
    MyRecord create();
    void save(RandomAccessFile ran) throws IOException;
    void fetch(RandomAccessFile ran) throws IOException;
}

// The following will need to be put in a file named Studen.java

public class Student implements MyRecord
{
    int age=54;
    double gpa=3.0;
    final int name_size=15;
    char[] name_arr= new char[name_size];

    Student()
    {
    }

    Student(int a, double g, String n)
    {
       age =a;
       gpa =g;
       for (int i= 0; i < name_arr.length; i++)
       {
            if (i < n.length())
                name_arr[i] = n.charAt(i);
            else
                name_arr[i] = ' ';
       }

    }
    public String toString()
    {
       String retval="name=";

       for (int i =0; i < name_arr.length; i++)
         retval += name_arr[i];

       retval += " age=" + age + " gpa=" + gpa ;

       return retval;
    }

    public MyRecord create()
    {
        return new Student();
    }


    public void save(RandomAccessFile ran) throws IOException
    {
        ran.writeInt(age);
        ran.writeDouble(gpa);
        for (int i=0; i < name_arr.length; i++)
            ran.writeChar(name_arr[i]);
    }
    public void fetch(RandomAccessFile ran) throws IOException
    {
        age = ran.readInt();
        gpa = ran.readDouble();
        for (int i=0; i< name_arr.length; i++)
            name_arr[i] = ran.readChar();
    }


}


class ArchivedArrayList extends ArrayList
{
    RandomAccessFile archive=null;
    long recordSize=-1;
    MyRecord factory;

    ArchivedArrayList(MyRecord f)
    {
        factory = f;
    }

    void setFile(String filename) throws IOException
    {
        archive = new RandomAccessFile(filename, "rw");
    }
    void setSeek(int index) throws IOException
    {
       if (recordSize < 0)
            throw new IOException("Must readAll or saveAll first");

       long seekPtr = recordSize*index + 16;
       archive.seek(seekPtr);
    }

    void saveAll() throws IOException
    {
        if (size() == 0) return; // Nothing to save
        archive.seek(0);
        archive.writeLong(recordSize);
        archive.writeLong(size());
        for (int i=0; i < size(); i++)
        {
            MyRecord rec = (MyRecord)get(i);
            rec.save(archive);
            if (i == 0)
            {
                recordSize = archive.getFilePointer() - 16;
            }
        }
        archive.seek(0);
        archive.writeLong(recordSize);
    }
    void save(int index) throws IOException
    {
        if (recordSize < 0)
            throw new IOException("Must readAll or saveAll first");

        MyRecord rec = (MyRecord)get(index);
        setSeek(index);
        rec.save(archive);
    }
    void readAll() throws IOException
    {
        long recSize;
        long numRecs;
        clear();
        archive.seek(0);
        recSize = archive.readLong();
        numRecs = archive.readLong();
        for (int i=0; i < numRecs; i++)
        {
            MyRecord rec = factory.create();
            rec.fetch(archive);
            if (i==0)
            {
                long calcRecSize = (archive.getFilePointer() - 16);
                if (recSize != calcRecSize)
                {
                    System.out.println("Record Mismatch- calcRecSize=" + calcRecSize +
                        " Recorded Rec Size = " + recSize);
                }
                else recordSize = calcRecSize;
            }
            add(rec);
        }
    }
    void read(int index) throws IOException
    {
        if (recordSize < 0)
            throw new IOException("Must readAll or saveAll first");

        MyRecord rec = factory.create();
        setSeek(index);
        rec.fetch(archive);
        set(index, rec);
    }

    public static void main(String[] args) throws IOException
    {
        Student stud0 = new Student(55, 3.2, "Clem Hasselbach");
        Student stud1 = new Student(30, 3.8, "Prudence");
        Student stud2 = new Student(40, 3.8, "Pete");
        ArchivedArrayList arr = new ArchivedArrayList (stud1);
        arr.setFile("archive.ran");

        arr.add(stud0);
        arr.add(stud1);
        arr.add(stud2);

        arr.saveAll();


        ArchivedArrayList arr2 = new ArchivedArrayList(stud1);
        arr2.setFile("archive.ran");
        arr2.readAll();

        for (int i =0; i < arr2.size(); i++)
        {
            Student st = (Student)arr2.get(i);
            System.out.println(" arr2: " + st);
        }
    }
}