Reputation: 69379
I have several questions regarding a client server model. My current application (or rather my proposed one) uses a central server and different clients can connect to it.
(Small explanation of O(n) for people wanting to answer the questions and not knowing about it, either google or follow this example:
Consider a list with n elements. O(1) means that you can just pick the element and O(n) basically means that you possibly have to iterate over every element (thus n elements) to get the item you want. And O(log n) is a middle way having to do with recursive subdivision which is still a lot faster as O(n) but not as fast as O(1).)
Question 1:
How can I efficiently retrieve records of users, I got no clue how many users the server will have to handle at some point, but I strongly believe that O(n) operations just will not suffice if O(1) is reasonble to implement.
First part is about the login procedure, I plan to let the user login with a personal identifier (username/email/etc.) and a password, this information gets sent to the server once someone tries to log in.
Furthermore I also plan to not use a database (for example MySQL) directly, but purely for 'backup' purposes (the server should store all information in RAM if possible, and only write it to the database such that nothing gets lost when power gets lost).
So basically the server needs to store the Client data (including the personal identifier, but also an unique ID).
My current ideas:
Store in a List, however then searching for a user (and then validate his information) may take O(n) time depending on the sorting, I could cut it down to O(log n) if I do something with alphabetical sorting on username.
Second proposal would be to store it in a Client[] array with the UniqueID's as keys. Then access in O(1) should be possible which is ideal, however the problem I am having with that approach is how do I convert the personal identifier (username, etc.) which the user puts in and sends to the server, to his unique ID? If I use anything like a List then the time will be O(n) again. Moreover, the array size may not be unproportionally huge, as it would simply allocate too much memory, for example I do not think that hashing the users name is ideal nor am I sure if it creates a unique ID.
Question 2:
Secondly I also want my userdata to be secure of course. Now assume that the underlying MySQL server (from which the data gets loaded into server's RAM at startup) is secure.
Then I wonder are the saved passwords (encrypted of course) also safe given these conditions?
Nothing has direct physical access to the server.
The communication protocol has no commands to retrieve password information or a superset including the password information, meaning that the server will under no conditions give out the password.
The passwords are stored as private variables in the Client objects that hang around in the server's RAM.
To check if the information a user has entered, is correct the Client object has a function like client.confirmPassword(password)
.
So unless I have forgotten things, the question basically comes down to can the RAM of the Server be directly read given that it is only connected to the outside world via a communication protocol?
Post turned out to be pretty long, but I hope there are people around that can answer these questions :)
Upvotes: 0
Views: 165
Reputation: 5944
Contrary to the answer tkr's answer, Hashmap has not O(1) performance. Please see this question: "Is a java hasmap really O(1)"
Depending on the multithreaded nature of your server and the way you would like to do synchronization, you could still use a Hashmap
or Hashtable
, but bear in mind that the performance is somewhere between O(1) and O(n), depending on the number of hash collisions. Also keep in mind that the hash function itself will cause overhead.
Alternatively you might want to look into a binary tree (O(log(n))
My choice would still be to use a database; as others have said, databases store data that is frequently accessed into memory, and therefore are well suited for this kind of tasks. You could run a local in-memory database (e.g. HSQLDB) and flush the data to an external server upon shutdown, and load it from there upon startup.
As for storing passwords in a database, make sure that you use a secure hash function such as SHA-1. Don't forget to salt the password in order to make decryption of password even harder if someone would get access to your password database accidentally.
Upvotes: 1
Reputation: 342
Upvotes: 1
Reputation: 1381
Question 1)
I would consider the use of a hashmap. It has has access in O(1). You could even use multiple hashmaps:
You should have a look at different map implementations because of concurreny.
Question 2)
As long as the password is properly encrypted I think you are fine. In regular circumstances the server Memory is considered safe.
Probably this other question is of interest for you: Best way to store password in database
Upvotes: 1
Reputation: 354
You are worrying about wrong reasons
it is a lot easier to do things for which solutions are already built like databases, libraries etc. They are made for performance and are very immune to wrong inputs also have better ways to deal with worst case scenarios.
Upvotes: 1