// ---------------------------------------------------------------------------
// - Recycle.cpp                                                            -
// - standard object library - object recycler class implementation         -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2008 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Recycle.hpp"
#include "cmem.hpp"

namespace afnix {

  // -------------------------------------------------------------------------
  // - private section                                                       -
  // -------------------------------------------------------------------------

  // default recycling size
  const long RECYCLE_SIZE = 1024;

  // -------------------------------------------------------------------------
  // - class section                                                         -
  // -------------------------------------------------------------------------

  // create a new recycler class

  Recycle::Recycle (void) {
    d_size = RECYCLE_SIZE;
    d_plen = 0;
    p_rptr = new void*[d_size];
    for (long i = 0; i < d_size; i++) p_rptr[i] = nilp;
  }

  // destroy this recycler class

  Recycle::~Recycle (void) {
    for (long i = 0; i < d_plen; i++) c_free (p_rptr[i]);
    delete [] p_rptr;
  }

  // push a pointer to recycle

  void Recycle::push (void* ptr) {
    d_mtx.lock ();
    if (d_plen == d_size) {
      c_free (ptr);
    } else {
      p_rptr[d_plen++] = ptr;
    }
    d_mtx.unlock ();
  }

  // pop a recycled pointer

  void* Recycle::pop (const t_size size) {
    d_mtx.lock ();
    void* result = nilp;
    if (d_plen == 0) {
      result = c_malloc (size);
    } else {
      result = p_rptr[--d_plen];
    }
    d_mtx.unlock ();
    return result;
  }
}
