<commit_before>/**
 * Copyright (C) 2009 - 2010 by OpenGamma Inc.
 *
 * Please see distribution for license.
 */
package com.opengamma.util;

import java.util.Arrays;

/**
 * A counter that keeps track of how many times something has happened
 * in the recent past.
 * <p>
 * The implementation uses {@link System#currentTimeMillis()} so
 * the figures will only be approximate.
 * <p>
 * The implementation is thread-safe.   
 *
 * @author pietari
 */
public class PerformanceCounter {
  
  private final int _secondsOfHistoryToKeep;
  private long _hits;
  private final long[] _hitsHistory;
  private long _zeroTimestamp; 
  private long _lastHitTimestamp;
  
  public PerformanceCounter(int secondsOfHistoryToKeep) {
    this(secondsOfHistoryToKeep, System.currentTimeMillis());
  }
  
  PerformanceCounter(int secondsOfHistoryToKeep, long zeroTimestamp) {
    if (secondsOfHistoryToKeep <= 0) {
      throw new IllegalArgumentException("secondsOfHistoryToKeep must be positive");
    }
    if (zeroTimestamp < 0) {
      throw new IllegalArgumentException("zeroTimestamp must be non-negative");
    }
    
    _secondsOfHistoryToKeep = secondsOfHistoryToKeep;
    _hitsHistory = new long[_secondsOfHistoryToKeep];
    
    reset(zeroTimestamp);
  }
  
  public void reset() {
    long timestamp = System.currentTimeMillis();
    reset(timestamp);
  }
  
  synchronized void reset(long timestamp) {
    _hits = 0;
    Arrays.fill(_hitsHistory, 0);
    _zeroTimestamp = timestamp;
    _lastHitTimestamp = _zeroTimestamp;
  }
  
  public int getSecondsOfHistoryToKeep() {
    return _secondsOfHistoryToKeep;
  }
  
  private long getSecondsSinceInception(long timestamp) {
    if (timestamp < _zeroTimestamp) { // could happen if the system clock is played with 
      reset(timestamp);      
    }
    return (timestamp - _zeroTimestamp) / 1000;   
  }
  
  private long getEarliestAvailableTime() {
    long lastHitTimestampRoundedDownToSeconds = _lastHitTimestamp / 1000 * 1000;
    return lastHitTimestampRoundedDownToSeconds - 1000 * _secondsOfHistoryToKeep; 
  }
  
  private int getIndex(long timestamp) {
    if (timestamp < getEarliestAvailableTime()) {
      throw new IllegalArgumentException("Earliest available is " + getEarliestAvailableTime() + ", tried to request " + timestamp);
    }
    return (int) (getSecondsSinceInception(timestamp) % _secondsOfHistoryToKeep);   
  }
  
  synchronized void hit(long timestamp) {
    int lastIndex = getIndex(_lastHitTimestamp);
    int index = getIndex(timestamp);
    
    long secondsSinceLastHit = getSecondsSinceInception(timestamp) - getSecondsSinceInception(_lastHitTimestamp);
    
    if (secondsSinceLastHit >= _secondsOfHistoryToKeep) {
      Arrays.fill(_hitsHistory, _hits);
    } else {
      if (index > lastIndex) {
        Arrays.fill(_hitsHistory, lastIndex, index, _hits);
      } else if (index < lastIndex) {
        Arrays.fill(_hitsHistory, lastIndex, _hitsHistory.length, _hits);
        Arrays.fill(_hitsHistory, 0, index, _hits);
      }
    }
    
    _hits++;
    _lastHitTimestamp = timestamp;
  }
  
  public void hit() {
    long timestamp = System.currentTimeMillis();
    hit(timestamp);
  }
  <commit_msg>Better logic for situation where system clock is moved backwards<commit_after>/**
 * Copyright (C) 2009 - 2010 by OpenGamma Inc.
 *
 * Please see distribution for license.
 */
package com.opengamma.util;

import java.util.Arrays;

/**
 * A counter that keeps track of how many times something has happened
 * in the recent past.
 * <p>
 * The implementation uses {@link System#currentTimeMillis()} so
 * the figures will only be approximate.
 * <p>
 * The implementation is thread-safe.   
 *
 * @author pietari
 */
public class PerformanceCounter {
  
  private final int _secondsOfHistoryToKeep;
  private long _hits;
  private final long[] _hitsHistory;
  private long _zeroTimestamp; 
  private long _lastHitTimestamp;
  
  public PerformanceCounter(int secondsOfHistoryToKeep) {
    this(secondsOfHistoryToKeep, System.currentTimeMillis());
  }
  
  PerformanceCounter(int secondsOfHistoryToKeep, long zeroTimestamp) {
    if (secondsOfHistoryToKeep <= 0) {
      throw new IllegalArgumentException("secondsOfHistoryToKeep must be positive");
    }
    if (zeroTimestamp < 0) {
      throw new IllegalArgumentException("zeroTimestamp must be non-negative");
    }
    
    _secondsOfHistoryToKeep = secondsOfHistoryToKeep;
    _hitsHistory = new long[_secondsOfHistoryToKeep];
    
    reset(zeroTimestamp);
  }
  
  public void reset() {
    long timestamp = System.currentTimeMillis();
    reset(timestamp);
  }
  
  synchronized void reset(long timestamp) {
    _hits = 0;
    Arrays.fill(_hitsHistory, 0);
    _zeroTimestamp = timestamp;
    _lastHitTimestamp = _zeroTimestamp;
  }
  
  public int getSecondsOfHistoryToKeep() {
    return _secondsOfHistoryToKeep;
  }
  
  private long getSecondsSinceInception(long timestamp) {
    return (timestamp - _zeroTimestamp) / 1000;   
  }
  
  private long getEarliestAvailableTime() {
    long lastHitTimestampRoundedDownToSeconds = _lastHitTimestamp / 1000 * 1000;
    return lastHitTimestampRoundedDownToSeconds - 1000 * _secondsOfHistoryToKeep; 
  }
  
  private int getIndex(long timestamp) {
    if (timestamp < getEarliestAvailableTime()) {
      throw new IllegalArgumentException("Earliest available is " + getEarliestAvailableTime() + ", tried to request " + timestamp);
    }
    return (int) (getSecondsSinceInception(timestamp) % _secondsOfHistoryToKeep);   
  }
  
  synchronized void hit(long timestamp) {
    if (timestamp < _lastHitTimestamp) { // could happen if the system clock is played with 
      reset(timestamp);      
    }

    long secondsSinceLastHit = getSecondsSinceInception(timestamp) - getSecondsSinceInception(_lastHitTimestamp);
    if (secondsSinceLastHit < 0) {
      throw new RuntimeException("Seconds since last hit should never be negative" + secondsSinceLastHit);
    }
    
    if (secondsSinceLastHit >= _secondsOfHistoryToKeep) {
      Arrays.fill(_hitsHistory, _hits);
    } else {
      int lastIndex = getIndex(_lastHitTimestamp);
      int index = getIndex(timestamp);

      if (index > lastIndex) {
        Arrays.fill(_hitsHistory, lastIndex, index, _hits);
      } else if (index < lastIndex) {
        Arrays.fill(_hitsHistory, lastIndex, _hitsHistory.length, _hits);
        Arrays.fill(_hitsHistory, 0, index, _hits);
      }
    }
    
    _hits++;
    _lastHitTimestamp = timestamp;
  }
  
  public void hit() {
    long timestamp = System.currentTimeMillis();
    hit(timestamp);
  }
  
{'fraction_non_alphanumeric': 0.08685766257389722, 'fraction_numerical': 0.00894345914809762, 'mean_word_length': 3.5724185724185724, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3512596', 'n_tokens_mistral': 1942, 'n_tokens_neox': 1893, 'n_words': 489}