Flare-k

Modified Caculating Function Speed

describe("Test suite", function () {
it("should be ok", function () {
assert.equal(true, false)
})
})
\ No newline at end of file
class LRUCache{
constructor(capacity){
this.capacity = capacity;
this.map = new Map();
}
get(key){
const value = this.map.get(key);
if(typeof value === "undefined"){
return -1;
}
this.map.delete(key);
this.map.set(key, value);
return value;
}
put(key, value){
let obj = {};
if(this.map.has(key)){
obj.key = key;
obj.value = this.map.get(key);
this.map.delete(key);
}
else{
obj.key = key;
obj.value = value;
}
this.map.set(key, value);
const keys = this.map.keys();
if(this.map.size > this.capacity){
obj.key = keys.next().value;
obj.value = this.map.get(obj.key);
this.map.delete(obj.key);
}
return obj;
}
}
module.exports = LRUCache;
\ No newline at end of file
......@@ -9,13 +9,16 @@ import mongoose from "mongoose";
import session from "express-session";
import flash from "express-flash";
import MongoStore from "connect-mongo";
import { localsMiddleware } from "./middlewares";
import { localsMiddleware, uploadFile } from "./middlewares";
import File from "./models/File";
import routes from "./routes";
import globalRouter from "./routers/globalRouter";
import fileRouter from "./routers/fileRouter";
import redis from 'redis';
import JSON from 'JSON';
dotenv.config();
const app = express();
const client = redis.createClient(6379,'127.0.0.1');
const CokieStore = MongoStore(session);
......@@ -39,6 +42,84 @@ app.use(
app.use(flash());
app.use(localsMiddleware);
app.use(routes.home, globalRouter);
app.use(routes.files, fileRouter);
//app.use(routes.files, fileRouter);
app.use(function(req,res,next){
req.cache = client;
next();
})
// Caching
app.use(function(req,res,next){
req.cache = client;
next();
})
app.get(`/files${routes.upload}`, (req, res) =>
res.render("upload", { pageTitle: "Upload" }));
app.post(`/files${routes.upload}`, uploadFile, (req, res) => {
// multer를 해야 파일이 넘어가는 것이 나타난다.
req.accepts('application/json');
const key = req.body.title;
const value = JSON.stringify(req.body);
req.cache.set(key, value, (err, data) => {
if(err){
console.log(err);
res.send("error"+err);
return;
}
req.cache.expire(key, 10);
console.log(value);
res.send(value);
});
});
app.get('/files/:title', (req, res, next) => {
const key = req.params.title;
console.log('title : ' + key);
req.cache.get(key, (err, data) => {
if(err){
console.log(err);
res.send("error : " + err);
return;
}
const value = JSON.parse(data);
res.json(value);
});
});
app.get('/view_cache', (req, res) => {
req.cache.get('/files/:title', async (err, data) => {
if(err){
console.log(err);
res.send("error : " + err);
return;
}
if(!data) {
const allData = await File.find({}).sort({ _id: -1 });
const dataArr = JSON.stringify(allData);
req.cache.set('/files/:title', dataArr, (err, data) => {
if(err){
console.log(err);
res.send("error :" + err);
return;
}
req.cache.expire('/files/:title', 10);
res.send(dataArr)
})
}
else {
res.send(data)
}
});
});
export default app; // 파일을 불러올때 app object를 준다는 의미.
......
/* eslint-disable no-console */
import routes from "../routes";
import File from "../models/File";
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
const csvInsertWriter = createCsvWriter({
path: 'insertOutput.csv',
......@@ -23,24 +24,31 @@ export const home = async (req, res) => {
res.render("home", { pageTitle: "Home", files: [] });
}
};
const searchTime = new Array();
// const searchTime = new Array();
export const search = async (req, res) => {
const startTime = new Date().getTime();
console.log(req);
// const startTime = new Date().getTime();
const {
query: { term: searchingBy },
} = req; // == const searchingBy = req.query.term;
let files = [];
try {
files = await File.find({
title: { $regex: searchingBy, $options: "i" }, // i를 옵션으로 추가하면 insensitive.. 대소문자 구분 안함.
title: { $regex: searchingBy, $options: "i" }, // i를 옵션으로 추가하면 insensitive.. 대소문자 구분 안함.
});
/*
const endTime = new Date().getTime(); // SELECT의 경우 파일 시간 측정
searchTime.push({ms: endTime - startTime});
if (searchTime.length === 3){
if (searchTime.length === 50){
csvSelectWriter
.writeRecords(searchTime)
.then(() => console.log("The CSV file was written successfully~"));
}
for (var i = 0; i < searchTime.length; i++){
console.log(i+1 + "번째 속도: " + Object.values(searchTime[i]) + "ms");
}
*/
} catch (error) {
console.log(error);
}
......@@ -54,7 +62,7 @@ export const getUpload = (req, res) =>
const insertTime = new Array();
export const postUpload = async (req, res) => {
const startTime = new Date().getTime();
// const startTime = new Date().getTime();
// multer를 해야 파일이 넘어가는 것이 나타난다.
const {
body: { title },
......@@ -66,14 +74,20 @@ export const postUpload = async (req, res) => {
title,
// 여기있는 fileUrl, title은 fileDB의 속성이다.
});
console.log(newFile);
// console.log(newFile);
/*
const endTime = new Date().getTime(); // INSERT의 경우 파일 시간 측정
insertTime.push({ms: endTime - startTime});
if (insertTime.length === 3){
if (insertTime.length === 50){
csvInsertWriter
.writeRecords(insertTime)
.then(() => console.log("The CSV file was written successfully~"));
}
for (var i = 0; i < insertTime.length; i++){
console.log(i+1 + "번째 속도: " + Object.values(insertTime[i]) + "ms");
}
*/
res.redirect(routes.home);
};
......
......@@ -2,6 +2,7 @@ dotenv.config();
import dotenv from "dotenv";
import app from "./app"; // app.js에서 export default app했기 때문에 불러올 수 있다.
import "./db";
import "./test/lruCache.spec";
import "./models/File";
const PORT = process.env.PORT || 80;
......
time
146
11
5
5
8
9
79
11
2
154
27
10
9
10
53
8
9
4
8
50
5
10
10
9
9
16
3
3
31
29
4
3
3
5
3
3
3
2
12
49
3
4
3
4
60
3
3
3
4
70
......@@ -18,8 +18,8 @@ var LRU = require("lru-cache")
, length: function (n, key) { return n * 2 + key.length }
, dispose: function (key, n) { n.close() }
, maxAge: 1000 * 60 * 60 }
, cache = LRU(options)
, otherCache = LRU(50) // sets just the max size
, cache = new LRU(options)
, otherCache = new LRU(50) // sets just the max size
cache.set("key", "value")
cache.get("key") // "value"
......@@ -49,10 +49,13 @@ away.
* `max` The maximum size of the cache, checked by applying the length
function to all values in the cache. Not setting this is kind of
silly, since that's the whole purpose of this lib, but it defaults
to `Infinity`.
to `Infinity`. Setting it to a non-number or negative number will
throw a `TypeError`. Setting it to 0 makes it be `Infinity`.
* `maxAge` Maximum age in ms. Items are not pro-actively pruned out
as they age, but if you try to get an item that is too old, it'll
drop it and return undefined instead of giving it to you.
Setting this to a negative value will make everything seem old!
Setting it to a non-number will throw a `TypeError`.
* `length` Function that is used to calculate the length of stored
items. If you're storing strings or buffers, then you probably want
to do something like `function(n, key){return n.length}`. The default is
......@@ -76,6 +79,11 @@ away.
it'll be called whenever a `set()` operation overwrites an existing
key. If you set this option, `dispose()` will only be called when a
key falls out of the cache, not when it is overwritten.
* `updateAgeOnGet` When using time-expiring entries with `maxAge`,
setting this to `true` will make each item's effective time update
to the current time whenever it is retrieved from cache, causing it
to not expire. (It can still fall out of cache based on recency of
use, of course.)
## API
......
This diff is collapsed. Click to expand it.
{
"_from": "lru-cache@^4.0.1",
"_id": "lru-cache@4.1.5",
"_from": "lru-cache",
"_id": "lru-cache@6.0.0",
"_inBundle": false,
"_integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"_integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"_location": "/lru-cache",
"_phantomChildren": {},
"_requested": {
"type": "range",
"type": "tag",
"registry": true,
"raw": "lru-cache@^4.0.1",
"raw": "lru-cache",
"name": "lru-cache",
"escapedName": "lru-cache",
"rawSpec": "^4.0.1",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "^4.0.1"
"fetchSpec": "latest"
},
"_requiredBy": [
"/cross-spawn"
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"_shasum": "8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd",
"_spec": "lru-cache@^4.0.1",
"_where": "/Users/noblyan/Desktop/4_2/캡스톤디자인II/2017110267/Project/node_modules/cross-spawn",
"_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"_shasum": "6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94",
"_spec": "lru-cache",
"_where": "/Users/noblyan/Desktop/4_2/캡스톤디자인II/2017110267/Project",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me"
......@@ -31,15 +32,16 @@
},
"bundleDependencies": false,
"dependencies": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
"yallist": "^4.0.0"
},
"deprecated": false,
"description": "A cache object that deletes the least-recently-used items.",
"devDependencies": {
"benchmark": "^2.1.4",
"standard": "^12.0.1",
"tap": "^12.1.0"
"tap": "^14.10.7"
},
"engines": {
"node": ">=10"
},
"files": [
"index.js"
......@@ -58,14 +60,11 @@
"url": "git://github.com/isaacs/node-lru-cache.git"
},
"scripts": {
"coveragerport": "tap --coverage-report=html",
"lintfix": "standard --fix test/*.js index.js",
"postpublish": "git push origin --all; git push origin --tags",
"posttest": "standard test/*.js index.js",
"postversion": "npm publish --tag=legacy",
"postversion": "npm publish",
"prepublishOnly": "git push origin --follow-tags",
"preversion": "npm test",
"snap": "TAP_SNAPSHOT=1 tap test/*.js -J",
"test": "tap test/*.js --100 -J"
"snap": "tap",
"test": "tap"
},
"version": "4.1.5"
"version": "6.0.0"
}
......
var Yallist = require('./yallist.js')
Yallist.prototype[Symbol.iterator] = function* () {
for (let walker = this.head; walker; walker = walker.next) {
yield walker.value
'use strict'
module.exports = function (Yallist) {
Yallist.prototype[Symbol.iterator] = function* () {
for (let walker = this.head; walker; walker = walker.next) {
yield walker.value
}
}
}
......
{
"_from": "yallist@^2.1.2",
"_id": "yallist@2.1.2",
"_from": "yallist@^4.0.0",
"_id": "yallist@4.0.0",
"_inBundle": false,
"_integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
"_integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"_location": "/yallist",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "yallist@^2.1.2",
"raw": "yallist@^4.0.0",
"name": "yallist",
"escapedName": "yallist",
"rawSpec": "^2.1.2",
"rawSpec": "^4.0.0",
"saveSpec": null,
"fetchSpec": "^2.1.2"
"fetchSpec": "^4.0.0"
},
"_requiredBy": [
"/lru-cache"
],
"_resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"_shasum": "1c11f9218f076089a47dd512f93c6699a6a81d52",
"_spec": "yallist@^2.1.2",
"_resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"_shasum": "9bb92790d9c0effec63be73519e11a35019a3a72",
"_spec": "yallist@^4.0.0",
"_where": "/Users/noblyan/Desktop/4_2/캡스톤디자인II/2017110267/Project/node_modules/lru-cache",
"author": {
"name": "Isaac Z. Schlueter",
......@@ -35,7 +35,7 @@
"deprecated": false,
"description": "Yet Another Linked List",
"devDependencies": {
"tap": "^10.3.0"
"tap": "^12.1.0"
},
"directories": {
"test": "test"
......@@ -58,5 +58,5 @@
"preversion": "npm test",
"test": "tap test/*.js --100"
},
"version": "2.1.2"
"version": "4.0.0"
}
......
'use strict'
module.exports = Yallist
Yallist.Node = Node
......@@ -53,6 +54,8 @@ Yallist.prototype.removeNode = function (node) {
node.next = null
node.prev = null
node.list = null
return next
}
Yallist.prototype.unshiftNode = function (node) {
......@@ -317,6 +320,37 @@ Yallist.prototype.sliceReverse = function (from, to) {
return ret
}
Yallist.prototype.splice = function (start, deleteCount, ...nodes) {
if (start > this.length) {
start = this.length - 1
}
if (start < 0) {
start = this.length + start;
}
for (var i = 0, walker = this.head; walker !== null && i < start; i++) {
walker = walker.next
}
var ret = []
for (var i = 0; walker && i < deleteCount; i++) {
ret.push(walker.value)
walker = this.removeNode(walker)
}
if (walker === null) {
walker = this.tail
}
if (walker !== this.head && walker !== this.tail) {
walker = walker.prev
}
for (var i = 0; i < nodes.length; i++) {
walker = insert(this, walker, nodes[i])
}
return ret;
}
Yallist.prototype.reverse = function () {
var head = this.head
var tail = this.tail
......@@ -330,6 +364,23 @@ Yallist.prototype.reverse = function () {
return this
}
function insert (self, node, value) {
var inserted = node === self.head ?
new Node(value, null, node, self) :
new Node(value, node, node.next, self)
if (inserted.next === null) {
self.tail = inserted
}
if (inserted.prev === null) {
self.head = inserted
}
self.length++
return inserted
}
function push (self, item) {
self.tail = new Node(item, self.tail, null, self)
if (!self.head) {
......@@ -368,3 +419,8 @@ function Node (value, prev, next, list) {
this.next = null
}
}
try {
// add if support for Symbol.iterator is present
require('./iterator.js')(Yallist)
} catch (er) {}
......
This diff is collapsed. Click to expand it.
......@@ -7,7 +7,7 @@
"dev:server": "nodemon --exec babel-node init.js --delay 2 --ignore '.scss' --ignore 'static'",
"dev:assets": "WEBPACK_ENV=development webpack -w",
"build:assets": "WEBPACK_ENV=production webpack",
"tunnel": "ngrok http 80"
"test": "mocha"
},
"repository": {
"type": "git",
......@@ -21,11 +21,13 @@
"@babel/node": "^7.8.7",
"@babel/polyfill": "^7.10.1",
"@babel/preset-env": "^7.9.6",
"JSON": "^1.0.0",
"autoprefixer": "^9.8.0",
"aws-sdk": "^2.702.0",
"axios": "^0.19.2",
"babel-loader": "^8.1.0",
"body-parser": "^1.19.0",
"chai": "^4.2.0",
"connect-mongo": "^3.2.0",
"cookie-parser": "^1.4.5",
"css-loader": "^3.5.3",
......@@ -37,6 +39,7 @@
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"get-blob-duration": "^1.1.1",
"helmet": "^3.22.0",
"lru-cache": "^6.0.0",
"mongoose": "^5.9.15",
"morgan": "^1.10.0",
"multer": "^1.4.2",
......@@ -52,6 +55,7 @@
"perf_hooks": "0.0.1",
"postcss-loader": "^3.0.0",
"pug": "^2.0.4",
"redis": "^3.0.2",
"sass-loader": "^8.0.2",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
......@@ -62,7 +66,10 @@
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.21.1",
"eslint-plugin-prettier": "^3.1.3",
"mocha": "^8.2.1",
"loadtest": "*",
"nodemon": "^2.0.4",
"prettier": "^2.0.5"
"prettier": "^2.0.5",
"supertest": "^6.0.1"
}
}
......
time
24
4
6
6
3
3
3
3
3
3
2
2
3
2
3
2
2
2
2
11
7
5
3
2
2
2
2
3
2
2
2
2
2
2
2
6
3
2
13
39
3
2
2
2
2
2
3
2
1
3
/*
const { expect } = require('chai');
const LRU = require('lru-cache');
const MAX = 3;
const options = {
max: MAX,
maxAge: 1900,
length(n, key) { return 1},
};
describe('LRU Cache Test', () => {
before( () => {
lruCache = new LRU(options);
// 데이터들을 최대로 cache!
lruCache.set(1, 'SampleData1');
lruCache.set(2, 'SampleData2');
lruCache.set(3, 'SampleData3');
});
it('LRU algorithm Test', () => {
// Happy3을 key로 가지는 데이터를 가장 사용 안함
lruCache.keys().forEach( k => {
for(let i = 0; i <= MAX - k; i++) {
console.log("########", k, lruCache.get(k));
}
});
// 새로운 데이터 cache!
lruCache.set(4, 'SampleData4');
//LRU 알고리즘에 의해 key가 3인 데이터가 삭제되어야함
expect(lruCache.has(1)).to.be.equal(true);
expect(lruCache.has(2)).to.be.equal(true);
expect(lruCache.has(3)).to.be.equal(false);
expect(lruCache.has(4)).to.be.equal(true);
});
it('dump & load Test', () => {
//dump
let cacheEntriesArray = lruCache.dump();
lruCache.reset();
expect(lruCache.itemCount).to.be.equal(0);
//load
lruCache.load(cacheEntriesArray);
expect(lruCache.itemCount).to.be.equal(3);
});
it('Expire time Test', done => {
//maxAge 시간 후엔 데이터 모두 만료되어야함
setTimeout(() => {
cache.prune();
expect(lruCache.itemCount).to.be.equal(0);
done();
}, 1900);
});
});*/
\ No newline at end of file
......@@ -7,4 +7,5 @@ block content
label(for="file") File
input(type="file", id="file", name="file", required=true)
input(type="text", placeholder="Title", name="title", required=true)
input(type="text", placeholder="Description", name="description", required=true)
input(type="submit", value="Upload File")
\ No newline at end of file
......
time
37
11
6
13
4
9
9
11
3
3
3
9
12
9
5
3
2
3
8
4
2
2
5
4
2
3
3
3
3
3
6
2
2
3
2
2
7
3
2
3
3
2
5
8
6
3
3
2
2
6
time
18
5
3
3
4
2
3
3
2
3
2
2
2
2
3
2
2
2
3
2
2
2
2
2
2
2
3
4
2
3
2
2
3
2
3
2
2
2
1
2
2
1
2
2
2
3
2
3
3
3
time
146
11
5
5
8
9
79
11
2
154
27
10
9
10
53
8
9
4
8
50
5
10
10
9
9
16
3
3
31
29
4
3
3
5
3
3
3
2
12
49
3
4
3
4
60
3
3
3
4
70
time
24
4
6
6
3
3
3
3
3
3
2
2
3
2
3
2
2
2
2
11
7
5
3
2
2
2
2
3
2
2
2
2
2
2
2
6
3
2
13
39
3
2
2
2
2
2
3
2
1
3