"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.TypedArrayManager = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var TypedArrayManager = function () {
  function TypedArrayManager() {
    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    (0, _classCallCheck2.default)(this, TypedArrayManager);
    this._pool = [];
    this.opts = {
      overAlloc: 2,
      poolSize: 100
    };
    this.setOptions(options);
  }

  var _proto = TypedArrayManager.prototype;

  _proto.setOptions = function setOptions(options) {
    Object.assign(this.opts, options);
  };

  _proto.allocate = function allocate(typedArray, count, _ref) {
    var _ref$size = _ref.size,
        size = _ref$size === void 0 ? 1 : _ref$size,
        type = _ref.type,
        _ref$padding = _ref.padding,
        padding = _ref$padding === void 0 ? 0 : _ref$padding,
        _ref$copy = _ref.copy,
        copy = _ref$copy === void 0 ? false : _ref$copy,
        _ref$initialize = _ref.initialize,
        initialize = _ref$initialize === void 0 ? false : _ref$initialize,
        maxCount = _ref.maxCount;
    var Type = type || typedArray && typedArray.constructor || Float32Array;
    var newSize = count * size + padding;

    if (ArrayBuffer.isView(typedArray)) {
      if (newSize <= typedArray.length) {
        return typedArray;
      }

      if (newSize * typedArray.BYTES_PER_ELEMENT <= typedArray.buffer.byteLength) {
        return new Type(typedArray.buffer, 0, newSize);
      }
    }

    var maxSize = Infinity;

    if (maxCount) {
      maxSize = maxCount * size + padding;
    }

    var newArray = this._allocate(Type, newSize, initialize, maxSize);

    if (typedArray && copy) {
      newArray.set(typedArray);
    } else if (!initialize) {
      newArray.fill(0, 0, 4);
    }

    this._release(typedArray);

    return newArray;
  };

  _proto.release = function release(typedArray) {
    this._release(typedArray);
  };

  _proto._allocate = function _allocate(Type, size, initialize, maxSize) {
    var sizeToAllocate = Math.max(Math.ceil(size * this.opts.overAlloc), 1);

    if (sizeToAllocate > maxSize) {
      sizeToAllocate = maxSize;
    }

    var pool = this._pool;
    var byteLength = Type.BYTES_PER_ELEMENT * sizeToAllocate;
    var i = pool.findIndex(function (b) {
      return b.byteLength >= byteLength;
    });

    if (i >= 0) {
      var array = new Type(pool.splice(i, 1)[0], 0, sizeToAllocate);

      if (initialize) {
        array.fill(0);
      }

      return array;
    }

    return new Type(sizeToAllocate);
  };

  _proto._release = function _release(typedArray) {
    if (!ArrayBuffer.isView(typedArray)) {
      return;
    }

    var pool = this._pool;
    var buffer = typedArray.buffer;
    var byteLength = buffer.byteLength;
    var i = pool.findIndex(function (b) {
      return b.byteLength >= byteLength;
    });

    if (i < 0) {
      pool.push(buffer);
    } else if (i > 0 || pool.length < this.opts.poolSize) {
      pool.splice(i, 0, buffer);
    }

    if (pool.length > this.opts.poolSize) {
      pool.shift();
    }
  };

  return TypedArrayManager;
}();

exports.TypedArrayManager = TypedArrayManager;

var _default = new TypedArrayManager();

exports.default = _default;
//# sourceMappingURL=typed-array-manager.js.map