<commit_before>// History -- adds objects that can store things and you can retrieve stuff
//            from them, blocking as needed until the objects are available.

function History(emptyCbTimeout) {
  this.emptyCbTimeout = emptyCbTimeout;
  this.futures = {}; // maps time => [{timer: timeout timer,
  //                                   cb: function(list_of_evesns){}}
  //                                 ]
  // if the callback times out, cb will be given an empty list.
  this.history = [];
}

History.prototype.time = function() {
  return this.history.length;
};

History.prototype.add = function(obj) {
  var now = this.time();
  if (now in this.futures) {
    // If people are waiting for us, then give them stuff.
    this.futures[now].forEach(function(cb) {
      if (cb.cb) { // if it didn't time out
        clearTimeout(cb.timer);
        cb.cb([obj]);
      } else {
      }
    });
    delete this.futures[now];
  }
  this.history.push(obj);
};

History.prototype.after = function(time, cb) {
  // Run the callback with all the actions that happened after the given time.
  // Block to wait for them if necessary.

  if (time < this.time()) {
    // Aha! We can already fufill their request.
    cb(this.history.slice(time));
  } else {
    // UH OH we don't have anything yet. Best post it on our pegboard for
    // later then.
    var cbData = {
        cb: cb,
        timer: setTimeout(function(){
            // this gets run on timeout
            cb([]);<commit_msg>quick fix for memory leaks hopefully<commit_after>// History -- adds objects that can store things and you can retrieve stuff
//            from them, blocking as needed until the objects are available.

function History(emptyCbTimeout) {
  this.emptyCbTimeout = emptyCbTimeout;
  this.futures = {}; // maps time => [{timer: timeout timer,
  //                                   cb: function(list_of_evesns){}}
  //                                 ]
  // if the callback times out, cb will be given an empty list.
  this.history = [];
  this.erasedHistory = 0;
}

History.prototype.time = function() {
  return this.history.length+this.erasedHistory;
};

History.prototype.add = function(obj) {
  var now = this.time(),
      self = this;
  if (now in this.futures) {
    // If people are waiting for us, then give them stuff.
    this.futures[now].forEach(function(cb) {
      if (cb.cb) { // if it didn't time out
        clearTimeout(cb.timer);
        cb.cb([obj]);
      } else {
      }
    });
    delete this.futures[now];
  }

  // timeout (TODO: needs test)
  this.history.push(obj);
  setTimeout(function(){
      self.history.shift();
      self.erasedHistory++;
    }, this.emptyCbTimeout);
};

History.prototype.after = function(time, cb) {
  // Run the callback with all the actions that happened after the given time.
  // Block to wait for them if necessary.

  if (time < this.time()) {
    // Aha! We can already fufill their request.
    cb(this.history.slice(time-this.erasedHistory));
  } else {
    // UH OH we don't have anything yet. Best post it on our pegboard for
    // later then.
    var cbData = {
        cb: cb,
        timer: setTimeout(function(){
            // this gets run on timeout
            cb([]);
{'fraction_non_alphanumeric': 0.12109978375038616, 'fraction_numerical': 0.00030892801977139327, 'mean_word_length': 2.1901477832512315, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4180408', 'n_tokens_mistral': 962, 'n_tokens_neox': 951, 'n_words': 312}