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

/*-------------------------------------------------------------------------
 *
 * cdbsharedoidsearch.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"
#include "miscadmin.h"
#include "cdb/cdbshareddoublylinked.h"
#include "cdb/cdbsharedoidsearch.h"

// -----------------------------------------------------------------------------
// Free Pool 
// -----------------------------------------------------------------------------

static void SharedOidSearch_MakeFreeObjPool(
	SharedOidSearchFreeObjPool 	*sharedFreeObjPool,
				/* The shared free object pool to initialize. */

	void *freeObjectArray,
				/* The shared-memory to use. */

	int32 freeObjectCount,
				/* The byte length of the shared-memory. */

	int32 objectLen)
				/* 
				 * The total length of the objects that includes the embedded header
				 * SharedOidSearchObjHeader.
				 */
{
	int32 i;

	SharedListBase_Init(
		&sharedFreeObjPool->listBase,
		freeObjectArray,
		objectLen,
		offsetof(SharedOidSearchObjHeader,private.links));

	SharedDoublyLinkedHead_Init(&sharedFreeObjPool->freeList);

	/*
	 * Initalize the free objects.
	 */
	for (i = 0; i < freeObjectCount; i++)
	{
		SharedOidSearchObjHeader *ele;

		ele = (SharedOidSearchObjHeader*)
					SharedListBase_ToElement(
							&sharedFreeObjPool->listBase, i);
		
		SharedDoubleLinks_Init(&ele->private.links, i);

		SharedDoublyLinkedHead_AddLast(
			&sharedFreeObjPool->listBase,
			&sharedFreeObjPool->freeList,
			ele);
	}
}

// -----------------------------------------------------------------------------
// Initialize
// -----------------------------------------------------------------------------

int32 SharedOidSearch_TableLen(
	int32 hashSize,
				/* The hash array size */

	int32 freeObjectCount,

	int32 objectLen)
				/* 
				 * The total length of the objects that includes the embedded header
				 * SharedOidSearchObjHeader.
				 */
{
	return MAXALIGN(offsetof(SharedOidSearchTable,private.buckets)) +
		   MAXALIGN(hashSize * sizeof(SharedOidSearchHashBucket)) +
		   MAXALIGN(freeObjectCount * objectLen);
}

void SharedOidSearch_InitTable(
	SharedOidSearchTable *table,
				/* The shared search tables to initialize. */

	int32 hashSize,
				/* The hash array size */

	int32 freeObjectCount,

	int32 objectLen)
				/* 
				 * The total length of the objects that includes the embedded header
				 * SharedOidSearchObjHeader.
				 */
{
	SharedOidSearchHashBucket	*bucketArray;
	int32						freePoolObjectArrayOffset;
	void 						*freePoolObjectArray;

	int32 i;

	table->private.hashSize = hashSize;

	bucketArray = &table->private.buckets[0];

	for (i = 0; i < hashSize; i++)
		SharedDoublyLinkedHead_Init(&bucketArray[i].bucketListHead);

	freePoolObjectArrayOffset =
					MAXALIGN(
						(int32)
							((uint8*)&table->private.buckets[hashSize] - (uint8*)table));

	freePoolObjectArray = 
					(void*)
						(((uint8*)table) + freePoolObjectArrayOffset);
	
	SharedOidSearch_MakeFreeObjPool(
						&table->private.freePool,
						freePoolObjectArray,
						freeObjectCount,
						objectLen);	

}


// -----------------------------------------------------------------------------
// Helpers
// -----------------------------------------------------------------------------

static SharedOidSearchHashBucket *SharedOidSearch_GetBucket(
	SharedOidSearchTable		*table,
	Oid 						oid1,
	Oid							oid2)
{
	int32 bucketNum;
	
	bucketNum = (oid1 ^ oid2) % table->private.hashSize;
	return &table->private.buckets[bucketNum];
}

static SharedOidSearchObjHeader *SharedOidSearch_FindInBucket(
	SharedOidSearchTable		*table,
	SharedOidSearchHashBucket	*bucket,
	Oid 						oid1,
	Oid							oid2)
{
	SharedListBase				*listBase = &table->private.freePool.listBase;
	SharedDoublyLinkedHead		*listHead;
	SharedOidSearchObjHeader 	*ele;

	listHead = &bucket->bucketListHead;
	ele = (SharedOidSearchObjHeader*)
					SharedDoublyLinkedHead_First(listBase, listHead);
	while (ele != NULL)
	{
		if (ele->oid1 == oid1 && ele->oid2 == oid2)
			return ele;

		ele = (SharedOidSearchObjHeader*)
					SharedDoubleLinks_Next(listBase, listHead, ele);
	}

	return NULL;
}

static SharedOidSearchObjHeader *SharedOidSearch_ProbeInBucket(
	SharedOidSearchTable		*table,
	SharedOidSearchHashBucket	*bucket,
	Oid 						oid1,
	Oid							oid2)
{
	SharedListBase				*listBase = &table->private.freePool.listBase;
	SharedDoublyLinkedHead		*listHead;
	SharedOidSearchObjHeader 	*ele;

	listHead = &bucket->bucketListHead;
	ele = (SharedOidSearchObjHeader*)
					SharedDoublyLinkedHead_First(listBase, listHead);
	while (ele != NULL)
	{
		if (ele->oid1 == oid1 && ele->oid2 == oid2)
			return ele;

		ele = (SharedOidSearchObjHeader*)
					SharedDoubleLinks_Next(listBase, listHead, ele);
	}

	return NULL;
}

static void SharedOidSearch_RemoveFromBucket(
	SharedOidSearchTable		*table,
	SharedOidSearchHashBucket	*bucket,
	SharedOidSearchObjHeader 	*ele)
{
	SharedListBase				*listBase = &table->private.freePool.listBase;
	SharedDoublyLinkedHead		*listHead;

	Assert(ele->private.isDeleted);
	Assert(ele->private.pinCount == 0);

	listHead = &bucket->bucketListHead;

	SharedDoubleLinks_Remove(listBase, listHead, ele);
	
	SharedDoublyLinkedHead_AddLast(
					&table->private.freePool.listBase,
					&table->private.freePool.freeList,
					ele);
}


// -----------------------------------------------------------------------------
// Add, Find, Probe, and Delete
// -----------------------------------------------------------------------------

SharedOidSearchAddResult SharedOidSearch_Add(
	SharedOidSearchTable 		*table,
	Oid 						oid1,
	Oid 						oid2,
	SharedOidSearchObjHeader	**header)
{
	SharedOidSearchHashBucket	*bucket;
	SharedOidSearchObjHeader 	*ele;

	bucket = SharedOidSearch_GetBucket(table, oid1, oid2);

	ele = SharedOidSearch_FindInBucket(table, bucket, oid1, oid2);
	if (ele != NULL)
		return SharedOidSearchAddResult_Exists;

	ele = 
		(SharedOidSearchObjHeader*)
				SharedDoublyLinkedHead_RemoveFirst(
								&table->private.freePool.listBase,
								&table->private.freePool.freeList);
	if (ele == NULL)
		return SharedOidSearchAddResult_NoMemory;

	ele->private.pinCount = 0;
	ele->private.isDeleted = false;
	ele->oid1 = oid1;
	ele->oid2 = oid2;

	SharedDoublyLinkedHead_AddLast(
							&table->private.freePool.listBase,
						    &bucket->bucketListHead,
						    ele);

	*header = ele;
	return SharedOidSearchAddResult_Ok;
}

SharedOidSearchObjHeader *SharedOidSearch_Find(
	SharedOidSearchTable 	*table,
	Oid 					oid1,
	Oid 					oid2)
{
	SharedOidSearchHashBucket	*bucket;
	SharedOidSearchObjHeader 	*ele;

	bucket = SharedOidSearch_GetBucket(table, oid1, oid2);

	ele = SharedOidSearch_FindInBucket(table, bucket, oid1, oid2);
	if (ele == NULL)
		return NULL;

	return ele;
}

SharedOidSearchObjHeader *SharedOidSearch_Probe(
	SharedOidSearchTable 	*table,
	Oid 					oid1,
	Oid						oid2)
{
	SharedOidSearchHashBucket	*bucket;
	SharedOidSearchObjHeader 	*ele;

	bucket = SharedOidSearch_GetBucket(table, oid1, oid2);

	ele = SharedOidSearch_ProbeInBucket(table, bucket, oid1, oid2);
	if (ele == NULL)
		return NULL;

	return ele;
}

static bool SharedOidSearch_NextBucket(
	SharedOidSearchTable		*table,
	SharedOidSearchHashBucket	**bucket)
{
	int32 hashSize = table->private.hashSize;

	if (*bucket == &table->private.buckets[hashSize-1])
		return false;

	(*bucket)++;
	return true;
}

static bool SharedOidSearch_FindNonDeletedInBucket(
	SharedListBase				*listBase,
	SharedDoublyLinkedHead		*listHead,
	SharedOidSearchObjHeader	**header)
{
	while (true)
	{
		if (!(*header)->private.isDeleted)
			return true;
		
		*header = 
			(SharedOidSearchObjHeader*)
					SharedDoubleLinks_Next(
										listBase,
										listHead,
										*header);
		if (*header == NULL)
			return false;
	}
}


void SharedOidSearch_Iterate(
	SharedOidSearchTable 		*table,
	SharedOidSearchObjHeader	**header)
{
	SharedListBase				*listBase = &table->private.freePool.listBase;
	SharedOidSearchHashBucket	*bucket;
	SharedOidSearchObjHeader	*current = *header;

	if (current != NULL)
	{
		/*
		 * Try to get next element in current bucket.
		 */
		bucket = SharedOidSearch_GetBucket(table, current->oid1, current->oid2);

		Assert(current->private.pinCount > 0);
		current->private.pinCount--;
			
		*header = 
			(SharedOidSearchObjHeader*)
					SharedDoubleLinks_Next(
										listBase,
										&bucket->bucketListHead,
										current);

		if (current->private.isDeleted &&
			current->private.pinCount == 0)
			SharedOidSearch_RemoveFromBucket(table, bucket, current);
			
		if (*header != NULL &&
			SharedOidSearch_FindNonDeletedInBucket(
											listBase,
											&bucket->bucketListHead,
											header))
		{
			(*header)->private.pinCount++;
			return;
		}

		Assert(*header == NULL);

		if (!SharedOidSearch_NextBucket(
									table,
									&bucket))
			return;		// No more buckets.
	}
	else
		bucket = &table->private.buckets[0];

	/*
	 * Find next non-empty bucket.
	 */
	 while (true)
	{
		*header = 
				(SharedOidSearchObjHeader*)
						SharedDoublyLinkedHead_First(
												listBase,
												&bucket->bucketListHead);
		if (*header != NULL &&
			SharedOidSearch_FindNonDeletedInBucket(
											listBase,
											&bucket->bucketListHead,
											header))
		{
			(*header)->private.pinCount++;
			return;
		}

		Assert(*header == NULL);

		if (!SharedOidSearch_NextBucket(
									table,
									&bucket))
			return;		// No more buckets.
	}
}

void SharedOidSearch_ReleaseIterator(
	SharedOidSearchTable 		*table,
	SharedOidSearchObjHeader	**header)
{
	SharedOidSearchObjHeader	*current = *header;
	SharedOidSearchHashBucket	*bucket;
	
	Assert(current->private.pinCount > 0);
	current->private.pinCount--;

	if (current->private.isDeleted &&
		current->private.pinCount == 0)
	{
		bucket = SharedOidSearch_GetBucket(table, current->oid1, current->oid2);
		SharedOidSearch_RemoveFromBucket(table, bucket, current);
	}
	
	*header = NULL;
}

void SharedOidSearch_Delete(
	SharedOidSearchTable 		*table,
	SharedOidSearchObjHeader	*header)
{
	SharedOidSearchHashBucket	*bucket;

	Assert(!header->private.isDeleted);
	header->private.isDeleted = true;

	if (header->private.pinCount > 0)
		return;		// Let the last iterator turn out the light.

	bucket = SharedOidSearch_GetBucket(table, header->oid1, header->oid2);

	SharedOidSearch_RemoveFromBucket(table, bucket, header);
}
