/*
 * 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.
 */

/*
 * poolmgr.c
 *	Have to be accessed in main thread!!!!
 */

#include "postgres.h"

#include "cdb/poolmgr.h"
#include "utils/hsearch.h"
#include "nodes/pg_list.h"

typedef struct PoolMgrState {
	MemoryContext			ctx;
	PoolMgrCleanCallback	callback;
	HTAB					*hashtable;
} PoolMgrState;

#define POOLMGR_HASH_TABLE_KEY_SIZE			128
#define POOLMGR_HASH_TABLE_ELEM_SIZE		1024

typedef struct PoolItemEntry {
	char		key[POOLMGR_HASH_TABLE_KEY_SIZE];
	List		*list;
} PoolItemEntry;


PoolMgrState *
poolmgr_create_pool(MemoryContext ctx, PoolMgrCleanCallback callback)
{
	PoolMgrState	*pool;
	HASHCTL			hash_ctl;

	pool = MemoryContextAlloc(ctx, sizeof(PoolMgrState));

	pool->ctx = ctx;
	pool->callback = callback;

	memset(&hash_ctl, 0, sizeof(hash_ctl));
	hash_ctl.keysize = POOLMGR_HASH_TABLE_KEY_SIZE;
	hash_ctl.entrysize = sizeof(PoolItemEntry);
	hash_ctl.hcxt = pool->ctx;

	pool->hashtable = hash_create("Pool Manager Hash",
							POOLMGR_HASH_TABLE_ELEM_SIZE,
							&hash_ctl,
							HASH_ELEM | HASH_CONTEXT);

	return pool;
}

bool
poolmgr_drop_pool(PoolMgrState *pool)
{
	HASH_SEQ_STATUS		hash_seq;
	PoolItemEntry		*entry;

	if (!pool)
		return true;

	hash_seq_init(&hash_seq, pool->hashtable);
	while ((entry = hash_seq_search(&hash_seq)))
	{
		ListCell	*lc;

		foreach(lc, entry->list)
		{
			if (pool->callback)
				pool->callback(lfirst(lc));
		}

		list_free(entry->list);
		entry->list = NULL;
	}

	hash_destroy(pool->hashtable);
	pfree(pool);
	return true;
}

PoolItem
poolmgr_get_random_item(PoolMgrState *pool)
{
	HASH_SEQ_STATUS		hash_seq;
	PoolItemEntry		*entry;
	char				*random_key_name = NULL;
	Assert(pool);

	hash_seq_init(&hash_seq, pool->hashtable);
	while ((entry = hash_seq_search(&hash_seq)))
	{
		if (list_length(entry->list) == 0)
			continue;

		random_key_name = entry->key;
		hash_seq_term(&hash_seq);
		break;
	}

	if (random_key_name == NULL)
		return NULL;

	return poolmgr_get_item_by_name(pool, random_key_name);
}


PoolItem
poolmgr_get_item_by_name(PoolMgrState *pool, const char *name)
{
	PoolItemEntry	*entry;
	PoolItem		*item;
	bool			found;
	Assert(pool);

	entry = hash_search(pool->hashtable, name, HASH_ENTER, &found);
	if (!found)
		entry->list = NIL;
	item = (PoolItem) (list_head(entry->list) ? linitial(entry->list) : NULL);
	entry->list = list_delete_first(entry->list);

	return item;
}

void
poolmgr_put_item(PoolMgrState *pool, const char *name, PoolItem item)
{
	PoolItemEntry	*entry;
	MemoryContext	old;
	bool			found;
	Assert(pool);

	entry = hash_search(pool->hashtable, name, HASH_ENTER, &found);
	if (!found)
		entry->list = NIL;
	old = MemoryContextSwitchTo(pool->ctx);
	entry->list = lappend(entry->list, item);
	MemoryContextSwitchTo(old);
}

void
poolmgr_iterate(PoolMgrState *pool, PoolMgrIterateFilter filter, PoolMgrIterateCallback callback, PoolIterateArg data)
{
	HASH_SEQ_STATUS		hash_seq;
	PoolItemEntry		*entry;

	if (!pool)
		return;

	hash_seq_init(&hash_seq, pool->hashtable);
	while ((entry = hash_seq_search(&hash_seq)))
	{
		ListCell	*lc;

		foreach(lc, entry->list)
		{
			PoolItem	item = lfirst(lc);

			if (filter && !filter(item))
				continue;

			callback(item, data);
		}

	}

	return;
}

int poolmgr_clean(struct PoolMgrState *pool, PoolMgrIterateFilter filter)
{
    int res = 0;
    HASH_SEQ_STATUS hash_seq;
    PoolItemEntry *entry;

    if (!pool)
        return res;

    hash_seq_init(&hash_seq, pool->hashtable);
    while ((entry = hash_seq_search(&hash_seq)))
    {
        ListCell *curr = list_head(entry->list);
        ListCell *prev = NULL;
        while (curr != NULL)
        {
            PoolItem  item = lfirst(curr);
            if (filter && !filter(item))
            {
                /* try next */
                prev = curr;
                curr = lnext(prev);
                continue;
            }

            /* clean now */
            res++;
            pool->callback(item);
            entry->list = list_delete_cell(entry->list, curr, prev);
            if (prev != NULL)
            {
                curr = lnext(prev);
            }
            else
            {
                curr = list_head(entry->list);
            }
        }
    }
    return res;
}

