Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Change listeners on LRU Set and Map

  • Loading branch information...
commit a0c0d15194f938da29b3c8d7b31f795e107cfd3c 1 parent 870211b
Kris Kowal authored

Showing 2 changed files with 78 additions and 12 deletions. Show diff stats Hide diff stats

  1. +33 10 lru-set.js
  2. +45 2 spec/lru-map-spec.js
43 lru-set.js
@@ -5,6 +5,7 @@ var Set = require("./set");
5 5 var GenericCollection = require("./generic-collection");
6 6 var GenericSet = require("./generic-set");
7 7 var PropertyChanges = require("./listen/property-changes");
  8 +var RangeChanges = require("./listen/range-changes");
8 9
9 10 module.exports = LruSet;
10 11
@@ -28,6 +29,7 @@ function LruSet(values, maxLength, equals, hash, getDefault) {
28 29 Object.addEach(LruSet.prototype, GenericCollection.prototype);
29 30 Object.addEach(LruSet.prototype, GenericSet.prototype);
30 31 Object.addEach(LruSet.prototype, PropertyChanges.prototype);
  32 +Object.addEach(LruSet.prototype, RangeChanges.prototype);
31 33
32 34 LruSet.prototype.constructClone = function (values) {
33 35 return new this.constructor(
@@ -55,27 +57,48 @@ LruSet.prototype.get = function (value) {
55 57 };
56 58
57 59 LruSet.prototype.add = function (value) {
58   - if (this.store.has(value)) {
  60 + var found = this.store.has(value);
  61 + // if the value already exists, we delete it and add it back again so it
  62 + // appears at the end of the list of values to truncate
  63 + var length = this.length;
  64 + if (found) {
59 65 this.store["delete"](value);
60   - this.length--;
  66 + length--;
  67 + }
  68 + // before change
  69 + if (!found && this.dispachesRangeChanges) {
  70 + this.dispatchBeforeRangeChange([value], [], 0);
61 71 }
62 72 this.store.add(value);
63   - this.length++;
  73 + length++;
  74 + // only assign to length once to avoid jitter on length observers
  75 + this.length = length;
  76 + // after change
  77 + if (!found && this.dispatchesRangeChanges) {
  78 + this.dispatchRangeChange([value], [], 0);
  79 + }
  80 + // truncate if necessary
64 81 if (this.store.length > this.maxLength) {
65 82 var eldest = this.store.order.head.next;
66   - this.store["delete"](eldest.value);
67   - this.length--;
68   - return false;
  83 + this["delete"](eldest.value);
  84 + return false; // did not grow
69 85 }
70   - return true;
  86 + return !found; // whether it grew
71 87 };
72 88
73 89 LruSet.prototype["delete"] = function (value) {
74   - if (this.store["delete"](value)) {
  90 + var found = this.store.has(value);
  91 + if (found) {
  92 + if (this.dispatchesRangeChanges) {
  93 + this.dispatchBeforeRangeChange([], [value], 0);
  94 + }
  95 + this.store["delete"](value);
75 96 this.length--;
76   - return true;
  97 + if (this.dispatchesRangeChanges) {
  98 + this.dispatcheRangeChange([], [value], 0);
  99 + }
77 100 }
78   - return false;
  101 + return found;
79 102 };
80 103
81 104 LruSet.prototype.one = function () {
47 spec/lru-map-spec.js
@@ -8,7 +8,7 @@ describe("LruMap", function () {
8 8 describeDict(LruMap);
9 9 describeMap(LruMap);
10 10
11   - it("should remote stale items", function () {
  11 + it("should remove stale items", function () {
12 12 var map = LruMap({a: 10, b: 20, c: 30}, 3);
13 13 map.get("b");
14 14 map.set("d", 40);
@@ -16,6 +16,49 @@ describe("LruMap", function () {
16 16 expect(map.length).toBe(3);
17 17 });
18 18
19   -});
  19 + it("should not grow when re-adding", function () {
  20 + var map = LruMap({a: 10, b: 20, c: 30}, 3);
  21 +
  22 + expect(map.keys()).toEqual(['a', 'b', 'c']);
  23 + expect(map.length).toBe(3);
  24 +
  25 + map.get("b");
  26 + expect(map.keys()).toEqual(['a', 'c', 'b']);
  27 + expect(map.length).toBe(3);
  28 +
  29 + map.set("c", 40);
  30 + expect(map.keys()).toEqual(['a', 'b', 'c']);
  31 + expect(map.length).toBe(3);
  32 + });
  33 +
  34 + it("should grow when adding new values", function () {
  35 + var map = LruMap({}, 3);
  36 + expect(map.length).toBe(0);
  37 +
  38 + map.set("a", 10);
  39 + expect(map.length).toBe(1);
  40 + map.set("a", 10);
  41 + expect(map.length).toBe(1);
  42 +
  43 + map.set("b", 20);
  44 + expect(map.length).toBe(2);
  45 + map.set("b", 20);
  46 + expect(map.length).toBe(2);
20 47
  48 + map.set("c", 30);
  49 + expect(map.length).toBe(3);
  50 + map.set("c", 30);
  51 + expect(map.length).toBe(3);
  52 +
  53 + // stops growing
  54 + map.set("d", 40);
  55 + expect(map.length).toBe(3);
  56 + map.set("d", 40);
  57 + expect(map.length).toBe(3);
  58 +
  59 + map.set("e", 50);
  60 + expect(map.length).toBe(3);
  61 + });
  62 +
  63 +});
21 64

0 comments on commit a0c0d15

Please sign in to comment.
Something went wrong with that request. Please try again.