// bslma_infrequentdeleteblocklist.h                                  -*-C++-*-
#ifndef INCLUDED_BSLMA_INFREQUENTDELETEBLOCKLIST
#define INCLUDED_BSLMA_INFREQUENTDELETEBLOCKLIST

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide allocation and management of a sequence of memory blocks.
//
//@INTERNAL_DEPRECATED: Use `bdlma_infrequentdeleteblocklist` instead.
//
//@CLASSES:
//  bslma::InfrequentDeleteBlockList: list of infrequently deleted blocks
//
//@SEE_ALSO: bdlma_infrequentdeleteblocklist
//
//@DESCRIPTION: This component implements a memory manager that allocates and
// manages a sequence of memory blocks, each potentially of a different size as
// specified in the `allocate` method's invocation.  The
// `bslma::InfrequentDeleteBlockList` object's `release` method deallocates the
// entire sequence of memory blocks, as does its destructor.
//
// This component does not allow individual items to be deallocated.
//
///Usage
///-----
// The `bslma::InfrequentDeleteBlockList` object is commonly used to supply
// memory to more elaborate memory managers that distribute parts of a memory
// block supplied by the `bslma::InfrequentDeleteBlockList` object.  The
// `my_StrPool` memory pool manager shown below requests relatively large
// blocks of memory from its `bslma::InfrequentDeleteBlockList` member object
// and distributes memory chunks of varying sizes from each block on demand:
// ```
// // my_strpool.h
//
// class my_StrPool {
//     int   d_blockSize;  // size of current memory block
//     char *d_block_p;    // current free memory block
//     int   d_cursor;     // offset to address of next available byte
//     bslma::InfrequentDeleteBlockList d_blockList;
//                                      // supplies managed memory blocks
//
//   private:
//
//     /// Request a new memory block of at least the specified `numBytes`
//     /// size and allocate the initial `numBytes` from this block.
//     /// Return the address of the allocated memory.
//     void *allocateBlock(int numBytes);
//
//   private: // not implemented
//     my_StrPool(const my_StrPool&);
//     my_StrPool& operator=(const my_StrPool&);
//
//   public:
//     // CREATORS
//
//     /// Create a memory manager using the specified `basicAllocator` to
//     /// supply memory.  If `basicAllocator` is 0, the currently
//     /// installed default allocator is used.
//     my_StrPool(bslma::Allocator *basicAllocator = 0);
//
//     /// Destroy this object and release all associated memory.
//     ~my_StrPool();
//
//     // MANIPULATORS
//
//     /// Allocate the specified `numBytes` of memory and return its
//     /// address.
//     void *allocate(int numBytes);
//
//     /// Release all memory currently allocated through this instance.
//     void release();
// };
//
// inline
// void *my_StrPool::allocate(int numBytes)
// {
//     if (numBytes <= 0) {
//         return 0;
//     }
//     if (d_block_p && numBytes + d_cursor <= d_blockSize) {
//         char *p = d_block_p + d_cursor;
//         d_cursor += numBytes;
//         return p;
//     }
//     else {
//         return allocateBlock(numBytes);
//     }
// }
//
// inline
// void my_StrPool::release()
// {
//     d_blockList.release();
//     d_block_p = 0;
// }
//
// // ...
//
// // my_strpool.cpp
//
// enum {
//     INITIAL_SIZE = 128, // initial block size
//     GROW_FACTOR  = 2,   // multiplicative factor to grow block size
//     THRESHOLD    = 128  // Size beyond which an individual block may be
//                         // allocated if it does not fit in the current
//                         // block.
// };
//
// void *my_StrPool::allocateBlock(int numBytes)
// {
//     ASSERT(0 < numBytes);
//     if (THRESHOLD < numBytes) { // Alloc separate block if above threshold.
//         return (char *) d_blockList.allocate(numBytes);
//     }
//     else {
//         if (d_block_p) { // Don't increase block size if no current block.
//             d_blockSize *= GROW_FACTOR;
//         }
//         d_block_p = (char *) d_blockList.allocate(d_blockSize);
//         d_cursor = numBytes;
//         return d_block_p;
//     }
// }
//
// my_StrPool::my_StrPool(bslma::Allocator *basicAllocator)
// : d_blockSize(INITIAL_SIZE)
// , d_block_p(0)
// , d_blockList(basicAllocator)
// {
// }
//
// my_StrPool::~my_StrPool()
// {
//     assert(INITIAL_SIZE <= d_blockSize);
//     assert(d_block_p || 0 <= d_cursor && d_cursor <= d_blockSize);
// }
// ```
// In the code above, the `my_StrPool` memory manager allocates from its
// `bslma::InfrequentDeleteBlockList` member object an initial memory block of
// size `INITIAL_SIZE`.  This size is multiplied by `GROW_FACTOR` each time a
// deplete memory block is replaced by a newly allocated block.  The `allocate`
// method distributes memory from the current memory block piecemeal, except
// when the requested size: 1) is not available in the current block and 2)
// exceeds the `THRESHOLD_SIZE`, in which case a separate memory block is
// allocated and returned.  When the `my_StrPool` memory manager is destroyed,
// its `bslma::InfrequentDeleteBlockList` member object is also destroyed,
// which in turn automatically deallocates all of its managed memory blocks.

#ifdef BDE_OPENSOURCE_PUBLICATION // DEPRECATED
#error "bslma_infrequentdeleteblocklist is deprecated"
#endif
#include <bslscm_version.h>

#include <bslma_default.h>

#include <bsls_alignmentutil.h>

namespace BloombergLP {


namespace bslma {

class Allocator;

                  // ===============================
                  // class InfrequentDeleteBlockList
                  // ===============================

/// This class implements a memory manager that allocates and manages a
/// sequence of memory blocks, each potentially of a different size as
/// specified in the `allocate` method's invocation.  This object's
/// `release` method deallocates the entire sequence of memory blocks, as
/// does its destructor.  Note that memory blocks can not be deallocated
/// individually.
class InfrequentDeleteBlockList {

    // TYPES
    struct Block {
        Block                               *d_next_p;
        bsls::AlignmentUtil::MaxAlignedType  d_memory;  // force alignment
    };

    // DATA
    Block           *d_head_p;       // refers to the first memory block
    Allocator       *d_allocator_p;  // holds (but does not own) the allocator

    // NOT IMPLEMENTED
    InfrequentDeleteBlockList(const InfrequentDeleteBlockList&);
    InfrequentDeleteBlockList&
                          operator=(const InfrequentDeleteBlockList&);

  public:
    // CREATORS

    /// Create a memory manager.  Optionally specify a `basicAllocator` used
    /// to supply memory.  If `basicAllocator` is 0, the currently installed
    /// default allocator is used.
    explicit InfrequentDeleteBlockList(Allocator *basicAllocator = 0);

    /// Destroy this object and deallocate all memory blocks managed by this
    /// object.
    ~InfrequentDeleteBlockList();

    // MANIPULATORS

    /// Allocate a memory block of the specified `numBytes` size and return
    /// its address.  The returned memory is guaranteed to be maximally
    /// aligned.  The behavior is undefined unless `0 <= numBytes`.
    void *allocate(int numBytes);

    /// This method has no effect.
    void deallocate(void *address);

    /// Deallocate all memory blocks managed by this object.
    void release();
};

// ============================================================================
//                      INLINE FUNCTION DEFINITIONS
// ============================================================================

                  // -------------------------------
                  // class InfrequentDeleteBlockList
                  // -------------------------------

// CREATORS
inline
InfrequentDeleteBlockList::
               InfrequentDeleteBlockList(Allocator *basicAllocator)
: d_head_p(0)
, d_allocator_p(Default::allocator(basicAllocator))
{
}

// MANIPULATORS
inline
void InfrequentDeleteBlockList::deallocate(void *)
{
}

}  // close package namespace

#ifndef BDE_OPENSOURCE_PUBLICATION  // BACKWARD_COMPATIBILITY
// ============================================================================
//                           BACKWARD COMPATIBILITY
// ============================================================================

/// This alias is defined for backward compatibility.
typedef bslma::InfrequentDeleteBlockList bslma_InfrequentDeleteBlockList;
#endif  // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY

}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// 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.
// ----------------------------- END-OF-FILE ----------------------------------
