github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/vue-1.0.24/src/cache.js (about)

     1  /**
     2   * A doubly linked list-based Least Recently Used (LRU)
     3   * cache. Will keep most recently used items while
     4   * discarding least recently used items when its limit is
     5   * reached. This is a bare-bone version of
     6   * Rasmus Andersson's js-lru:
     7   *
     8   *   https://github.com/rsms/js-lru
     9   *
    10   * @param {Number} limit
    11   * @constructor
    12   */
    13  
    14  export default function Cache (limit) {
    15    this.size = 0
    16    this.limit = limit
    17    this.head = this.tail = undefined
    18    this._keymap = Object.create(null)
    19  }
    20  
    21  var p = Cache.prototype
    22  
    23  /**
    24   * Put <value> into the cache associated with <key>.
    25   * Returns the entry which was removed to make room for
    26   * the new entry. Otherwise undefined is returned.
    27   * (i.e. if there was enough room already).
    28   *
    29   * @param {String} key
    30   * @param {*} value
    31   * @return {Entry|undefined}
    32   */
    33  
    34  p.put = function (key, value) {
    35    var removed
    36    if (this.size === this.limit) {
    37      removed = this.shift()
    38    }
    39  
    40    var entry = this.get(key, true)
    41    if (!entry) {
    42      entry = {
    43        key: key
    44      }
    45      this._keymap[key] = entry
    46      if (this.tail) {
    47        this.tail.newer = entry
    48        entry.older = this.tail
    49      } else {
    50        this.head = entry
    51      }
    52      this.tail = entry
    53      this.size++
    54    }
    55    entry.value = value
    56  
    57    return removed
    58  }
    59  
    60  /**
    61   * Purge the least recently used (oldest) entry from the
    62   * cache. Returns the removed entry or undefined if the
    63   * cache was empty.
    64   */
    65  
    66  p.shift = function () {
    67    var entry = this.head
    68    if (entry) {
    69      this.head = this.head.newer
    70      this.head.older = undefined
    71      entry.newer = entry.older = undefined
    72      this._keymap[entry.key] = undefined
    73      this.size--
    74    }
    75    return entry
    76  }
    77  
    78  /**
    79   * Get and register recent use of <key>. Returns the value
    80   * associated with <key> or undefined if not in cache.
    81   *
    82   * @param {String} key
    83   * @param {Boolean} returnEntry
    84   * @return {Entry|*}
    85   */
    86  
    87  p.get = function (key, returnEntry) {
    88    var entry = this._keymap[key]
    89    if (entry === undefined) return
    90    if (entry === this.tail) {
    91      return returnEntry
    92        ? entry
    93        : entry.value
    94    }
    95    // HEAD--------------TAIL
    96    //   <.older   .newer>
    97    //  <--- add direction --
    98    //   A  B  C  <D>  E
    99    if (entry.newer) {
   100      if (entry === this.head) {
   101        this.head = entry.newer
   102      }
   103      entry.newer.older = entry.older // C <-- E.
   104    }
   105    if (entry.older) {
   106      entry.older.newer = entry.newer // C. --> E
   107    }
   108    entry.newer = undefined // D --x
   109    entry.older = this.tail // D. --> E
   110    if (this.tail) {
   111      this.tail.newer = entry // E. <-- D
   112    }
   113    this.tail = entry
   114    return returnEntry
   115      ? entry
   116      : entry.value
   117  }