// Path: src/main/java/io/openio/sds/common/Check.java
// public static void checkArgument(boolean condition, String msg) {
//     if (!condition)
//         throw new IllegalArgumentException(msg);
// }
// 
// Path: src/main/java/io/openio/sds/common/DeadlineManager.java
// public class DeadlineManager {
// 
//     public interface ClockSource {
//         /**
//          *
//          * @return the current time in milliseconds
//          */
//         int now();
//     }
// 
//     private class SystemClockSource implements ClockSource {
// 
//         public SystemClockSource() {
//         }
// 
//         @Override
//         public int now() {
//             return (int) (System.nanoTime() / 1000000);
//         }
//     }
// 
// 
//     private static volatile DeadlineManager instance = null;
// 
//     private ClockSource clock;
// 
//     private DeadlineManager() {
//         useSystemClockSource();
//     }
// 
//     /**
//      * Get the single instance of {@link DeadlineManager}.
//      * @return the single instance of {@link DeadlineManager}
//      */
//     public static DeadlineManager instance() {
//         if (instance == null) {
//             synchronized (DeadlineManager.class) {
//                 if (instance == null) {
//                     instance = new DeadlineManager();
//                 }
//             }
//         }
//         return instance;
//     }
// 
//     /**
//      * Force the DeadlineManager to use a mocked {@link ClockSource}
//      * @param clockSource The new clock source to use
//      */
//     public void useMockedClockSource(ClockSource clockSource) {
//         this.clock = clockSource;
//     }
// 
//     /**
//      * Force the DeadlineManager to use the system monotonic clock source.
//      */
//     public void useSystemClockSource() {
//         this.clock = this.new SystemClockSource();
//     }
// 
//     /**
//      * Raise an exception when a deadline has been reached.
//      * 
//      * @param deadline the deadline, in milliseconds
//      * @throws DeadlineReachedException when the deadline has been reached
//      */
//     public void checkDeadline(int deadline) throws DeadlineReachedException {
//         checkDeadline(deadline, now());
//     }
// 
//     /**
//      * Raise an exception when a deadline has been reached.
//      * 
//      * @param deadline the deadline, in milliseconds
//      * @param refTime the reference time for the deadline, in milliseconds
//      * @throws DeadlineReachedException when the deadline has been reached
//      */
//     public void checkDeadline(int deadline, int refTime) throws DeadlineReachedException {
//         int diff = deadline - refTime;
//         if (diff <= 0) {
//             throw new DeadlineReachedException(-diff);
//         }
//     }
// 
//     /**
//      * Convert a deadline to a timeout.
//      *
//      * @param deadline the deadline to convert, in milliseconds
//      * @return a timeout in milliseconds
//      */
//     public int deadlineToTimeout(int deadline) {
//         return deadline - now();
//     }
// 
//     /**
//      * Convert a deadline to a timeout.
//      *
//      * @param deadline the deadline to convert, in milliseconds
//      * @param refTime the reference time for the deadline, in monotonic milliseconds
//      * @return a timeout in milliseconds
//      */
//     public int deadlineToTimeout(int deadline, int refTime) {
//         return deadline - refTime;
//     }
// 
//     /**
//      * Get the current monotonic time in milliseconds.
//      *
//      * @return The current monotonic time in milliseconds
//      */
//     public int now() {
//         return clock.now();
//     }
// 
//     /**
//      * Convert a timeout to a deadline.
//      *
//      * @param timeout the timeout in milliseconds
//      * @return a deadline in monotonic milliseconds
//      */
//     public int timeoutToDeadline(int timeout) {
//         return timeoutToDeadline(timeout, now());
//     }
// 
//     /**
//      * Convert a timeout to a deadline.
//      *
//      * @param timeout the timeout in milliseconds
//      * @param refTime the reference time for the deadline, in milliseconds
//      * @return a deadline in monotonic milliseconds
//      */
//     public int timeoutToDeadline(int timeout, int refTime) {
//         return refTime + timeout;
//     }
// }
// 
// Path: src/main/java/io/openio/sds/common/IdGen.java
// public class IdGen {
// 
//     private static final int REQ_ID_LENGTH = 16;
//     
//     private static Random rand = new Random();
//     
//     /**
//      * Generates a new random request id
//      * @return the generated id
//      */
//     public static String requestId() {
//         return toHex(bytes(REQ_ID_LENGTH));
//     }
//     
//     private static byte[] bytes(int size){
//         byte[] b = new byte[size];
//         rand.nextBytes(b);
//         return b;
//     }
// }


import static io.openio.sds.common.Check.checkArgument;
import io.openio.sds.common.DeadlineManager;
import io.openio.sds.common.IdGen;
package io.openio.sds;


/**
 * Generic parameters and context for all OpenIO SDS requests,
 * including a request ID, a timeout (or deadline), etc.
 *
 * @author Florent Vennetier
 *
 */
public class RequestContext {

    private DeadlineManager dm;

    private String reqId = null;
    private int reqStart = -1;
    private int rawTimeout = -1;
    private int deadline = -1;

    /**
     * Build a new {@link RequestContext} with a default 30s timeout.
     */
    public RequestContext() {
        this.dm = DeadlineManager.instance();
    }

    /**
     * Copy constructor. Build a new {@link RequestContext} from another one.
     * This will keep the request ID, the timeout and the deadline (if there is one).
     *
     * @param src The {@link RequestContext} to copy.
     */
    public RequestContext(RequestContext src) {
        this.withRequestId(src.requestId());
        this.deadline = src.deadline;
        this.rawTimeout = src.rawTimeout;
    }

    /* -- Request IDs ----------------------------------------------------- */

    /**
     * Ensure this request has an ID and it is at least 8 characters.
     *
     * @return this
     */
    public RequestContext ensureRequestId() {
        if (this.reqId == null)
// Path: src/main/java/io/openio/sds/common/Check.java
// public static void checkArgument(boolean condition, String msg) {
//     if (!condition)
//         throw new IllegalArgumentException(msg);
// }
// 
// Path: src/main/java/io/openio/sds/common/DeadlineManager.java
// public class DeadlineManager {
// 
//     public interface ClockSource {
//         /**
//          *
//          * @return the current time in milliseconds
//          */
//         int now();
//     }
// 
//     private class SystemClockSource implements ClockSource {
// 
//         public SystemClockSource() {
//         }
// 
//         @Override
//         public int now() {
//             return (int) (System.nanoTime() / 1000000);
//         }
//     }
// 
// 
//     private static volatile DeadlineManager instance = null;
// 
//     private ClockSource clock;
// 
//     private DeadlineManager() {
//         useSystemClockSource();
//     }
// 
//     /**
//      * Get the single instance of {@link DeadlineManager}.
//      * @return the single instance of {@link DeadlineManager}
//      */
//     public static DeadlineManager instance() {
//         if (instance == null) {
//             synchronized (DeadlineManager.class) {
//                 if (instance == null) {
//                     instance = new DeadlineManager();
//                 }
//             }
//         }
//         return instance;
//     }
// 
//     /**
//      * Force the DeadlineManager to use a mocked {@link ClockSource}
//      * @param clockSource The new clock source to use
//      */
//     public void useMockedClockSource(ClockSource clockSource) {
//         this.clock = clockSource;
//     }
// 
//     /**
//      * Force the DeadlineManager to use the system monotonic clock source.
//      */
//     public void useSystemClockSource() {
//         this.clock = this.new SystemClockSource();
//     }
// 
//     /**
//      * Raise an exception when a deadline has been reached.
//      * 
//      * @param deadline the deadline, in milliseconds
//      * @throws DeadlineReachedException when the deadline has been reached
//      */
//     public void checkDeadline(int deadline) throws DeadlineReachedException {
//         checkDeadline(deadline, now());
//     }
// 
//     /**
//      * Raise an exception when a deadline has been reached.
//      * 
//      * @param deadline the deadline, in milliseconds
//      * @param refTime the reference time for the deadline, in milliseconds
//      * @throws DeadlineReachedException when the deadline has been reached
//      */
//     public void checkDeadline(int deadline, int refTime) throws DeadlineReachedException {
//         int diff = deadline - refTime;
//         if (diff <= 0) {
//             throw new DeadlineReachedException(-diff);
//         }
//     }
// 
//     /**
//      * Convert a deadline to a timeout.
//      *
//      * @param deadline the deadline to convert, in milliseconds
//      * @return a timeout in milliseconds
//      */
//     public int deadlineToTimeout(int deadline) {
//         return deadline - now();
//     }
// 
//     /**
//      * Convert a deadline to a timeout.
//      *
//      * @param deadline the deadline to convert, in milliseconds
//      * @param refTime the reference time for the deadline, in monotonic milliseconds
//      * @return a timeout in milliseconds
//      */
//     public int deadlineToTimeout(int deadline, int refTime) {
//         return deadline - refTime;
//     }
// 
//     /**
//      * Get the current monotonic time in milliseconds.
//      *
//      * @return The current monotonic time in milliseconds
//      */
//     public int now() {
//         return clock.now();
//     }
// 
//     /**
//      * Convert a timeout to a deadline.
//      *
//      * @param timeout the timeout in milliseconds
//      * @return a deadline in monotonic milliseconds
//      */
//     public int timeoutToDeadline(int timeout) {
//         return timeoutToDeadline(timeout, now());
//     }
// 
//     /**
//      * Convert a timeout to a deadline.
//      *
//      * @param timeout the timeout in milliseconds
//      * @param refTime the reference time for the deadline, in milliseconds
//      * @return a deadline in monotonic milliseconds
//      */
//     public int timeoutToDeadline(int timeout, int refTime) {
//         return refTime + timeout;
//     }
// }
// 
// Path: src/main/java/io/openio/sds/common/IdGen.java
// public class IdGen {
// 
//     private static final int REQ_ID_LENGTH = 16;
//     
//     private static Random rand = new Random();
//     
//     /**
//      * Generates a new random request id
//      * @return the generated id
//      */
//     public static String requestId() {
//         return toHex(bytes(REQ_ID_LENGTH));
//     }
//     
//     private static byte[] bytes(int size){
//         byte[] b = new byte[size];
//         rand.nextBytes(b);
//         return b;
//     }
// }


// Path: src/main/java/io/openio/sds/RequestContext.java
import static io.openio.sds.common.Check.checkArgument;
import io.openio.sds.common.DeadlineManager;
import io.openio.sds.common.IdGen;

package io.openio.sds;


/**
 * Generic parameters and context for all OpenIO SDS requests,
 * including a request ID, a timeout (or deadline), etc.
 *
 * @author Florent Vennetier
 *
 */
public class RequestContext {

    private DeadlineManager dm;

    private String reqId = null;
    private int reqStart = -1;
    private int rawTimeout = -1;
    private int deadline = -1;

    /**
     * Build a new {@link RequestContext} with a default 30s timeout.
     */
    public RequestContext() {
        this.dm = DeadlineManager.instance();
    }

    /**
     * Copy constructor. Build a new {@link RequestContext} from another one.
     * This will keep the request ID, the timeout and the deadline (if there is one).
     *
     * @param src The {@link RequestContext} to copy.
     */
    public RequestContext(RequestContext src) {
        this.withRequestId(src.requestId());
        this.deadline = src.deadline;
        this.rawTimeout = src.rawTimeout;
    }

    /* -- Request IDs ----------------------------------------------------- */

    /**
     * Ensure this request has an ID and it is at least 8 characters.
     *
     * @return this
     */
    public RequestContext ensureRequestId() {
        if (this.reqId == null)
            this.reqId = IdGen.requestId();