// Path: siden-core/src/main/java/ninja/siden/util/ExceptionalConsumer.java
// @FunctionalInterface
// public interface ExceptionalConsumer<T, EX extends Exception> {
// 
// 	void accept(T t) throws EX;
// }
// 
// Path: siden-core/src/main/java/ninja/siden/util/ExceptionalFunction.java
// @FunctionalInterface
// public interface ExceptionalFunction<T, R, EX extends Exception> {
// 
// 	R apply(T t) throws EX;
// }
// 
// Path: siden-core/src/main/java/ninja/siden/util/LongAccumulators.java
// public interface LongAccumulators {
// 
// 	static LongAccumulator max() {
// 		return new LongAccumulator((x, y) -> x < y ? y : x, 0);
// 	}
// 
// 	static LongAccumulator min() {
// 		return new LongAccumulator(
// 				(x, y) -> y < x || (x < 0 && -1 < y) ? y : x, -1);
// 	}
// }


import java.util.Date;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
import ninja.siden.util.ExceptionalConsumer;
import ninja.siden.util.ExceptionalFunction;
import ninja.siden.util.LongAccumulators;
/*
 * Copyright 2015 SATO taichi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ninja.siden.jmx;



/**
 * @author taichi
 */
public class RequestMeter {

	static final AtomicLongFieldUpdater<RequestMeter> startTimeUpdater = AtomicLongFieldUpdater
			.newUpdater(RequestMeter.class, "startTime");

	volatile long startTime;
	LongAdder totalRequestTime;
	LongAccumulator maxRequestTime;
	LongAccumulator minRequestTime;
	LongAdder totalRequests;

	public RequestMeter() {
		this.startTime = System.currentTimeMillis();
		this.totalRequestTime = new LongAdder();
		this.maxRequestTime = LongAccumulators.max();
		this.minRequestTime = LongAccumulators.min();
		this.totalRequests = new LongAdder();
	}

	protected void accept(final long requestTime) {
		this.totalRequestTime.add(requestTime);
		this.maxRequestTime.accumulate(requestTime);
		this.minRequestTime.accumulate(requestTime);
		this.totalRequests.increment();
	}

	public <EX extends Exception> void accept(
// Path: siden-core/src/main/java/ninja/siden/util/ExceptionalConsumer.java
// @FunctionalInterface
// public interface ExceptionalConsumer<T, EX extends Exception> {
// 
// 	void accept(T t) throws EX;
// }
// 
// Path: siden-core/src/main/java/ninja/siden/util/ExceptionalFunction.java
// @FunctionalInterface
// public interface ExceptionalFunction<T, R, EX extends Exception> {
// 
// 	R apply(T t) throws EX;
// }
// 
// Path: siden-core/src/main/java/ninja/siden/util/LongAccumulators.java
// public interface LongAccumulators {
// 
// 	static LongAccumulator max() {
// 		return new LongAccumulator((x, y) -> x < y ? y : x, 0);
// 	}
// 
// 	static LongAccumulator min() {
// 		return new LongAccumulator(
// 				(x, y) -> y < x || (x < 0 && -1 < y) ? y : x, -1);
// 	}
// }


// Path: siden-core/src/main/java/ninja/siden/jmx/RequestMeter.java
import java.util.Date;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
import ninja.siden.util.ExceptionalConsumer;
import ninja.siden.util.ExceptionalFunction;
import ninja.siden.util.LongAccumulators;

/*
 * Copyright 2015 SATO taichi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ninja.siden.jmx;



/**
 * @author taichi
 */
public class RequestMeter {

	static final AtomicLongFieldUpdater<RequestMeter> startTimeUpdater = AtomicLongFieldUpdater
			.newUpdater(RequestMeter.class, "startTime");

	volatile long startTime;
	LongAdder totalRequestTime;
	LongAccumulator maxRequestTime;
	LongAccumulator minRequestTime;
	LongAdder totalRequests;

	public RequestMeter() {
		this.startTime = System.currentTimeMillis();
		this.totalRequestTime = new LongAdder();
		this.maxRequestTime = LongAccumulators.max();
		this.minRequestTime = LongAccumulators.min();
		this.totalRequests = new LongAdder();
	}

	protected void accept(final long requestTime) {
		this.totalRequestTime.add(requestTime);
		this.maxRequestTime.accumulate(requestTime);
		this.minRequestTime.accumulate(requestTime);
		this.totalRequests.increment();
	}

	public <EX extends Exception> void accept(
			ExceptionalConsumer<RequestMeter, EX> fn) throws EX {