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

/*-------------------------------------------------------------------------
 *
 * cdbbufferedread.c
 *	  Read buffers sequentially from a file efficiently.
 *
 * (See .h file for usage comments)
 *
 *-------------------------------------------------------------------------
 */
#include "cdb/cdbbufferedread.h"
#include <unistd.h>				/* for read() */
#include "utils/guc.h"

static void BufferedReadIo(
    BufferedRead        *bufferedRead);
static uint8 *BufferedReadUseBeforeBuffer(
    BufferedRead       *bufferedRead,
    int32              maxReadAheadLen,
    int32              *nextBufferLen,
    bool 				isUseSplitLen);


/*
 * Determines the amount of memory to supply for
 * BufferedRead given the desired buffer and
 * large write lengths.
 */
int32 BufferedReadMemoryLen(
    int32                maxBufferLen,
    int32                maxLargeReadLen)
{
	Assert(maxBufferLen > 0);
	Assert(maxLargeReadLen >= maxBufferLen);

	// Adjacent before memory for 1 buffer and large read memory.
	return (maxBufferLen + maxLargeReadLen);
}

/*
 * Initialize BufferedRead.
 *
 * Use the BufferedReadMemoryLen procedure to
 * determine the amount of memory to supply.
 */
void BufferedReadInit(
    BufferedRead         *bufferedRead,
    uint8                *memory,
    int32                memoryLen,
    int32                maxBufferLen,
    int32                maxLargeReadLen,
    char				 *relationName)
{
	int		relationNameLen;

	Assert(bufferedRead != NULL);
	Assert(memory != NULL);
	Assert(maxBufferLen > 0);
	Assert(maxLargeReadLen >= maxBufferLen);
	Assert(memoryLen >= BufferedReadMemoryLen(maxBufferLen, maxLargeReadLen));
	
	memset(bufferedRead, 0, sizeof(BufferedRead));

	/*
	 * Init level.
	 */
	relationNameLen = strlen(relationName);
	bufferedRead->relationName = (char *) palloc(relationNameLen + 1);
	memcpy(bufferedRead->relationName, relationName, relationNameLen + 1);

	/*
	 * Large-read memory level members.
	 */
	bufferedRead->maxBufferLen = maxBufferLen;
    bufferedRead->maxLargeReadLen = maxLargeReadLen;

	bufferedRead->memory = memory;
    bufferedRead->memoryLen = memoryLen;

    bufferedRead->beforeBufferMemory = memory;
	bufferedRead->largeReadMemory =
						&memory[maxBufferLen];

	bufferedRead->largeReadPosition = 0;
	bufferedRead->largeReadLen = 0;
	
	/*
	 * Buffer level members.
	 */	
	bufferedRead->bufferOffset = 0;
	bufferedRead->bufferLen = 0;

	/*
	 * File level members.
	 */
	bufferedRead->file = -1;
    bufferedRead->fileLen = 0;
	bufferedRead->splitLen = 0;

	/*
	 * Temporary limit support for random reading.
	 */
	bufferedRead->haveTemporaryLimitInEffect = false;
	bufferedRead->temporaryLimitFileLen = 0;
}

/*
 * Takes an open file handle for the next file.
 */
void BufferedReadSetFile(
    BufferedRead       *bufferedRead,
    File 				file,
    char				*filePathName,
    int64				splitLen,
    int64               fileLen)
{
	Assert(bufferedRead != NULL);
	
	// Assert(bufferedRead->file == -1);
	// Assert(bufferedRead->fileLen == 0);
		
    /* Assert(bufferedRead->largeReadPosition == 0); */
    // Assert(bufferedRead->largeReadLen == 0);

    // Assert(bufferedRead->bufferOffset == 0);
    // Assert(bufferedRead->bufferLen == 0);

	Assert(file >= 0);
	Assert(fileLen >= 0);
	Assert(splitLen >= 0);
	
	bufferedRead->file = file;
    bufferedRead->filePathName = filePathName;
    bufferedRead->fileLen = fileLen;
	bufferedRead->splitLen = splitLen;

	bufferedRead->haveTemporaryLimitInEffect = false;
	bufferedRead->temporaryLimitFileLen = 0;

    int64 real_fileLen = fileLen - bufferedRead->largeReadPosition;
	if (real_fileLen > 0)
	{
		/*
		 * Do the first read.
		 */
		if (real_fileLen > bufferedRead->maxLargeReadLen)
			bufferedRead->largeReadLen = bufferedRead->maxLargeReadLen;
		else
			bufferedRead->largeReadLen = (int32)real_fileLen;
		BufferedReadIo(bufferedRead);
	}
}

/*
 * Perform a large read i/o.
 */
static void BufferedReadIo(
    BufferedRead        *bufferedRead)
{
	int32 largeReadLen;
	uint8 *largeReadMemory;
	int32 offset;

	largeReadLen = bufferedRead->largeReadLen;
	Assert(bufferedRead->largeReadLen > 0);
	largeReadMemory = bufferedRead->largeReadMemory;

#ifdef USE_ASSERT_CHECKING
	{
		int64 currentReadPosition; 
		
		currentReadPosition = FileNonVirtualTell(bufferedRead->file);
		if (currentReadPosition < 0)
			ereport(ERROR, (errcode_for_file_access(),
							errmsg("unable to get current position for table \"%s\" in file \"%s\" (errcode %d)",
								   bufferedRead->relationName,
							       bufferedRead->filePathName,
								   errno),
						    errdetail("%s", HdfsGetLastError())));
			
		if (currentReadPosition != bufferedRead->largeReadPosition)
		{
			ereport(ERROR, (errcode_for_file_access(),
							errmsg("Current position mismatch actual "
								   INT64_FORMAT ", expected " INT64_FORMAT " for table \"%s\" in file \"%s\"",
								   currentReadPosition, bufferedRead->largeReadPosition,
								   bufferedRead->relationName,
								   bufferedRead->filePathName),
						    errdetail("%s", HdfsGetLastError())));
		}
	}
#endif

	offset = 0;
	while (largeReadLen > 0) 
	{
		int actualLen = FileRead(
							bufferedRead->file,
							(char*)largeReadMemory,
							largeReadLen);

		if (actualLen == 0) 
			ereport(ERROR, (errcode_for_file_access(),
							errmsg("read beyond eof in table \"%s\" in file \"%s\"",
								   bufferedRead->relationName,
							       bufferedRead->filePathName)));
		else if (actualLen < 0)
			ereport(ERROR, (errcode_for_file_access(),
							errmsg("unable to read table \"%s\" file \"%s\" (errcode %d)", 
								   bufferedRead->relationName,
								   bufferedRead->filePathName,
								   errno),
						    errdetail("%s", HdfsGetLastError())));
		
		if (Debug_appendonly_print_read_block)
		{
			elog(LOG,
				 "Append-Only storage read: table '%s', segment file '%s', read postition " INT64_FORMAT " (small offset %d), "
				 "actual read length %d (equals large read length %d is %s)",
				 bufferedRead->relationName,
				 bufferedRead->filePathName,
				 bufferedRead->largeReadPosition,
				 offset,
				 actualLen,
				 bufferedRead->largeReadLen,
				 (actualLen == bufferedRead->largeReadLen ? "true" : "false"));
		}
		
		largeReadLen -= actualLen;
		largeReadMemory += actualLen;
		offset += actualLen;
	}
}

static uint8 *BufferedReadUseBeforeBuffer(
    BufferedRead       *bufferedRead,
    int32              maxReadAheadLen,
    int32              *nextBufferLen,
    bool 				isUseSplitLen)
{
	int64 inEffectFileLen;
	int64 nextPosition;
	int64 remainingFileLen;
	int32 nextReadLen;
	int32 beforeLen;
	int32 beforeOffset;
	int32 extraLen;

	Assert(bufferedRead->largeReadLen - bufferedRead->bufferOffset > 0);
	
	if (bufferedRead->haveTemporaryLimitInEffect)
		inEffectFileLen = bufferedRead->temporaryLimitFileLen;
	else if(isUseSplitLen)
		inEffectFileLen = bufferedRead->splitLen;
	else
		inEffectFileLen = bufferedRead->fileLen;

	/*
	 * Requesting more data than in the current read.
	 */		
	nextPosition = bufferedRead->largeReadPosition + bufferedRead->largeReadLen;
	
	if (nextPosition == inEffectFileLen)
	{
		/*
		 * No more file to read.
		 */
		bufferedRead->bufferLen = bufferedRead->largeReadLen -
								  bufferedRead->bufferOffset;
		Assert(bufferedRead->bufferLen > 0);
		
		*nextBufferLen = bufferedRead->bufferLen;
		return &bufferedRead->largeReadMemory[bufferedRead->bufferOffset];
	}

	remainingFileLen = inEffectFileLen - 
	                   nextPosition;
	if (remainingFileLen > bufferedRead->maxLargeReadLen)
		nextReadLen = bufferedRead->maxLargeReadLen;
	else
		nextReadLen = (int32)remainingFileLen;
	
	Assert(nextReadLen >= 0);

	beforeLen = bufferedRead->maxLargeReadLen - bufferedRead->bufferOffset;
	beforeOffset = bufferedRead->maxBufferLen - beforeLen;
	
	/*
	 * Copy data from the current large-read buffer into the before memory.
	 */
	memcpy(&bufferedRead->beforeBufferMemory[beforeOffset],
	       &bufferedRead->largeReadMemory[bufferedRead->bufferOffset],
	       beforeLen);

	/*
	 * Do the next read.
	 */
	bufferedRead->largeReadPosition = nextPosition;
	bufferedRead->largeReadLen = nextReadLen;
	
	/*
	 * MPP-17061: nextReadLen should never be 0, since the code will return above
	 * if inEffectFileLen is equal to nextPosition.
	 */
	if (nextReadLen == 0)
	{
		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
				errmsg("Unexpected internal error,"
				" largeReadLen is set to 0 before calling BufferedReadIo." 
				" remainingFileLen is " INT64_FORMAT 
				" inEffectFileLen is " INT64_FORMAT 
				" nextPosition is " INT64_FORMAT, 
				remainingFileLen, inEffectFileLen, nextPosition)));
	}
	
	BufferedReadIo(bufferedRead);

	extraLen = maxReadAheadLen - beforeLen;
	Assert(extraLen > 0);
	if (extraLen > nextReadLen)
		extraLen = (int32)nextReadLen;

	/*
	 * Return a buffer using a negative offset that starts in the
	 * before memory and goes into the large-read memory.
	 */
	bufferedRead->bufferOffset = -beforeLen;
	bufferedRead->bufferLen = beforeLen + extraLen;
	Assert(bufferedRead->bufferLen > 0);
	
	*nextBufferLen = bufferedRead->bufferLen;

	return &bufferedRead->beforeBufferMemory[beforeOffset];
}

/*
 * Set a temporary read range in the current open segment file.
 *
 * The beginFileOffset must be to the beginning of an Append-Only Storage block.
 *
 * The afterFileOffset serves as the temporary EOF.  It will cause reads to return
 * false (no more blocks) when reached.  It must be at the end of an Append-Only Storage
 * block.
 *
 * When a read returns false (no more blocks), the temporary read range is forgotten.
 */
void BufferedReadSetTemporaryRange(
    BufferedRead         *bufferedRead,
	int64				  beginFileOffset,
	int64				  afterFileOffset)
{
	bool	newReadNeeded;
	int64	largeReadAfterPos;

	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);

	/*
	 * Forget any current read buffer length (but not the offset!).
	 */
	bufferedRead->bufferLen = 0;

	newReadNeeded = false;
	largeReadAfterPos = bufferedRead->largeReadPosition +
						bufferedRead->largeReadLen;
	if (bufferedRead->bufferOffset < 0)
	{
		int64	virtualLargeReadBeginPos;
		
		virtualLargeReadBeginPos = bufferedRead->largeReadPosition +
								   bufferedRead->bufferOffset;

		if (beginFileOffset >= virtualLargeReadBeginPos &&
			beginFileOffset < largeReadAfterPos)
		{
			/*
			 * Our temporary read begin position is within our before buffer and
			 * current read.
			 */
			bufferedRead->bufferOffset = 
								(int32)(beginFileOffset -
										bufferedRead->largeReadPosition);
		}
		else
			newReadNeeded = true;
	}
	else
	{
		if (beginFileOffset >= bufferedRead->largeReadPosition &&
			beginFileOffset < largeReadAfterPos)
		{
			/*
			 * Our temporary read begin position is within our current read.
			 */
			bufferedRead->bufferOffset = 
								(int32)(beginFileOffset -
										bufferedRead->largeReadPosition);
		}
		else
		{
			newReadNeeded = true;
		}
	}

	if (newReadNeeded)
	{
		int64	remainingFileLen;

		/* 
		 * Seek to the requested beginning position. 
		 * MPP-17061: allow seeking backward(negative offset) in file,
		 * this could happen during index scan, if we do look up for a
		 * block directory entry at the end of the segment file, followed
		 * by a look up for a block directory entry at the beginning of file.
		 */
			int64 seekOffset = beginFileOffset - largeReadAfterPos;
			int64 seekPos = FileSeek(bufferedRead->file, seekOffset, SEEK_CUR);
			if (seekPos != beginFileOffset)
				ereport(ERROR, (errcode_for_file_access(),
							errmsg("unable to seek to position for table \"%s\" in file \"%s\" (errcode %d):%m",
									   bufferedRead->relationName,
									   bufferedRead->filePathName,
									   errno),
						    errdetail("%s", HdfsGetLastError())));

		bufferedRead->bufferOffset = 0;

		remainingFileLen = afterFileOffset - beginFileOffset;
		if (remainingFileLen > bufferedRead->maxLargeReadLen)
			bufferedRead->largeReadLen = bufferedRead->maxLargeReadLen;
		else
			bufferedRead->largeReadLen = (int32)remainingFileLen;

		bufferedRead->largeReadPosition = beginFileOffset;

		if (bufferedRead->largeReadLen > 0)
			BufferedReadIo(bufferedRead);
	}

	bufferedRead->haveTemporaryLimitInEffect = true;
	bufferedRead->temporaryLimitFileLen = afterFileOffset;
	
}

/*
 * Return the position of the next read in bytes.
 */
int64 
BufferedReadNextBufferPosition(
    BufferedRead       *bufferedRead)
{
	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);

	/*
	 * Note that the bufferOffset can be negative when we are using the
	 * before buffer, but that is ok.  We should get an accurate
	 * next position.
	 */
	return bufferedRead->largeReadPosition + 
		   bufferedRead->bufferOffset + 
		   bufferedRead->bufferLen;
}

/*
 * Get the next buffer space for reading with a specified max read-ahead
 * amount.
 *
 * Returns NULL when the current file has been completely read.
 */
uint8 *BufferedReadGetNextBuffer(
    BufferedRead       *bufferedRead,
    int32              maxReadAheadLen,
    int32              *nextBufferLen,
    bool				isUseSplitLen)
{
	int64	inEffectFileLen;

	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);
	Assert(maxReadAheadLen > 0);
	Assert(nextBufferLen != NULL);
	if (maxReadAheadLen > bufferedRead->maxBufferLen)
	{
		Assert(maxReadAheadLen <= bufferedRead->maxBufferLen);
		
		elog(ERROR, "Read ahead length %d is greater than maximum buffer length %d",
		     maxReadAheadLen, bufferedRead->maxBufferLen);
	}

	if (bufferedRead->haveTemporaryLimitInEffect)
		inEffectFileLen = bufferedRead->temporaryLimitFileLen;
	else if(isUseSplitLen)
		inEffectFileLen = bufferedRead->splitLen;
	else
		inEffectFileLen = bufferedRead->fileLen;

	Assert(inEffectFileLen!=-1 && inEffectFileLen>=0);
	/*
	 * Finish previous buffer.
	 */
	bufferedRead->bufferOffset += bufferedRead->bufferLen;
	bufferedRead->bufferLen = 0;

	if (bufferedRead->largeReadPosition == inEffectFileLen
        // when the previous call isUseSplitLen is true, while this call is false
        || bufferedRead->largeReadPosition == bufferedRead->fileLen)
	{
		/*
		 * At end of file.
		 */
		*nextBufferLen = 0;
		bufferedRead->haveTemporaryLimitInEffect = false;
		return NULL;
	}
	
	/*
	 * Any more left in current read?
	 */
	if (bufferedRead->bufferOffset == bufferedRead->largeReadLen)
	{
		int64 remainingFileLen=0;
	
		/*
		 * Used exactly all of it.  Attempt read more.
		 */
		bufferedRead->largeReadPosition += bufferedRead->largeReadLen;
		bufferedRead->bufferOffset = 0;
		
        if (bufferedRead->largeReadPosition == bufferedRead->fileLen) {
            // when the previous call isUseSplitLen is true, while this call is false
            remainingFileLen = 0;
        }else{
            remainingFileLen = inEffectFileLen -
		                   bufferedRead->largeReadPosition;
        }
        
		if (remainingFileLen > bufferedRead->maxLargeReadLen)
			bufferedRead->largeReadLen = bufferedRead->maxLargeReadLen;
		else
			bufferedRead->largeReadLen = (int32)remainingFileLen;
		
        if (bufferedRead->largeReadLen == 0)
		{
			/*
			 * At end of file.
			 */
			*nextBufferLen = 0;
			bufferedRead->haveTemporaryLimitInEffect = false;
			return NULL;
		}

		BufferedReadIo(bufferedRead);

		if (maxReadAheadLen > bufferedRead->largeReadLen)
			bufferedRead->bufferLen = bufferedRead->largeReadLen;
		else
			bufferedRead->bufferLen = maxReadAheadLen;

		Assert(bufferedRead->bufferOffset == 0);
		Assert(bufferedRead->bufferLen > 0);

		*nextBufferLen = bufferedRead->bufferLen;
		return bufferedRead->largeReadMemory;
	}

	if (bufferedRead->bufferOffset + maxReadAheadLen > bufferedRead->largeReadLen)
	{
		/*
		 * Odd boundary.  Use before memory to carry us over.
		 */
		Assert(bufferedRead->largeReadLen - bufferedRead->bufferOffset > 0);
	
		return BufferedReadUseBeforeBuffer(
									bufferedRead, 
									maxReadAheadLen,
									nextBufferLen,
									isUseSplitLen);
	}

	/*
	 * We can satisify request from current read.
	 */
	bufferedRead->bufferLen = maxReadAheadLen;	
	Assert(bufferedRead->bufferLen > 0);

	*nextBufferLen = bufferedRead->bufferLen;
	return &bufferedRead->largeReadMemory[bufferedRead->bufferOffset];
}

/*
 * Get the next, maximum buffer space for reading.
 *
 * Returns NULL when the current file has been completely read.
 */
uint8 *BufferedReadGetMaxBuffer(
    BufferedRead       *bufferedRead,
    int32              *nextBufferLen)
{
	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);
	Assert(nextBufferLen != NULL);

	return BufferedReadGetNextBuffer(
							bufferedRead,
							bufferedRead->maxBufferLen,
							nextBufferLen,
							true);
}

/*
 * Grow the available length of the current buffer.
 *
 * NOTE: The buffer address returned can be different, even for previously
 * examined buffer data.  In other words, don't keep buffer pointers in
 * the buffer region.  Use offsets to re-establish pointers after this call.
 *
 * If the current file has been completely read, bufferLen will remain
 * the current value.
 */
uint8 *BufferedReadGrowBuffer(
    BufferedRead       *bufferedRead,
    int32              newMaxReadAheadLen,
    int32              *growBufferLen,
    bool 				isUseSplitLen)
{
	int32 originalBufferLen;
	int32 newNextOffset;

	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);
	Assert(newMaxReadAheadLen > bufferedRead->bufferLen);
	Assert(newMaxReadAheadLen <= bufferedRead->maxBufferLen);
	Assert(growBufferLen != NULL);

	originalBufferLen = bufferedRead->bufferLen;
	
	newNextOffset = bufferedRead->bufferOffset + newMaxReadAheadLen;
    if (newNextOffset > bufferedRead->largeReadLen)
	{
		/*
		 * Odd boundary.  Use before memory to carry us over.
		 */
		Assert(bufferedRead->largeReadLen - bufferedRead->bufferOffset > 0);
	
		return BufferedReadUseBeforeBuffer(
									bufferedRead, 
									newMaxReadAheadLen,
									growBufferLen,
									isUseSplitLen);
	}

	/*
	 * There is maxReadAheadLen more left in current large-read memory.
	 */
	bufferedRead->bufferLen = newMaxReadAheadLen;
	Assert(bufferedRead->bufferLen > 0);
	
	*growBufferLen = bufferedRead->bufferLen;
	return &bufferedRead->largeReadMemory[bufferedRead->bufferOffset];
}

/*
 * Return the address of the current read buffer.
 */
uint8 *BufferedReadGetCurrentBuffer(
    BufferedRead       *bufferedRead)
{
	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);
	
	return &bufferedRead->largeReadMemory[bufferedRead->bufferOffset];
}

/*
 * Return the current buffer's start position.
 */
int64 BufferedReadCurrentPosition(
    BufferedRead       *bufferedRead)
{
	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);

	return bufferedRead->largeReadPosition + bufferedRead->bufferOffset;
}

/*
 * Flushes the current file for append.  Caller is resposible for closing
 * the file afterwards.
 *
 */
void BufferedReadCompleteFile(
    BufferedRead       *bufferedRead)
{
	Assert(bufferedRead != NULL);
	Assert(bufferedRead->file >= 0);

	bufferedRead->file = -1;
	bufferedRead->filePathName = NULL;
	bufferedRead->fileLen = 0;

	bufferedRead->bufferOffset = 0;
	bufferedRead->bufferLen = 0;

	bufferedRead->largeReadPosition = 0;
	bufferedRead->largeReadLen = 0;
}


/*
 * Finish with reading all together.
 */
void BufferedReadFinish(BufferedRead *bufferedRead)
{
	Assert(bufferedRead != NULL);

	//Assert(bufferedRead->file == -1);
	Assert(bufferedRead->fileLen == 0);

	Assert(bufferedRead->bufferOffset == 0);
	Assert(bufferedRead->bufferLen == 0);	

	if(bufferedRead->memory)
	{
		pfree(bufferedRead->memory);
		bufferedRead->memory = NULL;
		bufferedRead->memoryLen = 0; 
	}

	if (bufferedRead->relationName != NULL)
	{
		pfree(bufferedRead->relationName);
		bufferedRead->relationName = NULL;
	}
}
