/*
 * object_pool.c :  generic pool of reference-counted objects
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */




#include <assert.h>

#include "svn_error.h"
#include "svn_hash.h"
#include "svn_pools.h"

#include "private/svn_atomic.h"
#include "private/svn_object_pool.h"
#include "private/svn_subr_private.h"
#include "private/svn_dep_compat.h"



/* A reference counting wrapper around the user-provided object.
 */
typedef struct object_ref_t
{
  /* reference to the parent container */
  svn_object_pool__t *object_pool;

  /* identifies the bucket in OBJECT_POOL->OBJECTS in which this entry
   * belongs. */
  svn_membuf_t key;

  /* User provided object. Usually a wrapper. */
  void *object;

  /* private pool. This instance and its other members got allocated in it.
   * Will be destroyed when this instance is cleaned up. */
  apr_pool_t *pool;

  /* Number of references to this data struct */
  volatile svn_atomic_t ref_count;
} object_ref_t;


/* Core data structure.  All access to it must be serialized using MUTEX.
 */
struct svn_object_pool__t
{
  /* serialization object for all non-atomic data in this struct */
  svn_mutex__t *mutex;

  /* object_ref_t.KEY -> object_ref_t* mapping.
   *
   * In shared object mode, there is at most one such entry per key and it
   * may or may not be in use.  In exclusive mode, only unused references
   * will be put here and they form chains if there are multiple unused
   * instances for the key. */
  apr_hash_t *objects;

  /* same as objects->count but allows for non-sync'ed access */
  volatile svn_atomic_t object_count;

  /* Number of entries in OBJECTS with a reference count 0.
     Due to races, this may be *temporarily* off by one or more.
     Hence we must not strictly depend on it. */
  volatile svn_atomic_t unused_count;

  /* the root pool owning this structure */
  apr_pool_t *pool;
};


/* Pool cleanup function for the whole object pool.
 */
static apr_status_t
object_pool_cleanup(void *baton)
{
  svn_object_pool__t *object_pool = baton;

  /* all entries must have been released up by now */
  SVN_ERR_ASSERT_NO_RETURN(   object_pool->object_count
                           == object_pool->unused_count);

  return APR_SUCCESS;
}

/* Remove entries from OBJECTS in OBJECT_POOL that have a ref-count of 0.
 *
 * Requires external serialization on OBJECT_POOL.
 */
static void
remove_unused_objects(svn_object_pool__t *object_pool)
{
  apr_pool_t *subpool = svn_pool_create(object_pool->pool);

  /* process all hash buckets */
  apr_hash_index_t *hi;
  for (hi = apr_hash_first(subpool, object_pool->objects);
       hi != NULL;
       hi = apr_hash_next(hi))
    {
      object_ref_t *object_ref = apr_hash_this_val(hi);

      /* note that we won't hand out new references while access
         to the hash is serialized */
      if (svn_atomic_read(&object_ref->ref_count) == 0)
        {
          apr_hash_set(object_pool->objects, object_ref->key.data,
                       object_ref->key.size, NULL);
          svn_atomic_dec(&object_pool->object_count);
          svn_atomic_dec(&object_pool->unused_count);

          svn_pool_destroy(object_ref->pool);
        }
    }

  svn_pool_destroy(subpool);
}

/* Cleanup function called when an object_ref_t gets released.
 */
static apr_status_t
object_ref_cleanup(void *baton)
{
  object_ref_t *object = baton;
  svn_object_pool__t *object_pool = object->object_pool;

  /* If we released the last reference to object, there is one more
     unused entry.

     Note that unused_count does not need to be always exact but only
     needs to become exact *eventually* (we use it to check whether we
     should remove unused objects every now and then).  I.e. it must
     never drift off / get stuck but always reflect the true value once
     all threads left the racy sections.
   */
  if (svn_atomic_dec(&object->ref_count) == 0)
    svn_atomic_inc(&object_pool->unused_count);

  return APR_SUCCESS;
}

/* Handle reference counting for the OBJECT_REF that the caller is about
 * to return.  The reference will be released when POOL gets cleaned up.
 *
 * Requires external serialization on OBJECT_REF->OBJECT_POOL.
 */
static void
add_object_ref(object_ref_t *object_ref,
              apr_pool_t *pool)
{
  /* Update ref counter.
     Note that this is racy with object_ref_cleanup; see comment there. */
  if (svn_atomic_inc(&object_ref->ref_count) == 0)
    svn_atomic_dec(&object_ref->object_pool->unused_count);

  /* Make sure the reference gets released automatically.
     Since POOL might be a parent pool of OBJECT_REF->OBJECT_POOL,
     to the reference counting update before destroying any of the
     pool hierarchy. */
  apr_pool_pre_cleanup_register(pool, object_ref, object_ref_cleanup);
}

/* Actual implementation of svn_object_pool__lookup.
 *
 * Requires external serialization on OBJECT_POOL.
 */
static svn_error_t *
lookup(void **object,
       svn_object_pool__t *object_pool,
       svn_membuf_t *key,
       apr_pool_t *result_pool)
{
  object_ref_t *object_ref
    = apr_hash_get(object_pool->objects, key->data, key->size);

  if (object_ref)
    {
      *object = object_ref->object;
      add_object_ref(object_ref, result_pool);
    }
  else
    {
      *object = NULL;
    }

  return SVN_NO_ERROR;
}

/* Actual implementation of svn_object_pool__insert.
 *
 * Requires external serialization on OBJECT_POOL.
 */
static svn_error_t *
insert(void **object,
       svn_object_pool__t *object_pool,
       const svn_membuf_t *key,
       void *item,
       apr_pool_t *item_pool,
       apr_pool_t *result_pool)
{
  object_ref_t *object_ref
    = apr_hash_get(object_pool->objects, key->data, key->size);
  if (object_ref)
    {
      /* Destroy the new one and return a reference to the existing one
       * because the existing one may already have references on it.
       */
      svn_pool_destroy(item_pool);
    }
  else
    {
      /* add new index entry */
      object_ref = apr_pcalloc(item_pool, sizeof(*object_ref));
      object_ref->object_pool = object_pool;
      object_ref->object = item;
      object_ref->pool = item_pool;

      svn_membuf__create(&object_ref->key, key->size, item_pool);
      object_ref->key.size = key->size;
      memcpy(object_ref->key.data, key->data, key->size);

      apr_hash_set(object_pool->objects, object_ref->key.data,
                   object_ref->key.size, object_ref);
      svn_atomic_inc(&object_pool->object_count);

      /* the new entry is *not* in use yet.
       * add_object_ref will update counters again.
       */
      svn_atomic_inc(&object_ref->object_pool->unused_count);
    }

  /* return a reference to the object we just added */
  *object = object_ref->object;
  add_object_ref(object_ref, result_pool);

  /* limit memory usage */
  if (svn_atomic_read(&object_pool->unused_count) * 2
      > apr_hash_count(object_pool->objects) + 2)
    remove_unused_objects(object_pool);

  return SVN_NO_ERROR;
}


/* API implementation */

svn_error_t *
svn_object_pool__create(svn_object_pool__t **object_pool,
                        svn_boolean_t thread_safe,
                        apr_pool_t *pool)
{
  svn_object_pool__t *result;

  /* construct the object pool in our private ROOT_POOL to survive POOL
   * cleanup and to prevent threading issues with the allocator
   */
  result = apr_pcalloc(pool, sizeof(*result));
  SVN_ERR(svn_mutex__init(&result->mutex, thread_safe, pool));

  result->pool = pool;
  result->objects = svn_hash__make(result->pool);

  /* make sure we clean up nicely.
   * We need two cleanup functions of which exactly one will be run
   * (disabling the respective other as the first step).  If the owning
   * pool does not cleaned up / destroyed explicitly, it may live longer
   * than our allocator.  So, we need do act upon cleanup requests from
   * either side - owning_pool and root_pool.
   */
  apr_pool_cleanup_register(pool, result, object_pool_cleanup,
                            apr_pool_cleanup_null);

  *object_pool = result;
  return SVN_NO_ERROR;
}

apr_pool_t *
svn_object_pool__new_item_pool(svn_object_pool__t *object_pool)
{
  return svn_pool_create(object_pool->pool);
}

svn_error_t *
svn_object_pool__lookup(void **object,
                        svn_object_pool__t *object_pool,
                        svn_membuf_t *key,
                        apr_pool_t *result_pool)
{
  *object = NULL;
  SVN_MUTEX__WITH_LOCK(object_pool->mutex,
                       lookup(object, object_pool, key, result_pool));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_object_pool__insert(void **object,
                        svn_object_pool__t *object_pool,
                        const svn_membuf_t *key,
                        void *item,
                        apr_pool_t *item_pool,
                        apr_pool_t *result_pool)
{
  *object = NULL;
  SVN_MUTEX__WITH_LOCK(object_pool->mutex,
                       insert(object, object_pool, key, item,
                              item_pool, result_pool));
  return SVN_NO_ERROR;
}
