Skip to content

Homework tasks #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
47 changes: 47 additions & 0 deletions JavaScript/8-timer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8-timeout.js


const memoize = (fn, msec = 100) => {
let cache = {};
let timer = setTimeout(() => {
console.log('Cache cleaned');
timer = null;
cache = {};
}, msec);

const setTimer = msec => {
timer = setTimeout(() => {
console.log('Cache cleaned');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove duplicate code

timer = null;
cache = {};
}, msec);
};

const generateKey = (...args) => args.join('|');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add types to cache key


return (...args) => {
if (!timer) setTimer(msec);
const key = generateKey(...args);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass array to generateKey to avoid arguments repack


if (cache[key]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check type, aware of 0, false and empty string

console.log(`From cache: ${args} = ${cache[key]}`);
return cache[key];
}

console.log(`Calculate: ${args} = ${fn(...args)}`);
const res = fn(...args);
cache[key] = res;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not write undefined to cache

console.log(cache);
return res;
};
};

const sum = (a, b) => a + b;

const sumM = memoize(sum, 2000);

//USAGE
sumM(1, 2);
sumM(1, 2);
setTimeout(() => {
sumM(1, 2);
}, 2500);
48 changes: 48 additions & 0 deletions JavaScript/9-least.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';

const memoizeLimited = (fn, size) => {
const cache = {};

const generateKey = (...args) => args.join('|');

const leastUsed = () => {
let toDelete = Object.keys(cache)[0];
for (const i in cache) {
if (cache[i].uses < cache[toDelete].uses) {
toDelete = i;
}
}
console.log('Deleting', toDelete);
return toDelete;
};

return (...args) => {
const key = generateKey(...args);

if (cache[key]) {
console.log(`From cache: ${args}`);
cache[key].uses++;
return cache[key].value;
}

if (Object.keys(cache).length === size)
delete cache[leastUsed()];

const res = { value: fn(...args), uses: 0 };
console.log(`Calculating ${args}`);
cache[key] = res;
return cache[key].value;
};
};

//USAGE

const sum = (a, b) => a + b;
const sumM = memoizeLimited(sum, 3);

console.log(`sumM(1, 2) = ${sumM(1, 2)}`); //uses: 0
console.log(`sumM(2, 3) = ${sumM(2, 3)}`); //uses: 0
console.log(`sumM(1, 2) = ${sumM(1, 2)}`); //uses: 1
console.log(`sumM(2, 3) = ${sumM(2, 3)}`); //uses: 2
console.log(`sumM(1, 3) = ${sumM(1, 3)}`); //uses: 0
console.log(`sumM(5, 6) = ${sumM(5, 6)}`); //uses: 0
80 changes: 80 additions & 0 deletions JavaScript/a-bytes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
'use strict';

const memoizeBytes = (fn, size) => {
let cache = {};

const generateKey = (...args) => args.join('|');

const sizeToBytes = (size) => {
const length = size.length;
const data = parseFloat(size, 10);
let k = 1;
switch (size.charAt(length - 1)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use new Map or {} for large cases

case 'T': k *= 1000;
case 'G': k *= 1000;
case 'M': k *= 1000;
case 'K': k *= 1000;
case 'B': break;
default: break;
}
return data * k;
};

const sizeInBytes = sizeToBytes(size);

const getSize = (obj) => {
let bytes = 0;
for (const i in obj) {
switch (typeof obj[i]) {
case 'number':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
  number: 8,
  boolean: 4
  ....
}

bytes += 8;
break;
case 'boolean':
bytes += 4;
break;
case 'string':
bytes += obj[i].length * 2;
break;
case 'object':
bytes += getSize(obj[i]);
break;
default: throw new Error('getSize: Wrong field type.');
}
}
return bytes;
};

return (...args) => {
const key = generateKey(...args);

if (cache[key]) {
console.log(`From cache: ${key}`);
return cache[key];
}

if (getSize(cache) >= sizeInBytes) {
console.log(`Cache with size ${getSize(cache)} bytes cleaned`);
cache = {};
}

console.log(`Calculating: ${key}`);
cache[key] = fn(...args);
console.dir(`Cache size: ${getSize(cache)}`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calculate getSize(cache) once

return fn(...args);
};
};

//USAGE

const sum = (a, b) => a + b;
const sumB = memoizeBytes(sum, '32B');
console.log(`sumB(1, 2) = ${sumB(1, 2)}`);
console.log(`sumB(1, 2) = ${sumB(1, 2)}`);
console.log(`sumB(2, 3) = ${sumB(2, 3)}`);
console.log(`sumB(3, 2) = ${sumB(3, 2)}`);
console.log(`sumB(4, 2) = ${sumB(4, 2)}`);
console.log(`sumB(2, 3) = ${sumB(2, 3)}`);
console.log(`sumB(1, 3) = ${sumB(1, 3)}`);
console.log(`sumB(4, 3) = ${sumB(4, 3)}`);
console.log(`sumB(9, 3) = ${sumB(1, 3)}`);
console.log(`sumB(8, 3) = ${sumB(8, 3)}`);
54 changes: 54 additions & 0 deletions JavaScript/b-universal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use strict';

const memeizeUniversal = fn => {
const cache = {};
const generateKey = (...args) => args.join('|');

return (...args) => {
let callback;
if (typeof args[args.length - 1] === 'function')
callback = args.pop();
const key = generateKey(...args);

if (cache[key]) {
if (callback) {
console.log(`Async cache: ${key}`);
callback(cache[key].err, cache[key].data);
return;
}
console.log(`Sync cache: ${key}`);
return cache[key];
}

if (callback) {
console.log(`Async calc: ${key}`);
fn(...args, (err, data) => {
cache[key] = { err, data };
callback(err, data);
});
return;
}
console.log(`Sync calc: ${key}`);
cache[key] = fn(...args);
return cache[key];
};
};

//USAGE

const fs = require('fs');

const asyncRead = memeizeUniversal(fs.readFile);

asyncRead('b-universal.js', 'utf8', (err, data) => {
console.log('data length:', data.length);
asyncRead('b-universal.js', 'utf8', (err, data) => {
console.log('data length:', data.length);
});
});

const сум = (a, b) => a + ' => ' + b;
const журба = memeizeUniversal(сум);
console.log(журба('Грушевський', 'Житомир'));
console.log(журба('Скоропадський', 'Мотовилівка'));
console.log(журба('Грушевський', 'Житомир'));
134 changes: 134 additions & 0 deletions JavaScript/c-object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
'use strict';

const generateKey = (...args) => args.join('|');
const getSize = (obj) => {
let bytes = 0;
for (const i in obj) {
switch (typeof obj[i]) {
case 'number':
bytes += 8;
break;
case 'boolean':
bytes += 4;
break;
case 'string':
bytes += obj[i].length * 2;
break;
case 'object':
bytes += getSize(obj[i]);
break;
default: throw new Error('getSize: Wrong field type.');
}
}
return bytes;
};

const memoizator = fn => {
let cache = {};
const events = [];

const func = (...args) => {
const key = generateKey(...args);

if (func.timeout && !func.timer) {
func.timer = setTimeout(() => {
cache = {};
console.log(`Cache cleared after ${func.timeout} msec`);
}, func.timeout);
}

if (cache[key]) {
console.log(`From cache ${key}`);
return cache[key];
}

if (func.maxSize && getSize(cache) >= func.maxSize) {
console.log(`Cache with size ${getSize(cache)} bytes cleaned`);
cache = {};
}

const cacheSize = Object.keys(cache).length;
if (func.maxCount && cacheSize >= func.maxCount) {
console.log(`Cache with length ${cacheSize} cleaned`);
}

console.log(`Calc ${key}`);
cache[key] = fn(...args);
return cache[key];
};

func.clear = () => {
console.log('Cache cleared');
cache = {};
};

func.add = (key, value) => {
if (cache[key]) throw new Error('This key already exists');
else cache[key] = value;
console.log(`${key} added`);
};

func.get = (key) => cache[key];

func.del = (key) => {
if (cache[key]) {
console.log(`${key} deleted`);
delete cache[key];
return;
}
console.log(`There is no ${key}`);
};

func.on = (name, fn) => {
if (events[name]) throw new Error('Event already exists');
if (!['clear', 'add', 'del'].find((el) => (el === name)))
throw new Error('Wrong event name');
events[name] = fn;
};

func.emit = (name, data) => {
if (name === 'clear') {
events[name](cache);
func.clear();
return true;
}
if (name === 'add') {
const res = data.map((el) => events[name](el));
res.map((el, key) => func.add(key, el));
return true;
}
if (name === 'del') {
const res = [];
res.push(events[name](...data, cache));
res.map((key) => func.del(key));
return true;
}
throw new Error('Frong event name');
};

func.timeout = null;
func.maxSize = null;
func.maxCount = null;

return func;
};

//USAGE

const sum = (a, b) => a + b;
const sumM = memoizator(sum);
console.log(sumM(1, 1));
sumM.maxCount = 3;
sumM.timeout = 100;
sumM.maxSize = 32;

sumM.on('clear', (cache) => console.dir({ cache }));
sumM.emit('clear');

const fibbo = (n) => (n < 2 ? 1 : fibbo(n - 1) + fibbo(n - 2));
sumM.on('add', fibbo);
sumM.emit('add', [1, 2, 3]);

sumM(1, 2);
sumM.on('del', (el) => generateKey(el, el + 1));
sumM.emit('del', [1]);
Loading