Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,5 @@ Interview Questions
- [Task #2](src/interview/automated-teller-machine) - _Automated Teller Machine_
- [Task #3](src/interview/create-message-handler) - _Create Message Handler_
- [Task #4](src/interview/create-channel-message-handler) - _Create Channel Message Handler_
- [Task #5](src/interview/create-smart-fetch) - _Create Smart Fetch_
- [Task #5](src/interview/create-smart-fetch) - _Create Smart Fetch_
- [Task #6](src/interview/time-limited-cache) - _Time Limited Cache_
21 changes: 21 additions & 0 deletions src/interview/time-limited-cache/solution.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { TimeLimitedCache } from './solution';

describe('Time Limited Cache | Interview | Testcases', () => {
test('#1 Basic functionality', () => {
vi.useFakeTimers();

const cache = new TimeLimitedCache();

expect(cache.set('user', 'Artem', 120)).toBe(false);
expect(cache.get('user')).toBe('Artem');
expect(cache.set('user', 'Bob', 120)).toBe(true);
expect(cache.count()).toBe(1);

vi.advanceTimersByTime(150);

expect(cache.get('user')).toBe(-1);
expect(cache.count()).toBe(0);

vi.useRealTimers();
});
});
55 changes: 55 additions & 0 deletions src/interview/time-limited-cache/solution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Create a cache structure, that stores data inside only for provided duration
*/
export class TimeLimitedCache {
private readonly cache = new Map<
string,
{ value: string; timer: NodeJS.Timeout }
>();

/**
*
* @param key - key of element
* @returns value, stored in cache by key `key`. If there is no such element, `-1` is returned
*/
get(key: string): string | -1 {
const el = this.cache.get(key);
return el?.value ?? -1;
}

/**
* Store provided `value` by `key` in cache for `duration` milliseconds.
* @param key - key to store new data in cache
* @param value - value of data that will be stored
* @param duration - amount of time (in `ms`) that data will exist in cache.
*/
set(key: string, value: string, duration: number): boolean {
const isReassigned = this.cache.has(key);
const timer = setTimeout(() => {
this.delete(key);
}, duration);
this.cache.set(key, { value, timer });

return isReassigned;
}

/**
* Removes the element from the cache
* @param key - key of the element
* @private
*/
private delete(key: string): void {
const el = this.cache.get(key);
if (el) {
clearTimeout(el.timer);
this.cache.delete(key);
}
}

/**
* @returns size of the cache
*/
count(): number {
return this.cache.size;
}
}
Loading