• Post Reply Bookmark Topic Watch Topic
  • New Topic

Which approach is better (not just faster)  RSS feed

 
Alok Pota
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a huge HashMap that is allocated per application user. I have three options to store this HashMap
#1. Store the map in the user session (such as HttpSession)
#2. Bind the map to a JNDI context such that i.e., context.bind(userid, new HashMap());
#3. Have a database table with userid & BLOB columns with the blob column being the serialized HashMap.

Approach #1
-----------
Although the fastest is also the fastest way to get to an OutOfMemoryError, as I am allocating new objects per user. For 1000 concurrent users, I could quickly be running out of heap
space. Worst yet in a browser based application, the HttpSession is invalidated only at intervals of say (minutes) and canceling the browser would hold those objects for atleast that many more minutes before I can null them and *qualify* them for garbage collection.
Approach #2.
-----------
I am basing this on the assumption that JNDI binds objects to
the disk and not the memory. (I really need clarification on this one). This would be slow as I would have to lookup the HashMap but then once I have a handle to the HashMap I can do O(1) gets on the map (I guess?). Binding objects to the JNDI, I HOPE is not taking up java heap. (Please clarify)

Approach #3.
-----------
The slowest and also the most memory efficient (I guess) approach. I will be getting objects directly from the DB.
My priorities for this are as follows:
1. Scalability: I want to be able to support an ever increasing
number of users without choking the JVM.
2. Speed.
Note: Speed is not the first one :-)
 
Frank Carver
Sheriff
Posts: 6920
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Before looking at the direct implications of this, I'd like to know a little more about what sort of data you are holding in your "huge hashmap". If your data entries are strings or other simple data types, then you might be much better off using a database directly.
Imagine a table with columns: user, key and value. Retrieving the whole hashmap for a user is as simple as "select key, value from data where user='id'". Retrieving a single value is equally simple, and doesn't need the whole map to be loaded: "select value from data where user='id' and key='something'".
Does each user need full read/write access to all the fields in the map or are some/all read-only? Is there any overlap between the values held for different users or different keys? Either of these could influence the choice of data storage.
Please let us know more ...
 
Alok Pota
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The stuff I am storing is a tree structure. The tree consists of nodes modeled by the NODES table.
NODES
-----
ID | PARENT_ID | NAME
| |
There are three kinds of data for a give node 'a':
1. The data corresponding to the node 'a' (id, parent_id, name)
2. The parent-child relationship of the node (a list of the
immediate children of the node 'a')
3. Any user specific filters defined that will allow/disallow a
user to see certain nodes under 'a' and above 'a'.
Data of type #1 & #2 is shared among the users and seldom changes
You can say its read-only. Data #3 is what gets currently stored in the session. I filter out data #1 using TreeNode object
class TreeNode { ...
TreeNode(id, parent_id, name)
}
and data #2 is just a List (ArrayList) of the direct childrn of that node. because #1 & #2 remain pretty much the same for all users, I store them in an in-process JNDI context
Map datamap = new HashMap();
Map childrenmap = new HashMap();
datamap.put("id1", new TreeNode("id1", "pid1", "CA");
datamap.put("id2", new TreeNode("id2", "pid2", "TX");
List cities1 = new ArrayList();
cities1.add("SF");
cities1.add("LA"); .. so on
List cities2 = new ArrayList();
cities2.add("DALLAS");
cities2.add("AUSTIN"); .. so on
childrenmap.put("id1", cities1);
childrenmap.put("id2", cities2);
context.bind("data", datamap);
context.bind("children", childrenmap);

You can see that the nature of data #1 & #2 is pretty much common to all users and I don't want to duplicate that information in each user's session (hence JNDI). Because I am never removing stuff from the context, I am not concerned about concurrent access, because even if two threads did end up conflicting they would both eventually end up doing the same thing i.e., putting say San Diego under California.

The question that I really want to ask is does binding to an in-process JNDI
consume memory? If that is not the case then theoritically I can get away with storing lots of common data in the JNDI context and keep my user HttpSession's lightweight.
 
Alok Pota
Ranch Hand
Posts: 185
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I also would like to point out that, the reason I have to do all these coding gymnastics is because I am trying to keep a strict partition between the M,V and C of the classic MVC pattern. My views (JSPs/Servlets) should not be concerned with fetching data from the database and all the proeceesing logic. All that is handled by the "M". But then how do I get this data from "M" to "V" at the time of rendering the page. I need some intermediate data structure to hold this data I got from the database.
-Alok
 
Frank Carver
Sheriff
Posts: 6920
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But do you need to show all of the huge hash map to the view at once? If the view only needs to see a subsection of the whole data on any given page, that is all you need to pass from the model to the view.
Just like any Java class, the Model in a MVC pattern should be coded in terms of capabilities, not just the data it holds. If a typical user screen shows just cities within 30 miles of Fort Worth (say), then the model should have an API which allows just that data to be extracted. Neither the view nor the controller should know that the data is actually in a tree structure, or how that data was located.
Can you give a few more details about typical views in this system?
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!