Merge pull request #12089 from timvandermeij/refsetcache

Convert `RefSetCache` to a proper class and to use a `Map` internally
This commit is contained in:
Tim van der Meij 2020-07-17 15:38:09 +02:00 committed by GitHub
commit c55122c828
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 32 deletions

View File

@ -239,46 +239,41 @@ class RefSet {
}
}
var RefSetCache = (function RefSetCacheClosure() {
// eslint-disable-next-line no-shadow
function RefSetCache() {
this.dict = Object.create(null);
class RefSetCache {
constructor() {
this._map = new Map();
}
RefSetCache.prototype = {
get size() {
return Object.keys(this.dict).length;
},
get size() {
return this._map.size;
}
get: function RefSetCache_get(ref) {
return this.dict[ref.toString()];
},
get(ref) {
return this._map.get(ref.toString());
}
has: function RefSetCache_has(ref) {
return ref.toString() in this.dict;
},
has(ref) {
return this._map.has(ref.toString());
}
put: function RefSetCache_put(ref, obj) {
this.dict[ref.toString()] = obj;
},
put(ref, obj) {
this._map.set(ref.toString(), obj);
}
putAlias: function RefSetCache_putAlias(ref, aliasRef) {
this.dict[ref.toString()] = this.get(aliasRef);
},
putAlias(ref, aliasRef) {
this._map.set(ref.toString(), this.get(aliasRef));
}
forEach: function RefSetCache_forEach(callback) {
for (const i in this.dict) {
callback(this.dict[i]);
}
},
forEach(callback) {
for (const value of this._map.values()) {
callback(value);
}
}
clear: function RefSetCache_clear() {
this.dict = Object.create(null);
},
};
return RefSetCache;
})();
clear() {
this._map.clear();
}
}
function isEOF(v) {
return v === EOF;

View File

@ -27,6 +27,7 @@ import {
Name,
Ref,
RefSet,
RefSetCache,
} from "../../src/core/primitives.js";
import { StringStream } from "../../src/core/stream.js";
import { XRefMock } from "./test_utils.js";
@ -336,6 +337,64 @@ describe("primitives", function () {
});
});
describe("RefSetCache", function () {
const ref1 = Ref.get(4, 2);
const ref2 = Ref.get(5, 2);
const obj1 = Name.get("foo");
const obj2 = Name.get("bar");
let cache;
beforeEach(function (done) {
cache = new RefSetCache();
done();
});
afterEach(function () {
cache = null;
});
it("should put, have and get a value", function () {
cache.put(ref1, obj1);
expect(cache.has(ref1)).toBeTruthy();
expect(cache.has(ref2)).toBeFalsy();
expect(cache.get(ref1)).toBe(obj1);
});
it("should put, have and get a value by alias", function () {
cache.put(ref1, obj1);
cache.putAlias(ref2, ref1);
expect(cache.has(ref1)).toBeTruthy();
expect(cache.has(ref2)).toBeTruthy();
expect(cache.get(ref1)).toBe(obj1);
expect(cache.get(ref2)).toBe(obj1);
});
it("should report the size of the cache", function () {
cache.put(ref1, obj1);
expect(cache.size).toEqual(1);
cache.put(ref2, obj2);
expect(cache.size).toEqual(2);
});
it("should clear the cache", function () {
cache.put(ref1, obj1);
expect(cache.size).toEqual(1);
cache.clear();
expect(cache.size).toEqual(0);
});
it("should support iteration", function () {
cache.put(ref1, obj1);
cache.put(ref2, obj2);
const values = [];
cache.forEach(function (value) {
values.push(value);
});
expect(values).toEqual([obj1, obj2]);
});
});
describe("isEOF", function () {
it("handles non-EOF", function () {
const nonEOF = "foo";