/*
 * 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);
}
示例#2
0
// 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;
}
示例#3
0
void
Dbtup::scanCont(Signal* signal, ScanOpPtr scanPtr)
{
  bool immediate = scanNext(signal, scanPtr);
  if (! immediate) {
    jam();
    // time-slicing again
    return;
  }
  scanReply(signal, scanPtr);
}
示例#4
0
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);
}
示例#5
0
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;
}
示例#6
0
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;
}