Search code examples
javafilesortingnamessequential

Java: Sequential sorting names and saving into a Random Access File


I am trying to make a program where I can add a name and it's supposed to be saved in a RandomAccessFile, (alphabetically). Whenever I add a name it gets saved in a file, it's supposed to have at the end the next corresponding position for the next name. I'm having problems with the saving whenever I add a name with starting with A, then I add a name with C, and if I where to add a name starting with B it's not pointing me in the right alphabetical order.

Here is what an example of what the program should do:

I add a name starting with A.

Numbers on "left" side are just where the next name start, Numbers on "right" side are the pointers to the next name

[0]-----A----[-1] ----------- the "-1" pointer means its the end of the list

I add a name starting with C.

[0]-----A----[100] ------- the "100" pointer means that the next name "C" start on byte 100

[100]---C----[-1] --------- end of the list pointer, notice how A no longer has the "-1" pointer

I add a name starting with B.

[0]-----A----[200] ------ "A" no longer points to 100 because the next letter should be "B"

[100]---C----[-1] -------- -1 still means that "C" is the end of the list pointer

[200]---B----[100] --------- "B" is pointing at "C" because the next letter after

Here is my code so far, but I'm missing the part where a name that belongs in the middle of the list is added.

public boolean add(String name, String lastName, String telf) {

    try {
        fileSize = file.length();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    if (fileSize == 0) { //must be a new entry

        try {

            byte entry[] = new byte[sizeEntry];  // size of each entry
            file.write(entry);
            file.seek(file.getFilePointer() - sizeEntry);

            file.writeUTF(name);   //name gets saved
            file.writeUTF(lastName);// last name gets saved
            file.writeUTF(telf);    // telf gets saved
            file.writeUTF("N");     // deleted "Y" or "N" gets saved
            file.writeUTF("-1");    // pointer gets saved

        } catch (IOException e) {
            System.out.println("Error at saving....");
            e.printStackTrace();
        }

    } else {
        pPresent= 0;     //variable for the pointer reading
        pPrevious= 0; // variable for the pointer read

        try {
            file.seek(0); //start reading at the top
            do {
                pPresent= file.getFilePointer();//saves present pointer
                file.seek(pPresent);//seeks to present pointer
                nameRead = file.readUTF();  //reads name
                file.readUTF();  //reads last name
                file.readUTF();  //reads telf
                file.readUTF();  //reads deleted?
                pNext= Long.parseLong(file.readUTF()); // reads the next pointer

                int comparison= name.compareTo(nameRead);
                if (comparison< 0) {

                    //enters here if the new entry goes before the present entry
                    if (pNext!= -1) {
                        file.seek(pNext);//enters here if pointer is not at end of list
                    } else {
                        try {// proceeds to writing a new entry 

                            file.seek(file.length()); //goes to the end of the file
                            byte entry[] = new byte[sizeEntry];
                            file.write(entry);
                            file.seek(file.getFilePointer() - sizeEntry);

                            file.writeUTF(name);
                            file.writeUTF(lastname);
                            file.writeUTF(telf);
                            file.writeUTF("N");
                            file.writeUTF(Long.toString(pPrevious));//writes the previous pointer

                            file.seek(pPrevious);//seeks to the previous entry
                            file.readUTF();//reads name
                            file.readUTF();//reads lastname
                            file.readUTF();//reads telf
                            file.readUTF();//reads deleted?
                            file.writeUTF(Long.toString(pPrevious));//overwrites the new previous

                        } catch (IOException e) {
                            System.out.println("Error at saving...");
                            e.printStackTrace();
                        }
                        break;//exits
                    }
                } else {//enteres here if the entry is bigger than the present

                    if (pNext!= -1) {
                        file.seek(pNext);
                    } else {
                        try {

                            pPresent= file.length()-sizeEntry;//saves present entry
                            file.seek(pPrevious); //seeks to previous entry
                            file.readUTF();//reads name
                            file.readUTF();//reads last name
                            file.readUTF();//reads telf
                            file.readUTF();//reads deleted
                            file.writeUTF(Long.toString(pPresent+100));//overwrites the next pointer

                            file.seek(file.length());//seeks at the end
                            byte entry[] = new byte[sizeEntry];//creates a new entry
                            file.write(entry);
                            file.seek(file.getFilePointer() - sizeEntry);

                            file.writeUTF(name);//writes name
                            file.writeUTF(lastname);//writes lastname
                            file.writeUTF(telf);//writes telf
                            file.writeUTF("N");//writes deleted
                            file.writeUTF(Long.toString(pNext));//writes next pointer

                        } catch (IOException e) {
                            System.out.println("Error at saving...");
                            e.printStackTrace();
                        }
                        break;//exits
                    }
                }
                pPresent= file.getFilePointer();//present pointer read
                pPrevious= pPresent;//present pointer becomes previous
            } while (true);


        } catch (IOException e) {

            System.out.println("Error at saving....");
            e.printStackTrace();
        }
    }
    return false;
}

I hope you guys understand the idea of the program a little better now with the source code. The part I don't know how to do is where I add a entry that belongs in the middle of the list. Remember that the order of the names dont change only the pointers pointing to the next do.


Solution

  • Finding the insertion point will require traversing the list, which in turn requires a disk access for every single name. Assuming you have 1 million names, and a typical disk access time of 10 ms, inserting a single name would take about 3 hours. Put differently, linked lists are an extremly unsuitable data structure for storing data on disk.

    A reasonable data structure such as a B-Tree would permit lookup and insertion among 1 million names in as little as 3 disk accesses.