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

View File

@ -27,6 +27,7 @@ import {
Name, Name,
Ref, Ref,
RefSet, RefSet,
RefSetCache,
} from "../../src/core/primitives.js"; } from "../../src/core/primitives.js";
import { StringStream } from "../../src/core/stream.js"; import { StringStream } from "../../src/core/stream.js";
import { XRefMock } from "./test_utils.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 () { describe("isEOF", function () {
it("handles non-EOF", function () { it("handles non-EOF", function () {
const nonEOF = "foo"; const nonEOF = "foo";