/* * 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; }
/* * 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 = <s->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, <->currBlk); lt->currPos.blkNum = lt->firstBlkNum; lt->currPos.offset = 0; return lts; }
/* * 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))); } }