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

/*-------------------------------------------------------------------------
 *
 * workfile_segmentspace.c
 *	 Implementation of workfile manager per-segment disk space accounting
 *
 *-------------------------------------------------------------------------
 */

#include <postgres.h>
#include "storage/shmem.h"
#include "utils/atomic.h"
#include "cdb/cdbvars.h"
#include "utils/workfile_mgr.h"
#include "miscadmin.h"

/* Name to identify the WorkfileSegspace shared memory area by */
#define WORKFILE_SEGSPACE_SHMEM_NAME "WorkfileSegspace"

/* Pointer to the shared memory counter with the total used diskspace across segment */
static int64 *used_segspace = NULL;

/*
 * Initialize shared memory area for the WorkfileSegspace module
 */
void
WorkfileSegspace_Init(void)
{
	bool attach = false;
	/* Allocate or attach to shared memory area */
	void *shmem_base = ShmemInitStruct(WORKFILE_SEGSPACE_SHMEM_NAME,
			WorkfileSegspace_ShMemSize(),
			&attach);

	used_segspace = (int64 *)shmem_base;
	Assert(0 == *used_segspace);
}

/*
 * Returns the amount of shared memory needed for the WorkfileSegspace module
 */
Size
WorkfileSegspace_ShMemSize(void)
{
	return sizeof(*used_segspace);
}

/*
 * Reserve 'bytes' bytes to write to disk
 *   This should be called before actually writing to disk
 *
 *   If enough disk space is available, increments the global counter and returns true
 *   Otherwise, sets the workfile_diskfull flag to true and returns false
 */
bool
WorkfileSegspace_Reserve(int64 bytes_to_reserve)
{
	Assert(NULL != used_segspace);

	int64 total = gp_atomic_add_int64(used_segspace, bytes_to_reserve);
	Assert(total >= (int64) 0);

	if (gp_workfile_limit_per_segment == 0)
	{
		/* not enforced */
		return true;
	}

	int64 max_allowed_diskspace = (int64) (gp_workfile_limit_per_segment * 1024);
	if (total <= max_allowed_diskspace)
	{
		return true;
	}
	else
	{
		/* We exceeded the logical limit. Revert and try to evict */

		int crt_attempt = 0;
		while (crt_attempt < MAX_EVICT_ATTEMPTS)
		{

			/* Revert the reserved space */
			(void) gp_atomic_add_int64(used_segspace, - bytes_to_reserve);

			CHECK_FOR_INTERRUPTS();

			int64 requested_evict = Max(MIN_EVICT_SIZE, bytes_to_reserve);
			int64 size_evicted = workfile_mgr_evict(requested_evict);

			if (size_evicted < bytes_to_reserve)
			{
				workfileError = WORKFILE_ERROR_LIMIT_PER_SEGMENT;
				/*
				 * We couldn't evict as much as we need to write. Reservation
				 * failed, notify caller.
				 */
				elog(gp_workfile_caching_loglevel,
						"Failed to reserved size " INT64_FORMAT ". Reverted back to total " INT64_FORMAT,
						bytes_to_reserve, *used_segspace);

				/* Set diskfull to true to stop any further attempts to write more data */
				WorkfileDiskspace_SetFull(true /* isFull */);

				return false;
			}

			/* Try to reserve again */
			total = gp_atomic_add_int64(used_segspace, bytes_to_reserve);
			Assert(total >= (int64) 0);

			if (total <= max_allowed_diskspace)
			{
				/* Reservation successful, we're done */
				return true;
			}

			/*
			 * Someone else snatched the space after we evicted it.
			 * Loop around and try to evict again
			 */
			crt_attempt++;
		}
	}


	/*
	 * We exceeded max_eviction_attempts and did not manage to reserve.
	 * Set diskfull to true to stop any further attempts to write more data
	 * and notify the caller.
	 */
	WorkfileDiskspace_SetFull(true /* isFull */);
	return false;
}

/*
 * Notify of how many bytes were actually written to disk
 *
 * This should be called after writing to disk, with the actual number
 * of bytes written. This must be less or equal than the amount we reserved
 *
 * Returns the current used_diskspace after the commit
 */
void
WorkfileSegspace_Commit(int64 commit_bytes, int64 reserved_bytes)
{
	Assert(NULL != used_segspace);
	Assert(reserved_bytes >= commit_bytes);

#if USE_ASSERT_CHECKING
	int64 total = 
#endif
	gp_atomic_add_int64(used_segspace, (commit_bytes - reserved_bytes));
	Assert(total >= (int64) 0);
}

/*
 * Returns the amount of disk space used for workfiles on this segment
 */
int64
WorkfileSegspace_GetSize()
{
	Assert(NULL != used_segspace);
	return *used_segspace;
}

/* EOF */
