# All files / lib/util pool.js

100% Statements 97/97
100% Branches 13/13
100% Functions 5/5
100% Lines 97/97

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    982x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    17501x
    17501x
    17501x
    17501x
    17501x
    17501x
    17501x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    5x
    5x
    17500x
    17500x
    5x
    5x
    5x
    2x
    2x
    15000x
    7500x
    7500x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    8629x
    8629x
    8629x
    8629x
    8629x
    8629x
    8629x
    1x
    1x
    8629x
    8629x
    8629x
    8629x
    2x
    2x
    2x
    2x
    2x
    2x
    1605x
    1605x
    2x
    2x
    2x
    2x
    2x
    2x
    1161x
    696x
    696x
    696x
    696x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
     import { EMPTY, NODE_TYPE, VTree } from './types';
    import getConfig from './config';

    const size = /** @type {Number} */ (getConfig('initialPoolSize', 5000));
    const free = new Set();
    const allocate = new Set();
    const protect = new Set();

    const shape = () => ({
      rawNodeName: EMPTY.STR,
      nodeName: EMPTY.STR,
      nodeValue: EMPTY.STR,
      nodeType: NODE_TYPE.ELEMENT,
      key: EMPTY.STR,
      childNodes: [],
      attributes: {},
    });

    // Creates a pool to query new or reused values from.
    const memory = { free, allocated: allocate, protected: protect };

    // Cache the values object, we'll refer to this iterator which is faster
    // than calling it every single time. It gets replaced once exhausted.
    let freeValues = free.values();

    // A pool contains Virtual Tree objects which are a deterministic, pre-created
    // shape that is used internally by diffHTML. Since diffHTML constantly creates
    // and recycles objects, this helps avoid unwanted and unexpected garbage
    // collection and improves performance.
    const Pool = {
      size,
      memory,

      /**
       * As the Pool size is configurable, this method can be used to fill up the
       * pool after making it larger.
       */
      fill() {
        // Increase the pool size.
        for (let i = free.size; i < this.size; i++) {
          free.add(shape());
        }

        // Decrease the pool size.
        if (this.size < free.size) {
          // Loop the set until pruning has completed.
          free.forEach(value => {
            if (free.size !== this.size) {
              free.delete(value);
            }
          });
        }
      },

      /**
       * @return {VTree}
       */
      get() {
        // This will create a new VTree and add to the pool if
        // we do not get one from the freeValues.
        const { value = shape(), done } = freeValues.next();

        // This extra bit of work allows us to avoid calling `free.values()` every
        // single time an object is needed.
        if (done) {
          freeValues = free.values();
        }

        free.delete(value);
        allocate.add(value);
        return value;
      },

      /**
       * @param {VTree} vTree - Virtual Tree to protect
       */
      protect(vTree) {
        allocate.delete(vTree);
        protect.add(vTree);
      },

      /**
       * @param {VTree} vTree - Virtual Tree to unprotect and deallocate
       */
      unprotect(vTree) {
        if (protect.has(vTree) || allocate.has(vTree)) {
          protect.delete(vTree);
          allocate.delete(vTree);
          free.add(vTree);
        }
      },
    };

    // Fill the pool.
    Pool.fill();

    export default Pool;