diff --git a/JavaScript/8-timer.js b/JavaScript/8-timer.js new file mode 100644 index 0000000..95bcaff --- /dev/null +++ b/JavaScript/8-timer.js @@ -0,0 +1,60 @@ +'use strict'; + +const transKey = key => key.toString() + '(' + typeof(key) + ')'; +const createKey = keys => keys.map(key => transKey(key)).join('|'); + +const memoizeTime = ( + // Memoize the results of the fucntion + fn, //Function to memoize + timeout = 0 //Time in milliseconds, if not specify time is unlimited + //Returns: memoized function with time expiration cache +) => { + const cache = new Map(); + if (timeout) setTimeout(() => { + console.log('Clear cache'); + cache.clear(); + timeout = true; + }, timeout); + return (...args) => { + const key = createKey(args); + if (cache.has(key)) { + console.log( + `From cache:, ${fn.name}(${(args.join(', '))}) ${cache.get(key)}` + ); + return cache.get(key); + } + console.log(`Calculate: ${fn.name}(${args.join(', ')})`); + const res = fn(...args); + if (timeout !== true) cache.set(key, res); + return res; + }; +}; + +//Test +const fib = n => (n <= 2 ? 1 : fib(n - 1) + fib(n - 2)); + +const memoTimed = memoizeTime(fib, 500); +memoTimed(2); +memoTimed(5); +memoTimed(5); +memoTimed(6); +memoTimed(2); +memoTimed(2); +memoTimed(8); +memoTimed(9); +memoTimed(8); +memoTimed(9); +setTimeout(() => { + memoTimed(10); + memoTimed(2); + memoTimed(10); + memoTimed(3); + memoTimed(16); + memoTimed(3); + memoTimed(10); + memoTimed(3); + memoTimed(2); + memoTimed(2); + memoTimed(10); + memoTimed(10); +}, 1000); diff --git a/JavaScript/9-count.js b/JavaScript/9-count.js new file mode 100644 index 0000000..35244c5 --- /dev/null +++ b/JavaScript/9-count.js @@ -0,0 +1,68 @@ +'use strict'; + +const transKey = key => key.toString() + '(' + typeof(key) + ')'; +const createKey = keys => keys.map(key => transKey(key)).join('|'); + +const memoizeCount = ( + // Memoize the results of the fucntion + fn, //Function to memoize + length = 0 //Max record in the cache, if not specify records are unlimited + //Returns: memoized function with max records count and removing least used +) => { + const cache = new Map(); + return (...args) => { + const key = createKey(args); + if (cache.has(key)) { + const record = cache.get(key); + console.log( + `From cache:, ${fn.name}(${(args.join(', '))}) ${record.res}` + ); + record.count += 1; + return record.res; + } + console.log(`Calculate: ${fn.name}(${args.join(', ')})`); + const res = fn(...args); + if (length && cache.size >= length) { + let minUsage = length; + let minKey; + for (const [key, value] of cache.entries()) { + if (value.count < minUsage) { + minKey = key; + minUsage = value.count; + } + } + console.log(`Delete element: ${minKey}: ${cache.get(minKey).count}`); + cache.delete(minKey); + } + cache.set(key, { res, count: 0 }); + return res; + }; +}; + +//Test + +const fib = n => (n <= 2 ? 1 : fib(n - 1) + fib(n - 2)); + +const memoCounted = memoizeCount(fib, 7); +memoCounted(2); +memoCounted(5); +memoCounted(5); +memoCounted(6); +memoCounted(7); +memoCounted(7); +memoCounted(2); +memoCounted(9); +memoCounted(6); +memoCounted(2); +memoCounted(9); +memoCounted(2); +memoCounted(15); +memoCounted(3); +memoCounted(15); +memoCounted(3); +memoCounted(10); +memoCounted(10); +memoCounted(19); +memoCounted(18); +memoCounted(19); +memoCounted(10); diff --git a/JavaScript/a-size.js b/JavaScript/a-size.js new file mode 100644 index 0000000..7245d65 --- /dev/null +++ b/JavaScript/a-size.js @@ -0,0 +1,116 @@ +'use strict'; + +const transKey = key => key.toString() + '(' + typeof(key) + ')'; +const createKey = keys => keys.map(key => transKey(key)).join('|'); + +const sizeOf = ( + //Roughly calculate the size of objects + unit, //Unit of information + ...args //Array of object + //Returns: number represents the size of object in the units +) => { + let bytes = 0; + const count = (args) => { + args.forEach(el => size(el)); + }; + function size( + //Calculate size of object + obj //Object of value or reference type + //Returns: number represents the size of object in bytes + ) { + if (obj !== null && obj !== undefined) { + const type = typeof obj; + if (type === 'number') { + bytes += 8; + } else if (type === 'string') { + bytes += obj.length * 2; + } else if (type === 'boolean') { + bytes += 4; + } else if (type === 'object') { + const objClass = Object.prototype.toString.call(obj).slice(8, -1); + if (objClass === 'Object' || objClass === 'Array') { + for (const key in obj) { + if (!obj.hasOwnProperty(key)) continue; + size(obj[key]); + } + } else if (objClass === 'Map') { + for (const [key, value] of obj.entries()) { + size(key); + size(value); + } + } else bytes += obj.toString().length * 2; + } + } + } + const format = ( + //Convert bytes in the other units + number, //number of bytes + unit //unit in which convert + //Returns: size of object in the other units + ) => { + if (unit === 'bytes') return number; + if (unit === 'KiB') return (number / 1024).toFixed(5); + if (unit === 'MiB') return (number / 1048576).toFixed(5); + if (unit === 'GiB') return (number / 1073741824).toFixed(5); + throw new Error('Unknown units'); + }; + + count(args); + return format(bytes, unit); +}; + +const memoizeSize = ( + //Memoize the results of the fucntion + fn, //Function to memoize + maxSize = 0, //Max size of cache, if not specify size is unlimited + unit = 'bytes' //Unit of information, if not specify unit is bytes + //Returns: memoized function with max total stored data size +) => { + const cache = new Map(); + return (...args) => { + const key = createKey(args); + if (cache.has(key)) { + console.log( + `From cache:, ${fn.name}(${(args.join(', '))}) ${cache.get(key)}` + ); + return cache.get(key); + } + console.log(`Calculate: ${fn.name}(${args.join(', ')})`); + const res = fn(...args); + if (sizeOf(unit, cache, key, res) > maxSize && maxSize) { + const firstKey = cache.keys().next().value; + console.log(`Delete element: ${firstKey}: ${cache.get(firstKey)}`); + cache.delete(firstKey); + } + cache.set(key, res); + return res; + }; +}; + +//Tests + +const fib = n => (n <= 2 ? 1 : fib(n - 1) + fib(n - 2)); + +const memoSized = memoizeSize(fib, 200); +memoSized(2); +memoSized(4); +memoSized(5); +memoSized(6); +memoSized(7); +memoSized(2); +memoSized(3); +memoSized(9); +memoSized(8); +memoSized(2); +memoSized(11); +memoSized(2); +memoSized(14); +memoSized(3); +memoSized(16); +memoSized(3); +memoSized(10); +memoSized(13); +memoSized(19); +memoSized(18); +memoSized(10); +memoSized(10); diff --git a/JavaScript/b-univ.js b/JavaScript/b-univ.js new file mode 100644 index 0000000..42e5d8a --- /dev/null +++ b/JavaScript/b-univ.js @@ -0,0 +1,63 @@ +'use strict'; + +const fs = require('fs'); + +const transKey = key => key.toString() + '(' + typeof(key) + ')'; +const createKey = keys => keys.map(key => transKey(key)).join('|'); +const generateKey = (keys, cb) => { + keys = createKey(keys); + if (cb) keys = keys + '(' + cb.length + ')'; + else keys = keys + '(' + cb + ')'; + return keys; +}; + +const memoizeUniv = ( + //Memoize the result of both sync and async functions + fn, //Async or sync function to memoize + lib = null //Library of the functions + //Returns: memoized function +) => { + const cache = new Map(); + const f = lib ? lib[fn] : fn; + return (...args) => { + let cb = null; + if (typeof(args[args.length - 1]) === 'function') cb = args.pop(); + const key = generateKey(args, cb); + if (cache.has(key)) { + const record = cache.get(key); + if (cb) { + console.log('From cache with cb:', cb); + cb(record.err, record.data); + return; + } + console.log(`From cache:, ${f.name}(${(args.join(', '))}) ${record}`); + return record; + } + console.log(`Calculate: ${f.name}(${args.join(', ')})`); + if (cb) { + f(...args, (err, data) => { + cache.set(key, { err, data }); + cb(err, data); + }); + } else { + const res = f(...args); + cache.set(key, res); + return res; + } + }; +}; + +//Test + +const fib = n => (n <= 2 ? 1 : fib(n - 1) + fib(n - 2)); + +const memoSync = memoizeUniv(fib); +const memoAsync = memoizeUniv('readFile', fs); +console.log(memoSync(5)); +console.log(memoSync(5)); +memoAsync('4-async.js', 'utf8', (err, data) => { + console.log('data length:', data.length); + memoAsync('4-async.js', 'utf8', (err, data) => { + console.log('data length:', data.length); + }); +}); diff --git a/JavaScript/c-object.js b/JavaScript/c-object.js new file mode 100644 index 0000000..f1b9bb7 --- /dev/null +++ b/JavaScript/c-object.js @@ -0,0 +1,264 @@ +'use strict'; + +const fs = require('fs'); + +const transKey = key => key.toString() + '(' + typeof(key) + ')'; +const createKey = keys => keys.map(key => transKey(key)).join('|'); +const generateKey = (keys, cb) => { + keys = createKey(keys); + if (cb) keys = keys + '(' + cb.length + ')'; + else keys = keys + '(' + cb + ')'; + return keys; +}; + +const sizeOf = ( + //Roughly calculate the size of objects + unit, //Unit of information + ...args //Array of object + //Returns: number represents the size of object in the units +) => { + let bytes = 0; + const count = (args) => { + args.forEach(el => size(el)); + }; + function size( + //Calculate size of object + obj //Object of value or reference type + //Returns: number represents the size of object in bytes + ) { + if (obj !== null && obj !== undefined) { + const type = typeof obj; + if (type === 'number') { + bytes += 8; + } else if (type === 'string') { + bytes += obj.length * 2; + } else if (type === 'boolean') { + bytes += 4; + } else if (type === 'object') { + const objClass = Object.prototype.toString.call(obj).slice(8, -1); + if (objClass === 'Object' || objClass === 'Array') { + for (const key in obj) { + if (!obj.hasOwnProperty(key)) continue; + size(obj[key]); + } + } else if (objClass === 'Map') { + for (const [key, value] of obj.entries()) { + size(key); + size(value); + } + } else bytes += obj.toString().length * 2; + } + } + } + const format = ( + //Convert bytes in the other units + number, //number of bytes + unit //unit in which convert + //Returns: size of object in the other units + ) => { + if (unit === 'bytes') return number; + if (unit === 'KiB') return (number / 1024).toFixed(5); + if (unit === 'MiB') return (number / 1048576).toFixed(5); + if (unit === 'GiB') return (number / 1073741824).toFixed(5); + throw new Error('Unknown units'); + }; + + count(args); + return format(bytes, unit); +}; + +const memoizator = ( + //Memoize the results of the function + func, //Function to memize + lib = null //Library of the functions + //Returns: functional object +) => { + const cache = new Map(); + const events = new Map(); + const f = lib ? lib[func] : func; + const memo = (...args) => { + let cb = null; + if (typeof(args[args.length - 1]) === 'function') cb = args.pop(); + const key = generateKey(args, cb); + if (cache.has(key)) { + const record = memo.get(key); + record.count += 1; + if (cb) { + console.log('From cache with cb:', cb); + cb(record.err, record.data); + return; + } + console.log(`From cache: ${f.name}(${(args.join(', '))}) ${record.res}`); + return record.res; + } + if (memo.maxCount) memo.checkCount(); + console.log(`Calculate: ${f.name}(${args.join(', ')})`); + if (cb) { + f(...args, (err, data) => { + if (!memo.timeout) { + if (memo.size) memo.checkSize(cache, err, data, 'count', 0); + memo.add(key, { + err, + data, + count: 0, + }); + } + cb(err, data); + }); + } else { + const res = f(...args); + if (!memo.timeout) { + if (memo.size) memo.checkSize(cache, res, 'count', 0); + memo.add(key, { + res, + count: 0, + }); + } + return res; + } + }; + + const methods = { + clear() { + if (events.has('clear')) this.emit('clear'); + cache.clear(); + return this; + }, + add(key, value) { + if (!cache.has(key)) { + cache.set(key, value); + if (events.has('add')) this.emit('add', cache, key); + return this; + } + }, + del(key) { + if (cache.has(key)) { + if (events.has('del')) this.emit('del', cache, key); + cache.delete(key); + } + return this; + }, + get(key) { + if (cache.has(key)) return cache.get(key); + }, + setTime(msec) { + setTimeout(() => { + this.clear(); + this.timeout = true; + }, msec); + return this; + }, + setMaxSize(size, unit = 'bytes') { + this.size = size; + this.unit = unit; + this.checkSize(cache); + return this; + }, + checkSize(...args) { + while (sizeOf(this.unit, ...args) > this.size) { + console.log('\nSize check'); + const key = cache.keys().next().value; + this.del(key); + return this; + } + }, + setMaxCount(count) { + this.maxCount = count; + this.checkCount(); + return this; + }, + checkCount() { + while (cache.size >= this.maxCount) { + console.log('\nRecords check'); + let minUsage = this.maxCount; + let minKey = ''; + for (const [key, value] of cache.entries()) { + if (value.count < minUsage) { + minKey = key; + minUsage = value.count; + } + } + this.del(minKey); + } + return this; + }, + on(name, fn) { + const event = events.get(name); + if (event) event.push; + else events.set(name, [fn]); + return this; + }, + emit(name, ...data) { + const event = events.get(name); + event.forEach(fn => fn(...data)); + return this; + } + }; + + return Object.assign(memo, methods); +}; + +//Test +const fib = n => (n <= 2 ? 1 : fib(n - 1) + fib(n - 2)); + +const memo = memoizator('readFile', fs); + +memo('4-async.js', 'utf8', (err, data) => { + console.log('data length:', data.length); + memo('4-async.js', 'utf8', (err, data) => { + console.log('data length:', data.length); + }); +}); + +const memoized = memoizator(fib) + .setMaxCount(12) + .setTime(1000) + .setMaxSize(350) + .on('del', (cache, key) => console.log( + `Delete element: ${key}: ${JSON.stringify(cache.get(key))}`) + ); + +memoized(5); +memoized(5); +memoized(2); +memoized(6); +memoized(5); +memoized(6); +memoized(8); +memoized(2); +memoized(3); +memoized(9); +memoized(8); +memoized(6); +memoized + .on('add', (cache, key) => console.log( + `Add element: ${key}: ${JSON.stringify(cache.get(key))}`) + ) + .on('clear', () => console.log('Clear cache')); +setTimeout(() => { + memoized(2); + memoized(14); + memoized(14); + memoized(9); + memoized(19); + memoized(3); + memoized(10); + memoized(13); + memoized(19); + memoized(19); + memoized(10); + memoized(10); + memoized(19); + memoized(6); + memoized(2); + memoized.setMaxCount(5); + setTimeout(() => { + memoized(7); + memoized(20); + memoized(21); + memoized(7); + memoized(20); + memoized(21); + memoized(5); + }, 500); +}, 500); diff --git a/JavaScript/d-timeout.js b/JavaScript/d-timeout.js new file mode 100644 index 0000000..0a93cd2 --- /dev/null +++ b/JavaScript/d-timeout.js @@ -0,0 +1,63 @@ +'use strict'; + +const transKey = key => key.toString() + '(' + typeof(key) + ')'; +const createKey = keys => keys.map(key => transKey(key)).join('|'); + +const memoizeTime = ( + // Memoize the results of the fucntion + fn, //Function to memoize + msec //Time for each element in cache in milliseconds + //Returns: memoized function with limited time in the cache for each element +) => { + const cache = new Map(); + return (...args) => { + const key = createKey(args); + const timeout = setTimeout(() => { + console.log(`Delete: ${key}`); + cache.delete(key); + }, msec); + if (cache.has(key)) { + const record = cache.get(key); + clearTimeout(record.timeout); + record.timeout = timeout; + console.log( + `From cache:, ${fn.name}(${(args.join(', '))}) ${record.res}` + ); + return record.res; + } + console.log(`Calculate: ${fn.name}(${args.join(', ')})`); + const res = fn(...args); + cache.set(key, { res, timeout }); + return res; + }; +}; + +const fib = n => (n <= 2 ? 1 : fib(n - 1) + fib(n - 2)); + +const memoTimed = memoizeTime(fib, 300); +memoTimed(2); +memoTimed(5); +memoTimed(5); +memoTimed(6); +memoTimed(2); +memoTimed(9); +memoTimed(8); +memoTimed(10); +memoTimed(8); +memoTimed(9); +setTimeout(() => { + memoTimed(10); + memoTimed(6); + memoTimed(10); + memoTimed(3); + memoTimed(16); + memoTimed(3); + setTimeout(() => { + memoTimed(10); + memoTimed(3); + memoTimed(2); + memoTimed(2); + memoTimed(10); + memoTimed(10); + }, 200); +}, 200); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy