/* * Move list of scans away from entry about to be removed. Uses scan * method scanNext(). */ void Dbtux::moveScanList(NodeHandle& node, unsigned pos) { ScanOpPtr scanPtr; scanPtr.i = node.getNodeScan(); do { jam(); c_scanOpPool.getPtr(scanPtr); TreePos& scanPos = scanPtr.p->m_scanPos; const Uint32 nextPtrI = scanPtr.p->m_nodeScan; ndbrequire(scanPos.m_loc == node.m_loc); if (scanPos.m_pos == pos) { jam(); #ifdef VM_TRACE if (debugFlags & DebugScan) { debugOut << "Move scan " << scanPtr.i << " " << *scanPtr.p << endl; debugOut << "At pos=" << pos << " " << node << endl; } #endif scanNext(scanPtr, true); ndbrequire(! (scanPos.m_loc == node.m_loc && scanPos.m_pos == pos)); } scanPtr.i = nextPtrI; } while (scanPtr.i != RNIL); }
// scan the next record and also return the actual record const Status HeapFileScan::scanNext(RID& outRid, Record& rec) { Status status; if ((status = scanNext(outRid)) != OK) return status; if ((status = getRecord(outRid, rec)) != OK) return status; return OK; }
void Dbtup::scanCont(Signal* signal, ScanOpPtr scanPtr) { bool immediate = scanNext(signal, scanPtr); if (! immediate) { jam(); // time-slicing again return; } scanReply(signal, scanPtr); }
void Dbtup::execACC_CHECK_SCAN(Signal* signal) { jamEntry(); const AccCheckScan reqCopy = *(const AccCheckScan*)signal->getDataPtr(); const AccCheckScan* const req = &reqCopy; ScanOpPtr scanPtr; c_scanOpPool.getPtr(scanPtr, req->accPtr); ScanOp& scan = *scanPtr.p; // fragment FragrecordPtr fragPtr; fragPtr.i = scan.m_fragPtrI; ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord); Fragrecord& frag = *fragPtr.p; if (req->checkLcpStop == AccCheckScan::ZCHECK_LCP_STOP) { jam(); signal->theData[0] = scan.m_userPtr; signal->theData[1] = true; EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2); jamEntry(); return; } if (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) { jam(); // LQH asks if we are waiting for lock and we tell it to ask again NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend(); conf->scanPtr = scan.m_userPtr; conf->accOperationPtr = RNIL; // no tuple returned conf->fragId = frag.fragmentId; unsigned signalLength = 3; // if TC has ordered scan close, it will be detected here sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF, signal, signalLength, JBB); return; // stop } if (scan.m_state == ScanOp::First) { jam(); scanFirst(signal, scanPtr); } if (scan.m_state == ScanOp::Next) { jam(); bool immediate = scanNext(signal, scanPtr); if (! immediate) { jam(); // time-slicing via TUP or PGMAN return; } } scanReply(signal, scanPtr); }
void *map(struct ThreadData *td) { int uid = rand() % 50 + 100; //printf("[%d][STARTED] %d-%d\n", uid, td->start, td-> end); FILE *fp; char *readWord = NULL; char c; fp = fopen("input.txt", "r"); if (fp == NULL) { printf("Could not open input file.\n"); } else { fseek(fp, td->start, SEEK_SET); c = fgetc(fp); fseek(fp, td->start, SEEK_SET); if (isspace(c)) { printf("era un espacio nomas...\n"); } else { if (td->start > 0) { skipFirst(&fp, uid); } } int result; while(!feof(fp) && ftell(fp) <= td->end + 1) { scanNext(&readWord, &fp, uid); if (readWord) { pthread_mutex_lock(td->mutex); //readWord[strlen(readWord)] = '\n'; result = write(td->fd[1], readWord, (strlen(readWord) + 1)); printf("(%d) -> %s (@%d)\n", uid, readWord, ftell(fp)); free(readWord); //if (result != 1){ // perror("write"); //} } } fclose(fp); } pthread_mutex_lock(td->mutex); write(td->fd[1], "FINISHED", 9); //printf("[%d][FINISHED]\n", uid); pthread_exit(NULL); return NULL; }
const Status Index::insertEntry(const void *value, RID rid) { Bucket* bucket; Status status; Bucket *newBucket; int newPageNo; char data[PAGESIZE*2]; int counter; int index; // If the 'unique' flag is set, scan the index to see if the // <attribute, rid> pair already exists if (headerPage->unique == UNIQUE) { RID outRid; if((status = startScan(value)) != OK) return status; while ((status = scanNext(outRid)) != NOMORERECS) { if (status != OK) return status; if (!memcmp(&outRid, &rid, sizeof(RID))) return NONUNIQUEENTRY; } if((status = endScan()) != OK) return status; } // Get the bucket containing the entry into buffer pool status = hashIndex(value, index); int pageNo = headerPage->dir[index]; #ifdef DEBUGIND cout << "Inserting entry " << *(int*)value << " to bucket " << pageNo << endl; #endif status = bufMgr->readPage(file, pageNo, (Page*&)bucket); if (status != OK) return status; // the bucket needs to be splitted if the number of entries // on the bucket equals the maximum if (bucket->slotCnt == numSlots) { // splitting bucket // allocate a new bucket status = bufMgr->allocPage(file, newPageNo, (Page*&)newBucket); if (status != OK) return status; // Initialize this newly allocated bucket newBucket->depth = ++(bucket->depth); newBucket->slotCnt = 0; // Copy all (value, rid) pairs in the old bucket and the new // entry to a temporary area memcpy(data, bucket->data, numSlots*recSize); memcpy(&(data[numSlots*recSize]), value, headerPage->length); memcpy(&(data[numSlots*recSize + headerPage->length]), &rid, sizeof(RID)); counter = bucket->slotCnt + 1; bucket->slotCnt = 0; // the directory needs to be doubled if the depth of the bucket // being splitted equals the depth of the directory if (bucket->depth > headerPage->depth) { // doubling directory // The directory is doubled and the lower half of the directory // is copied to the upper half int newDirSize = 2 * dirSize; if (newDirSize > DIRSIZE) return DIROVERFLOW; for (int i = 0; i < dirSize; i++) headerPage->dir[i + dirSize] = headerPage->dir[i]; dirSize = newDirSize; (headerPage->depth)++; headerPage->dir[index + (1 << (bucket->depth - 1))] = newPageNo; } else { // reset the appropriate directories to the new bucket int oldindex = index % (1 << (bucket->depth - 1)); int newindex = oldindex + (1 << (bucket->depth - 1)); for (int j = 0; j < dirSize; j++) if ((j % (1 << (bucket->depth))) == newindex) headerPage->dir[j] = newPageNo; } #ifdef DEBUGIND printDir(); #endif // call insertEntry recursively to insert all (value, rid) // pairs in the temporary area to the index for (int k = 0; k < counter; k++) { value = &(data[k * recSize]); rid = * ((RID *)((char *)value + headerPage->length)); status = insertEntry(value, rid); if (status != OK) return status; } status = bufMgr->unPinPage(file, newPageNo, true); if (status != OK) return status; } else { // There is sufficient free space in the bucket. Insert (value, rid) here int offset = (bucket->slotCnt) * recSize; memcpy(&(bucket->data[offset]), value, headerPage->length); memcpy(&(bucket->data[offset+headerPage->length]), &rid, sizeof(RID)); (bucket->slotCnt)++; } status = bufMgr->unPinPage(file, pageNo, true); return status; }