예제 #1
0
/*
 * Do a byte-by-byte comparison between a given plan and a saved one.
 *
 * Returns true if identical, false otherwise
 *
 */
static bool
workfile_mgr_compare_plan(workfile_set *work_set, workfile_set_plan *sf_plan)
{
	Assert(NULL != work_set);
	Assert(NULL != sf_plan);

	ExecWorkFile *plan_file = workfile_mgr_open_fileno(work_set, WORKFILE_NUM_ALL_PLAN);
	elog(gp_workfile_caching_loglevel, "Loading and comparing query plan from file %s",
			ExecWorkFile_GetFileName(plan_file));

	if (plan_file == NULL)
	{
		elog(gp_workfile_caching_loglevel, "could not open plan file for matching for set %s",
				work_set->path);
		return false;
	}

	char buffer[BLCKSZ];
	uint64 plan_offset = 0;
	bool match = false;

	while (true)
	{
		uint64 size_read = ExecWorkFile_Read(plan_file, buffer, sizeof(buffer));

		if (plan_offset + size_read > sf_plan->serialized_plan_len)
		{
			/* Disk plan is larger than new plan. No match */
			break;
		}

		if (size_read < sizeof(buffer) &&
				plan_offset + size_read < sf_plan->serialized_plan_len)
		{
			/* Disk plan is smaller than new plan. No match */
			break;
		}

		/* We have enough data in memory to compare */
		char *plan_pointer = ((char *) sf_plan->serialized_plan ) + plan_offset;
		if ( memcmp(buffer, plan_pointer, size_read) != 0)
		{
			break;
		}

		/* Reached the end of both streams, with no miss-match */
		if (size_read < sizeof(buffer))
		{
			match = true;
			break;
		}
		plan_offset += size_read;
	}

	workfile_mgr_close_file(work_set, plan_file);
	return match;
}
예제 #2
0
파일: logtape.c 프로젝트: BenjaminYu/gpdb
/*
 * Loads the state of a LogicaTapeSet from a BufFile
 *
 *   statefile is an open ExecWorkFile containing the state of the LogicalTapeSet
 *   tapefile is an open ExecWorkfile containing the tapeset
 */
LogicalTapeSet *
LoadLogicalTapeSetState(ExecWorkFile *statefile, ExecWorkFile *tapefile)
{
	Assert(NULL != statefile);
	Assert(NULL != tapefile);

	LogicalTapeSet *lts;
	LogicalTape *lt;
	size_t readSize;

	lts = (LogicalTapeSet *) palloc(sizeof(LogicalTapeSet));
	lts->pfile = tapefile;
	lts->nTapes = 1;
	lt = &lts->tapes[0];

	readSize = ExecWorkFile_Read(statefile, &(lts->nFileBlocks), sizeof(lts->nFileBlocks));
	if(readSize != sizeof(lts->nFileBlocks))
		elog(ERROR, "Load logicaltapeset failed to read nFileBlocks");

	/* For loaded tape, we will read only and do not care about free space */
	lts->forgetFreeSpace = true;
	lts->blocksSorted = true;
	lts->freeBlocks = NULL;
	lts->nFreeBlocks = 0;
	lts->freeBlocksLen = 0;

	lt->writing = false;
	lt->frozen = true;

	readSize = ExecWorkFile_Read(statefile, &(lt->firstBlkNum), sizeof(lt->firstBlkNum));
	if(readSize != sizeof(lt->firstBlkNum))
		elog(ERROR, "Load logicaltapeset failed to read tape firstBlkNum");

	if(lt->firstBlkNum != -1)
		ltsReadBlock(lts, lt->firstBlkNum, &lt->currBlk);

	lt->currPos.blkNum = lt->firstBlkNum;
	lt->currPos.offset = 0;

	return lts;
}
예제 #3
0
파일: logtape.c 프로젝트: BenjaminYu/gpdb
/*
 * Read a block-sized buffer from the specified block of the underlying file.
 *
 * No need for an error return convention; we ereport() on any error.	This
 * module should never attempt to read a block it doesn't know is there.
 */
static void
ltsReadBlock(LogicalTapeSet *lts, int64 blocknum, void *buffer)
{
	Assert(lts != NULL);
	if (ExecWorkFile_Seek(lts->pfile, blocknum * BLCKSZ, SEEK_SET) != 0 ||
			ExecWorkFile_Read(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
	{
		ereport(ERROR,
		/* XXX is it okay to assume errno is correct? */
				(errcode_for_file_access(),
				 errmsg("could not read block " INT64_FORMAT  " of temporary file: %m",
						blocknum)));
	}
}