Skip to content

Instantly share code, notes, and snippets.

@archangel-irk
Last active January 20, 2019 13:55
Show Gist options
  • Save archangel-irk/07b0d318970230047ecedb81577684f1 to your computer and use it in GitHub Desktop.
Save archangel-irk/07b0d318970230047ecedb81577684f1 to your computer and use it in GitHub Desktop.
// Complexity for getBondsData - 3n
// Memory - ?
class BondsCache {
constructor() {
this.data = new Map();
}
getId(date, isin) {
return `${date}_${isin}`;
}
getItem(id) {
return this.data.get(id);
}
setItem(id, item) {
this.data.set(id, item);
}
clear() {
this.data.clear();
}
size(){
return this.data.size;
}
isCached(id) {
return this.data.has(id);
}
getCachedData(date, isins) {
const result = {
cached: [],
uncached: [],
};
isins.forEach((isin) => {
const id = this.getId(date, isin);
if (this.isCached(id)) {
result.cached.push(this.getItem(id));
} else {
result.uncached.push(isin);
}
});
return result;
}
put(date, items) {
items.forEach((item) => {
this.setItem(this.getId(date, item.isin), item);
});
}
}
const cache = new BondsCache();
const getBondsData = async ({date, isins}) => {
const data = cache.getCachedData(date, isins);
let result = [];
if (data.uncached.length) {
result = await http.post({
url: `/bonds/${date}`,
body: data.uncached,
});
cache.put(date, result);
}
return [].concat(data.cached, result);
};
// getBondsData({
// date: '20180120',
// isins: ['XS0971721963', 'RU000A0JU4L3']
// });
function assert(condition, message) {
if (!condition) {
throw new Error(message || 'Assertion failed');
}
}
async function test(name, func) {
try {
await func();
console.log(name, ': passed')
} catch (exception) {
console.log(name, ': failed');
console.error(exception);
}
}
test('Put data into cache', () => {
const cache = new BondsCache();
const date = '20180120';
const items = [{
isin: 'XS0971721963',
data: {}
}, {
isin: 'RU000A0JU4L3',
data: {}
}];
cache.put(date, items);
const id1 = cache.getId(date, items[0].isin);
const id2 = cache.getId(date, items[1].isin);
assert(cache.getItem(id1).isin === items[0].isin, 'First item is not match after `put`');
assert(cache.getItem(id2).isin === items[1].isin, 'Second item is not match after `put`');
assert(cache.size() === 2, '`size` is not correct after `put`');
});
test('Check cached data with initial cache', () => {
const cache = new BondsCache();
const date = '20180120';
const cachedIsin = 'XS0971721963';
const uncachedIsin = 'RU000A0JU4L3';
const previousResult = [{
isin: cachedIsin,
data: {}
}];
const request = {
date,
isins: [cachedIsin, uncachedIsin]
};
// Set initial cache
const prevId1 = cache.getId(date, cachedIsin);
cache.put(date, previousResult);
assert(cache.size() === 1, '`size` is not correct after `put`');
assert(cache.getItem(prevId1).isin === cachedIsin, 'Cached item is not matched after `put`');
// Check cached data
let data = cache.getCachedData(request.date, request.isins);
assert(data.cached.length === 1, 'cached length is not correct');
assert(data.uncached.length === 1, 'uncached length is not correct');
assert(data.cached[0].isin === cachedIsin, 'Cached item is not matched');
assert(data.uncached[0] === uncachedIsin, 'Uncached item is not matched');
// Cache api result
cache.put(date, [{ isin: data.uncached[0], data: {} }]);
assert(cache.size() === 2, '`size` is not correct after `put` api result');
// Check cached data
data = cache.getCachedData(request.date, request.isins);
assert(data.cached.length === 2, 'cached length is not correct');
assert(data.uncached.length === 0, 'uncached length is not correct');
assert(data.cached[0].isin === cachedIsin, 'Cached item is not matched');
assert(data.cached[1].isin === uncachedIsin, 'Cached item is not matched');
cache.clear();
assert(cache.size() === 0, '`size` is not correct after clear');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment