Browse Source

Add cache for queries with ID

master
Menci 6 years ago
parent
commit
56c4c4447b
  1. 2
      models/article.ts
  2. 65
      models/common.ts
  3. 2
      models/contest.ts
  4. 2
      models/problem.ts
  5. 2
      models/problem_tag.ts
  6. 2
      models/user.ts
  7. 2
      package.json
  8. 17
      yarn.lock

2
models/article.ts

@ -9,6 +9,8 @@ declare var syzoj: any;
@TypeORM.Entity() @TypeORM.Entity()
export default class Article extends Model { export default class Article extends Model {
static cache = true;
@TypeORM.PrimaryGeneratedColumn() @TypeORM.PrimaryGeneratedColumn()
id: number; id: number;

65
models/common.ts

@ -1,4 +1,6 @@
import * as TypeORM from "typeorm"; import * as TypeORM from "typeorm";
import * as LRUCache from "lru-cache";
import * as ObjectAssignDeep from "object-assign-deep";
interface Paginater { interface Paginater {
pageCnt: number; pageCnt: number;
@ -6,13 +8,74 @@ interface Paginater {
currPage: number; currPage: number;
} }
const caches: Map<string, LRUCache<number, Model>> = new Map();
function ensureCache(modelName) {
if (!caches.has(modelName)) {
caches.set(modelName, new LRUCache({
max: 500
}));
}
return caches.get(modelName);
}
function cacheGet(modelName, id) {
return ensureCache(modelName).get(parseInt(id));
}
function cacheSet(modelName, id, data) {
if (data == null) {
ensureCache(modelName).del(id);
} else {
ensureCache(modelName).set(parseInt(id), data);
}
}
export default class Model extends TypeORM.BaseEntity { export default class Model extends TypeORM.BaseEntity {
static cache = false;
static async findById<T extends TypeORM.BaseEntity>(this: TypeORM.ObjectType<T>, id?: number): Promise<T | undefined> { static async findById<T extends TypeORM.BaseEntity>(this: TypeORM.ObjectType<T>, id?: number): Promise<T | undefined> {
return await (this as any).findOne(parseInt(id as any) || 0); const doQuery = async () => await (this as any).findOne(parseInt(id as any) || 0);
if ((this as typeof Model).cache) {
let result;
if (result = cacheGet(this.name, id)) {
// Got cached result.
// Return a copy of it to avoid issue of adding or assigning properties.
const object = {};
Object.keys(result).forEach(key => {
object[key] = result[key] && typeof result[key] === 'object'
? ObjectAssignDeep({}, result[key])
: result[key];
});
return (this as typeof Model).create<T>(object);
}
result = await doQuery();
if (result) {
cacheSet(this.name, id, result);
}
return result;
} else {
return await doQuery();
}
} }
async destroy() { async destroy() {
const id = (this as any).id;
await TypeORM.getManager().remove(this); await TypeORM.getManager().remove(this);
if ((this.constructor as typeof Model).cache) {
cacheSet(this.constructor.name, id, null);
}
}
async save(): Promise<this> {
await super.save();
if ((this.constructor as typeof Model).cache) {
cacheSet(this.constructor.name, (this as any).id, this);
}
return this;
} }
static async countQuery<T extends TypeORM.BaseEntity>(this: TypeORM.ObjectType<T>, query: TypeORM.SelectQueryBuilder<T> | string) { static async countQuery<T extends TypeORM.BaseEntity>(this: TypeORM.ObjectType<T>, query: TypeORM.SelectQueryBuilder<T> | string) {

2
models/contest.ts

@ -16,6 +16,8 @@ enum ContestType {
@TypeORM.Entity() @TypeORM.Entity()
export default class Contest extends Model { export default class Contest extends Model {
static cache = true;
@TypeORM.PrimaryGeneratedColumn() @TypeORM.PrimaryGeneratedColumn()
id: number; id: number;

2
models/problem.ts

@ -200,6 +200,8 @@ enum ProblemType {
@TypeORM.Entity() @TypeORM.Entity()
export default class Problem extends Model { export default class Problem extends Model {
static cache = true;
@TypeORM.PrimaryGeneratedColumn() @TypeORM.PrimaryGeneratedColumn()
id: number; id: number;

2
models/problem_tag.ts

@ -3,6 +3,8 @@ import Model from "./common";
@TypeORM.Entity() @TypeORM.Entity()
export default class ProblemTag extends Model { export default class ProblemTag extends Model {
static cache = true;
@TypeORM.PrimaryGeneratedColumn() @TypeORM.PrimaryGeneratedColumn()
id: number; id: number;

2
models/user.ts

@ -9,6 +9,8 @@ import Article from "./article";
@TypeORM.Entity() @TypeORM.Entity()
export default class User extends Model { export default class User extends Model {
static cache = true;
@TypeORM.PrimaryGeneratedColumn() @TypeORM.PrimaryGeneratedColumn()
id: number; id: number;

2
package.json

@ -25,6 +25,7 @@
"homepage": "https://github.com/syzoj/syzoj#readme", "homepage": "https://github.com/syzoj/syzoj#readme",
"dependencies": { "dependencies": {
"@types/fs-extra": "^5.0.5", "@types/fs-extra": "^5.0.5",
"@types/lru-cache": "^5.1.0",
"ansi-to-html": "^0.6.10", "ansi-to-html": "^0.6.10",
"async-lock": "^1.2.0", "async-lock": "^1.2.0",
"bluebird": "^3.5.4", "bluebird": "^3.5.4",
@ -45,6 +46,7 @@
"jsdom": "^14.0.0", "jsdom": "^14.0.0",
"jsondiffpatch": "0.2.5", "jsondiffpatch": "0.2.5",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"lru-cache": "^5.1.1",
"mariadb": "^2.0.3", "mariadb": "^2.0.3",
"moment": "^2.24.0", "moment": "^2.24.0",
"msgpack-lite": "^0.1.26", "msgpack-lite": "^0.1.26",

17
yarn.lock

@ -14,6 +14,11 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/lru-cache@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03"
integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==
"@types/node@*": "@types/node@*":
version "11.11.4" version "11.11.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.4.tgz#8808bd5a82bbf6f5d412eff1c228d178e7c24bb3" resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.4.tgz#8808bd5a82bbf6f5d412eff1c228d178e7c24bb3"
@ -2135,6 +2140,13 @@ lru-cache@^4.0.1, lru-cache@^4.1.3:
pseudomap "^1.0.2" pseudomap "^1.0.2"
yallist "^2.1.2" yallist "^2.1.2"
lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
dependencies:
yallist "^3.0.2"
mailcomposer@^3.12.0: mailcomposer@^3.12.0:
version "3.12.0" version "3.12.0"
resolved "https://registry.yarnpkg.com/mailcomposer/-/mailcomposer-3.12.0.tgz#9c5e1188aa8e1c62ec8b86bd43468102b639e8f9" resolved "https://registry.yarnpkg.com/mailcomposer/-/mailcomposer-3.12.0.tgz#9c5e1188aa8e1c62ec8b86bd43468102b639e8f9"
@ -3842,6 +3854,11 @@ yallist@^2.1.2:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
yallist@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
yargonaut@^1.1.2: yargonaut@^1.1.2:
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.4.tgz#c64f56432c7465271221f53f5cc517890c3d6e0c" resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.4.tgz#c64f56432c7465271221f53f5cc517890c3d6e0c"

Loading…
Cancel
Save