noyjs / users-search-assignment

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implementation Details

To implement this assignment, I used node.js, alongside a few other npm packages, for parsing the CSV file. Since no external database was required/allowed, I loaded all the data to the main memory, using Map and a Prefix Trie as my data structures, in order to get the best asymptotic runtime for the required API.

getting users by id/country:

I used JS Map with id/country as keys.

getting users by age:

I used JS Map with the year, month and day of the user's dob as keys. Also, I used the javascript date object to determine the required dates for the age we are looking for from the GET request.

getting user by name:

I used JS Map with full names and first/last names as keys. Also, I used trie to add the first/last names prefixes, so we can know which keys to retrieve from the userMapByName.

delete user by id:

I retrieve all the relevant user information (name, country, dob) from the userMapByID, which were used as keys in the data structures, and then removed all other references.

Time And Space Complexity Analysis

Time Complexity:

Initialization the data:

In each iteration, we parse a single user from the CSV data file and add it to the Maps and Trie Data Structures. Adding a (key, value) entry to the Map’s data structures should take O(1). Adding a name to the Trie should take O(Length of First/Last name), but we can assume that the length of a first/last name is blocked by some constant size so it should take O(1) as well. Overall, we get that the initialization runtime is O(N) where N is the number of users.

Get user by id:

Getting and retrieving the user from usersMapById by the given id from the GET request – O(1)

Get users list by country:

Getting a reference to all the users living in a specific country by using usersMapByCountry – O(1) Returning All users living in a specific country – O(Ncountry), where Ncountry is the number of users living in the given country from the GET request.

Get users list by age:

Getting a reference to all the users of the given age by using usersMapbyAge – O(1) Returning All users of the specific age – O(Nage), Where Nage is the number of users of that specific given age from the GET request.

Get users list by name:

Getting a reference to all the users of a specific full name or full single/last name by using userNameMap – O(1).

Returning All users of that specific name – O(Nname), Where Nname is the number of users that have that specific name, either full name or as first/last name.

If nothing was found, then we’ll move to match partial name, as follow: Retrieving all names of given prefix – O(M+Nprefix), where M is the maximum length of a first/last name, and N is the number of first/last names that start with that given prefix from the GET request. We can assume that the length of a first/last name is upper bound by some constant therefore we receive O(Nprefix).

We now found all single/last names that match the prefix and we need to extract them from usersMapByName. since we can get a reference to all the users of a specific full name or full single/last name by O(1), as mentioned above, Retrieving all users which their first/last name matches the prefix will take O(NallMatchedUser), where NallMatchedUser is the number of users which their first/last name match the prefix.

Delete user by id

deleting from Maps should take O(1). deleting from trie will occur only if there aren't any other users with the first or last name of the user that about to be deleted. deleting should take O(M), where M is the maximum length of a first/last name in the data. We can assume that the length of a first/last name is upper bound by some constant therefore we receive O(1).

Space Complexity:

Looking at the Initialization data runtime complexity, we can infer that the total space required for the data is O(N*SizeOfUserObject).

We are using Maps and a Trie to store references to the user. Since those data structures uses some of the user’s data as keys (id, name, country, dob), and since we save only a few references to the same object, the total amount of data required to store those keys is still blocked by the size of O(SizeOfUserObject), therefore the total amount of memory that is required is still O(N*SizeOfUserObject).

API

Get user by Id
    - GET /users/a2ee2667-c2dd-52a7-b9d8-1f31c3ca4eae
    - Should return the requested user details 

Get users list by country - GET /users?country=US - Should return a list of all users from requested country

Get users list by age - GET /users?age=30 - Should return all users which are of age 30 at the time of the request

Get users list by name - GET /users?name=Susan - Should return all users which name matches the requested name - Matching names rules: - Full match - for input "Susan James" should return all users with name "Susan James". - Full first name or last name - for input "Susan" should return all users with that first or last name. - Partial match (minimum 3 chars) - for input "Sus", should return all users with first or last name that begin with "Sus". - Should support non case sensitive search (Searching for "susan" should return users with name "Susan").

Delete user by id - DELETE /users/a2ee2667-c2dd-52a7-b9d8-1f31c3ca4eae - Should delete the user, after the call the user will not be returned by any of the previous APIs.

Start up the service

npm install

npm start OR node index.js

About


Languages

Language:JavaScript 100.0%