Implement an in-memory database similar to Redis. Be able to read commands via standard input (stdin), and print appropriate responses to standard output (stdout).
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---|---|---|---|---|---|
All files | 97.14 | 94.59 | 100 | 97.14 | |
DatabaseManager.ts | 100 | 100 | 100 | 100 | |
Processor.ts | 93.75 | 94.44 | 100 | 93.75 | 53 |
TransactionManager.ts | 95.83 | 85.71 | 100 | 95.83 | 39 |
constants.ts | 100 | 100 | 100 | 100 |
- Note that this test coverage is generated once the file is commited. This is a placeholder for later CI/CD
Node | Yarn (Optional) | Docker (Optional) |
---|---|---|
18.x.x | Install | Install |
- Note: Can skip install yarn if running the project in production mode using Docker
-
Install dependencies
$ yarn set version stable $ yarn install
-
Setup repository
$ yarn setup
- Running this command to make sure the pre-commit hook would be installed correctly
- Pre-commit hook will be triggered for all
*.ts
files and all other file types supported by Prettier
- Pre-commit hook will be triggered for all
- Running this command to make sure the pre-commit hook would be installed correctly
We can either start the application using Docker or Yarn Note that the docker version is not yet supported for file changes watch
-
Using yarn
$ yarn dev
-
Using Docker
$ npm run docker:dev
$ yarn test
$ yarn build
$ yarn start
$ yarn lint
- This command will run linter for:
- Typescript checking
- Eslint for
*.ts
files - Prettier for the other file types (E.g.
*.md
,*.json
)
$ yarn format
- This command will fix some auto-fixable issues. The rest must be yours
$ yarn depcheck .
- Note that the command will work only if you have not imported the package anywhere
- Execute successfully with test cases provided in the requirement
- Compatible with Typescript
- Has linter, dependencies checker, and pre-commit hook
- Able to run with docker (to skip Yarn installation)
- Test coverage > 90%
- Ready for production deployment
- The current implementation is not the best solution, due to the fact that
TransactionManager
will initialize another layer ofDatabaseManager
whenever a transaction is initialized - Because the time is over (3 hours), I would like to stop the development at this stage, as long as the program can be executed properly (tested with test cases in
src/index.spec.ts
)
- In each transaction, the number of changed variables are not varied. Thus, instead of taking a layer as
DatabaseManager
, we can create another class likeTransactionLayer
, which contains:- List of changed variables within the current transaction
- Values of changed variables within the current transaction
TransactionManager
in this case will have an additional hashmap({[key: string]: TransactionLayer[]})
to store the key and its correspondingTransactionLayer
- Thus, when execute
GET
, we will retrieve theTransactionLayer
based on the key and get the value by theTransactionLayer
- Thus, when execute
- Further explanation:
COMMIT
will initialize an empty layer uppon calledROLLBACK
will pop the layer, and scan through changed keys in order to updatekey - TransactionLayer hashmap
ofTransactionManager
COMMIT
will merge the changed values of current layer with previous layerSET
,UNSET
will be executed on the current layer, and add the key to changed-keys list
- Note:
- Using this approach, the data will be duplicated at the level of
DatabaseManager
andTransactionManager
, since we will need 2 hashmaps to store the key-value and key-TransactionLayer, also 2 hashmaps to handle inverted index of value list
- Using this approach, the data will be duplicated at the level of