aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Data class cached implementation Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Data class cached implementation" Watch "Data class cached implementation" New topic
Author

Data class cached implementation

Rafal Kawecki
Ranch Hand

Joined: Feb 08, 2011
Posts: 30

Hi Ranchers,

first of all I would like to say hello and thanks for this fourm.
I have already found many answers to my questions despite of not posting even a one

After completing SCJP and SCWCD/OCPJWCD it is high time to get started on SCJD. My assignment is URLyBird. I've got some questions about the Data's class design. I have some basic functionality already implemented but before going further here are my thoughts.

I decided to implement cache instead of direct writing to the database file. When Data class is initialized I read the file and for each entry I incerement a counter, which represents the recNo, and create a new Room class. Then both values (counter and Room) are added to a Map<Integer, Room> (the cache). No rocket science.

Orginal database file retrieved from Oracle contains only valid records (delete flag == 0) therefore after initial reading the Map contains as many entries as records in the database.
The question is: what should happpen if there are deleted records in the file? I could still read all records but when a deleted record is met store it in the Map as null.

For instance <2, null> means that second record is deleted and its place in the file could be reused. So when a new record is created I could look for NULL values in the Map and:
  • if null found replace it with Room instance: Map.put(2, new Room())
  • if not found add new entry to the Map: Map.put(highestRecNo++, new Room())

  • Thanks to this approach I would still have the same number of entries in the Map and records in the file.
    When a Room is deleted (for instance recNo == 5) simple update Map.put(5, null) would represent the situation. Then the record can be reused for new Rooms as described above.

    So far so good but when storing the cache in the file the following problems occur:
  • when going through the Map I do not know which room was deleted by the application and which one was originally deleted so for each entry in the Map where value is null I have to check deletedFlag in the database file: if(deletedFlag == 0) {database.write(1)}. I do not like this solution.
  • I do not know which Rooms were newly created. For instance: initial read -> <2, null> -> new Room created -> Map.put(2, new Room()) so again I need to check the deleted flag in the database file for each entry in the map where value != null but this time the condition will be opposite: if(deletedFlag == 1) {database.write(0)} I do not like it either.


  • One very important notice is that when it comes to programming I tend to make things more complicated that they are in reality so I hope everything is clear enough.
    If not, let me know.

    Thanks in advance.
    Roberto Perillo
    Bartender

    Joined: Dec 28, 2007
    Posts: 2268
        
        3

    Howdy, Rafal. Welcome to JavaRanch!!!

    Champ, my solution was quite similar to what you are proposing. When loading the records to the Map, if the record was deleted, I added it as null to the Map. So, for instance, if record 2 is deleted, then databaseRecords.put(2, null);. I also had a List<Integer> where I put the numbers of the deleted records to be used when creating new records, and I also had an int variable that I kept what would be the next valid number in the file. For instance, if there are 10 records in the file, then the value of this variable would be 11. If the List<Integer> of deleted record numbers was empty, then I would then use the value of this variable to add the new record to the cache and increment it with 1. Otherwise, I would use the first available number in the List<Integer> to create the new record.


    Cheers, Bob "John Lennon" Perillo
    SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
    Rafal Kawecki
    Ranch Hand

    Joined: Feb 08, 2011
    Posts: 30

    Roberto thanks a lot,
    what you wrote sounds fair and it allows you to trace effectively the recNum to be used for a new record. But when you store the cache in the database file you have no idea what the "history" of a particular record is, haven't you? You do not know if it was created as a new one and replaced deleted one, updated, deleted by the applicarion?

    Correct if I'm wrong but while saving a record you need to do the following:

    The code below indicates that the record is deleted but you have no idea if it was deleted now or it has already been marked deleted in the file so the second if condition is requiredCode below indicates that record is not deleted and this has to be done for all the records (!= null) because you do not know if it was udpated or created as a new one replacing the deleted one so the second if condition is required (as above)


    Thanks
    RK
    Roberto Perillo
    Bartender

    Joined: Dec 28, 2007
    Posts: 2268
        
        3

    Howdy, Rafal!

    Well champ, the history of the record doesn't really matter. When you are creating the record, remember that is has already been read, so when you say



    then it wasn't deleted when you first read it, and thus, you don't have to verify the deleted flag again. The algorithm can be something like this:

    Rafal Kawecki
    Ranch Hand

    Joined: Feb 08, 2011
    Posts: 30

    Roberto thanks for the answer but ... I don't get it

    The algorithm is exactly what I implemented and I have no problems with that. What is not clear to me is saving the cache in the database file. What do you mean by saying that
    Roberto Perillo wrote:When you are creating the record, remember that is has already been read
    ?

    When you first read a deleted record from the database what do you do:
  • do you just add it to the cache (databaseRecords.put(2, null)) ?
  • do you just add its number to the list with available recNo to be eligible for usage by new records ?
  • both ?

  • Roberto Perillo wrote:
    when you say

    then it wasn't deleted when you first read it, and thus, you don't have to verify the deleted flag again.
    I don't agree because when you say all you know is that the record 2 in the cache needs to be saved in the database file (if it was null you would just need to update the deletedFlag). But you do not know if this record was created as new one and replaced the deleted one. Let's try with an example. After some time, someone calls create(record) so Now, when you store objects back in the file (i.e when stopping the server): the condition is true because you replaced the deleted record with a new one in the cache but in the database file recNo 2 is still marekd as deleted. So you have no idea that this record replaced the deleted one and you need to check the flag in the file and update it accordingly.

    Thanks again.
    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 5608
        
      15

    I also used a record cache. All the actions (create, update, delete) are performed on the cache. My cache is represented by a map and a record that's deleted just has null as value in the map.
    When the server is shut down and the cache needs to be written to the database file again, I follow this quiet simple logic: I just iterate thorugh my cache and if a record is deleted, I just write the delete flag and an empty record; when the record is not deleted, I just write the valid flag and the actual contents of the record.


    SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
    http://www.javaroe.be/
    Rafal Kawecki
    Ranch Hand

    Joined: Feb 08, 2011
    Posts: 30

    Hi Roel,

    Roel De Nijs wrote:I just iterate thorugh my cache and if a record is deleted, I just write the delete flag and an empty record; when the record is not deleted, I just write the valid flag and the actual contents of the record.


    So I think I'll do the same, I won't check the deleted flag value and simply set it to 1 for all deleted records (if (databaseRecords.get(i) == null){...}) and 0 for valid ones (if (databaseRecords.get(i) != null){...})
    Thanks for help.

    Probably I'll get back to you with other questions
    Roberto Perillo
    Bartender

    Joined: Dec 28, 2007
    Posts: 2268
        
        3

    Howdy, y'all.

    Roel went even further then me, because when I have to write the records back to the file, I just verify if the value is null, and if it is, I just write the deleted flag and keep whatever is there.

    And Rafal, the algorithm I showed is to create records and just store them on the memory cache... sorry for not covering the "writing the records back to the file" part! But I was just going to say what Roel already said.
    Rafal Kawecki
    Ranch Hand

    Joined: Feb 08, 2011
    Posts: 30

    no problem,
    thanks again - that helped me a lot
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Data class cached implementation