/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

#ifndef _ACTIVEMQ_UTIL_MEMORYUSAGE_H_
#define _ACTIVEMQ_UTIL_MEMORYUSAGE_H_

#include <activemq/util/Config.h>
#include <decaf/util/concurrent/Mutex.h>

namespace activemq {
namespace util {

    class AMQCPP_API MemoryUsage {
    private:

        // The physical limit of memory usage this object allows.
        unsigned long long limit;

        // Amount of memory currently used in.
        unsigned long long usage;

        // Mutex to lock usage and wait on.
        mutable decaf::util::concurrent::Mutex mutex;

    public:

        /**
         * Default Constructor.
         */
        MemoryUsage();

        /**
         * Creates an instance of an Usage monitor with a set limit.
         * @param limit - amount of memory this manager allows.
         */
        MemoryUsage( unsigned long long limit );

        virtual ~MemoryUsage();

        /**
         * Waits forever for more space to be returned to this Usage Manager.
         */
        virtual void waitForSpace();

        /**
         * Waits for more space to be returned to this Usage Manager, times out
         * when the given timespan in milliseconds elapses.
         * @param timeout The time to wait for more space.
         */
        virtual void waitForSpace( unsigned int timeout );

        /**
         * Tries to increase the usage by value amount but blocks if this object is
         * currently full.
         * @param value Amount of usage in bytes to add.
         */
        virtual void enqueueUsage( unsigned long long value ) {
            waitForSpace();
            increaseUsage(value);
        }

        /**
         * Increases the usage by the value amount
         * @param value Amount of usage to add.
         */
        virtual void increaseUsage( unsigned long long value );

        /**
         * Decreases the usage by the value amount.
         * @param value Amount of space to return to the pool
         */
        virtual void decreaseUsage( unsigned long long value );

        /**
         * Returns true if this Usage instance is full, i.e. Usage >= 100%
         */
        virtual bool isFull() const;

        /**
         * Gets the current usage amount.
         * @return the amount of bytes currently used.
         */
        unsigned long long getUsage() const {
            return usage;
        }

        /**
         * Sets the current usage amount
         * @param usage - The amount to tag as used.
         */
        void setUsage( unsigned long long usage ) {
            this->usage = usage;
        }

        /**
         * Gets the current limit amount.
         * @return the amount that can be used before full.
         */
        unsigned long long getLimit() const {
            return limit;
        }

        /**
         * Sets the current limit amount
         * @param limit - The amount that can be used before full.
         */
        void setLimit( unsigned long long limit ) {
            this->limit = limit;
        }

    };

}}

#endif /*_ACTIVEMQ_UTIL_MEMORYUSAGE_H_*/
