Пример #1
0
////////////////////////////////////////////////////////////
// Push down any data from the old tree onto the new tree 
// by doing a traversal over the deleted clusters
//////////////////////////////////////////////////////////
void pushDown(cluster* cl)
{   
  cluster* ccl;
  int i;
  assert(cl);
 
  ccl = GET_CL(cl);  
  deprintf("pushDown: cl = %d\n",ccl->id);
 
  cluster** clusters = ccl->getClusters();
  for(i=0; i < MAX_DEGREE; ++i)
    {
      cluster* child = clusters[i];
      cluster* ccp = GET_CL(child);
      if(child) {
	pushDownFun(ccl,ccp);
	if(isDeleted(ccp)) {
	  if(ccp->child) {
	    deprintf("Child\n");
	    pushDown(child);
	    deprintf("ret\n");
	  }
	  freeCluster(ccp);
	}
      }
    }
  free(clusters);     
}
Пример #2
0
void setupNullaryVertexCluster (node* thisNode, int event, tree_t* tree, clusterList* rootList) 
{
  int i, k=0;
  unary_cluster *cll;
  
  final_cluster *cl = new (allocBlock(tree->UClusters)) final_cluster;
 
  drun(ucs++);

  cluster* oldCluster = thisNode->vertex->cl;
  if(oldCluster != NULL) 
    {
     
      if(PUSHDOWN) {
	 oldCluster->affected = DELETED;
	if(isRoot(oldCluster))
	  insertCluster(oldCluster,rootList);
      }
      else {
	freeVertexCluster(oldCluster,tree);
      }
    }
    
  thisNode->vertex->cl = cl;
  

  deprintf("Setting up cluster for node %d\n",thisNode->nId);
  deprintf("Cluster %p\n",cl);

  cl->id = thisNode->nId;
  cl->height = thisNode->height;


  // Make children cluster points to thisNode
  for(i = 0; i < MAX_DEGREE; i++) {
    cll = (unary_cluster *) GET_CL(thisNode->scars[i].cl);
    deprintf("i is %d \n",i);
    if(cll) {
      deprintf("cll exists\n");      
      cll->parent = cl;
      
      cl->unaryCl[k] = (unary_cluster *) thisNode->scars[i].cl;
      deprintf("Unary cluster %d is %p\n", k, cl->unaryCl[k]);
      k++;
      
    }
  }
  for(k=k;k<MAX_DEGREE;k++) {
    cl->unaryCl[k] = NULL;
  }

  // Make node data cluster points to this node
  cll = thisNode->data;
  cll->parent = cl;
  cl->child = cll;


  deprintf("Cl->id is %d\n",cl->id);
}
Пример #3
0
void setupBinVertexCluster (node* thisNode, int event,tree_t* tree, clusterList* rootList) 
{
  int i, j=0,k=0;
  cluster *cll;
  bin_cluster *cl;
 
  cluster* oldCluster = thisNode->vertex->cl;
  cl = new (allocBlock(tree->BClusters)) bin_cluster;
  drun(bcs++);

 
  if(oldCluster != NULL) {
    if(PUSHDOWN) {   
      oldCluster->affected = DELETED;
      if(isRoot(oldCluster))
	insertCluster(oldCluster,rootList);
    }
    else {
      freeVertexCluster(oldCluster,tree);
    }
  } 
  
  thisNode->vertex->cl = cl;
 
  deprintf("Setting up binary cluster %p\n",cl);
  cl->id = thisNode->nId;
  cl->height = thisNode->height;
  
  // Make children cluster points to thisNode
  for(i = 0; i < MAX_DEGREE; i++) {
    cll = (cluster *) GET_CL(thisNode->scars[i].cl);
    
    if(cll) {   
      
      cll->parent = cl;
      if(i == thisNode->left || i == thisNode->right) {
	cl->binaryCl[j] = (bin_cluster *) thisNode->scars[i].cl;
	j++;
      }
      else {
	cl->unaryCl[k] = (unary_cluster *) thisNode->scars[i].cl;
	k++;
      }
    }
  
  }
  for(k=k;k<MAX_DEGREE-2;k++) {
    cl->unaryCl[k] = NULL;
  }
  
  // Make node data cluster points to this node
  cll = thisNode->data;
  
  
  cll->parent = cl;
  cl->child = cll;
  
}
Пример #4
0
/* Find the clusters with the two largest distances from the distinguished endpints, adjusting for being in a subcluster
 */
void find2max(cluster* curcl, cluster** child, double* max2,int ep1,double w1,int ep2,double w2)
{
  int i;
  double max1;
  double effMax; 
  bin_cluster** binaryCl;
  unary_cluster** unaryCl;
 
  max1 = *max2 = 0;
  binaryCl = (bin_cluster**) curcl->getBinaryClusters();
  unaryCl = (unary_cluster**) curcl->getUnaryClusters();
  
  for (i = 0; i < curcl->endpoints; ++i) {
    bin_cluster* cl = binaryCl[i];
    if(cl) {
      bin_data* d = getBinData(cl);
      double mpath = getThisData(d);
      double len = getLen(d);
      
      deprintf("Binary cluster \n");
      if((GET_CL(cl))->isEndPoint(ep1))
	effMax = dmax(mpath,w1+len);
      else 
	effMax = dmax(mpath,w2+len);
      deprintf("mpath is %lf, len is %lf \n",mpath, len);
      deprintf("w1 is %lf, w2 is %lf, ep1 is %d, ep2 is %d\n",w1,w2,ep1,ep2);
      deprintf("i is %d, effMax is %lf, max1 is %lf\n", i, effMax,max1);
      if(effMax > max1) {*max2 = max1; *child = cl; max1 = effMax;}
      else if(effMax > *max2) {*max2 = effMax;}
    }
  }
 

  for(i=0;i<MAX_DEGREE-curcl->endpoints;i++) {
    unary_cluster* cl = unaryCl[i];
    if(cl) {
      double mpath = cl->data.mpath;
      effMax = mpath;
      deprintf("i is %d, effMax is %lf, max1 is %lf\n", i, effMax,max1);
      if(effMax > max1) {*max2 = max1; *child = cl; max1 = effMax;}
      else if(effMax > *max2) {*max2 = effMax;}
    }
  }
  
    
}
Пример #5
0
cluster* synchronizeClusterContract(cluster* cl)
{

  int i;
  cluster** clusters = cl->getClusters();
  for(i=0; i < MAX_DEGREE; ++i)
    {
      if(clusters[i]) {
	cluster* ccp = GET_CL(clusters[i]);
	deprintf("Child->affected is %d\n",ccp->affected);
	if(ccp->affected == IS_AFFECTED) {      
	  synchronizeClusterContract(ccp);	 
	}
      }
    }
  free(clusters);
  updateClusterContract(cl);
  return cl;
  
}
Пример #6
0
void BIOSCALL int13_cdemu(disk_regs_t r)
{
    // @TODO: a macro or a function for getting the EBDA segment
    uint16_t            ebda_seg=read_word(0x0040,0x000E);
    uint8_t             device, status;
    uint16_t            vheads, vspt, vcylinders;
    uint16_t            head, sector, cylinder, nbsectors;
    uint32_t            vlba, ilba, slba, elba;
    uint16_t            before, segment, offset;
    cdb_atapi           atapicmd;
    cdemu_t __far       *cdemu;
    bio_dsk_t __far     *bios_dsk;

    cdemu    = ebda_seg :> &EbdaData->cdemu;
    bios_dsk = ebda_seg :> &EbdaData->bdisk;

    BX_DEBUG_INT13_ET("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES);

    /* at this point, we are emulating a floppy/harddisk */

    // Recompute the device number
    device  = cdemu->controller_index * 2;
    device += cdemu->device_spec;

    SET_DISK_RET_STATUS(0x00);

    /* basic checks : emulation should be active, dl should equal the emulated drive */
    if (!cdemu->active || (cdemu->emulated_drive != GET_DL())) {
        BX_INFO("%s: function %02x, emulation not active for DL= %02x\n", __func__, GET_AH(), GET_DL());
        goto int13_fail;
    }

    switch (GET_AH()) {

    case 0x00: /* disk controller reset */
        if (pktacc[bios_dsk->devices[device].type])
        {
            status = softrst[bios_dsk->devices[device].type](device);
        }
        goto int13_success;
        break;
    // all those functions return SUCCESS
    case 0x09: /* initialize drive parameters */
    case 0x0c: /* seek to specified cylinder */
    case 0x0d: /* alternate disk reset */  // FIXME ElTorito Various. should really reset ?
    case 0x10: /* check drive ready */     // FIXME ElTorito Various. should check if ready ?
    case 0x11: /* recalibrate */
    case 0x14: /* controller internal diagnostic */
    case 0x16: /* detect disk change */
        goto int13_success;
        break;

    // all those functions return disk write-protected
    case 0x03: /* write disk sectors */
    case 0x05: /* format disk track */
        SET_AH(0x03);
        goto int13_fail_noah;
        break;

    case 0x01: /* read disk status */
        status=read_byte(0x0040, 0x0074);
        SET_AH(status);
        SET_DISK_RET_STATUS(0);

        /* set CF if error status read */
        if (status)
            goto int13_fail_nostatus;
        else
            goto int13_success_noah;
        break;

    case 0x02: // read disk sectors
    case 0x04: // verify disk sectors
        vspt       = cdemu->vdevice.spt;
        vcylinders = cdemu->vdevice.cylinders;
        vheads     = cdemu->vdevice.heads;
        ilba       = cdemu->ilba;

        sector    = GET_CL() & 0x003f;
        cylinder  = (GET_CL() & 0x00c0) << 2 | GET_CH();
        head      = GET_DH();
        nbsectors = GET_AL();
        segment   = ES;
        offset    = BX;

        BX_DEBUG_INT13_ET("%s: read to %04x:%04x @ VCHS %u/%u/%u (%u sectors)\n", __func__,
                          ES, BX, cylinder, head, sector, nbsectors);

        // no sector to read ?
        if(nbsectors==0)
            goto int13_success;

        // sanity checks sco openserver needs this!
        if ((sector   >  vspt)
          || (cylinder >= vcylinders)
          || (head     >= vheads)) {
            goto int13_fail;
        }

        // After validating the input, verify does nothing
        if (GET_AH() == 0x04)
            goto int13_success;

        segment = ES+(BX / 16);
        offset  = BX % 16;

        // calculate the virtual lba inside the image
        vlba=((((uint32_t)cylinder*(uint32_t)vheads)+(uint32_t)head)*(uint32_t)vspt)+((uint32_t)(sector-1));

        // In advance so we don't lose the count
        SET_AL(nbsectors);

        // start lba on cd
        slba   = (uint32_t)vlba / 4;
        before = (uint32_t)vlba % 4;

        // end lba on cd
        elba = (uint32_t)(vlba + nbsectors - 1) / 4;

        _fmemset(&atapicmd, 0, sizeof(atapicmd));
        atapicmd.command = 0x28;    // READ 10 command
        atapicmd.lba     = swap_32(ilba + slba);
        atapicmd.nsect   = swap_16(elba - slba + 1);

        bios_dsk->drqp.nsect   = nbsectors;
        bios_dsk->drqp.sect_sz = 512;

        bios_dsk->drqp.skip_b = before * 512;
        bios_dsk->drqp.skip_a = ((4 - nbsectors % 4 - before) * 512) % 2048;

        status = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset));

        bios_dsk->drqp.skip_b = 0;
        bios_dsk->drqp.skip_a = 0;

        if (status != 0) {
            BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status);
            SET_AH(0x02);
            SET_AL(0);
            goto int13_fail_noah;
        }

        goto int13_success;
        break;

    case 0x08: /* read disk drive parameters */
        vspt       = cdemu->vdevice.spt;
        vcylinders = cdemu->vdevice.cylinders - 1;
        vheads     = cdemu->vdevice.heads - 1;

        SET_AL( 0x00 );
        SET_BL( 0x00 );
        SET_CH( vcylinders & 0xff );
        SET_CL((( vcylinders >> 2) & 0xc0) | ( vspt  & 0x3f ));
        SET_DH( vheads );
        SET_DL( 0x02 );   // FIXME ElTorito Various. should send the real count of drives 1 or 2
                          // FIXME ElTorito Harddisk. should send the HD count

        switch (cdemu->media) {
        case 0x01: SET_BL( 0x02 ); break;   /* 1.2 MB  */
        case 0x02: SET_BL( 0x04 ); break;   /* 1.44 MB */
        case 0x03: SET_BL( 0x05 ); break;   /* 2.88 MB */
        }

        /* Only set the DPT pointer for emulated floppies. */
        if (cdemu->media < 4) {
            DI = (uint16_t)&diskette_param_table;   // @todo: should this depend on emulated medium?
            ES = 0xF000;                            // @todo: how to make this relocatable?
        }
        goto int13_success;
        break;

    case 0x15: /* read disk drive size */
        // FIXME ElTorito Harddisk. What geometry to send ?
        SET_AH(0x03);
        goto int13_success_noah;
        break;

    // all those functions return unimplemented
    case 0x0a: /* read disk sectors with ECC */
    case 0x0b: /* write disk sectors with ECC */
    case 0x18: /* set media type for format */
    case 0x41: // IBM/MS installation check
      // FIXME ElTorito Harddisk. Darwin would like to use EDD
    case 0x42: // IBM/MS extended read
    case 0x43: // IBM/MS extended write
    case 0x44: // IBM/MS verify sectors
    case 0x45: // IBM/MS lock/unlock drive
    case 0x46: // IBM/MS eject media
    case 0x47: // IBM/MS extended seek
    case 0x48: // IBM/MS get drive parameters
    case 0x49: // IBM/MS extended media change
    case 0x4e: // ? - set hardware configuration
    case 0x50: // ? - send packet command
    default:
        BX_INFO("%s: function AH=%02x unsupported, returns fail\n", __func__, GET_AH());
        goto int13_fail;
        break;
    }

int13_fail:
    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
int13_fail_noah:
    SET_DISK_RET_STATUS(GET_AH());
int13_fail_nostatus:
    SET_CF();     // error occurred
    return;

int13_success:
    SET_AH(0x00); // no error
int13_success_noah:
    SET_DISK_RET_STATUS(0x00);
    CLEAR_CF();   // no error
    return;
}
Пример #7
0
void BIOSCALL int13_harddisk(disk_regs_t r)
{
    uint32_t            lba;
    uint16_t            cylinder, head, sector;
    uint16_t            nlc, nlh, nlspt;
    uint16_t            count;
    uint8_t             device, status;
    bio_dsk_t __far     *bios_dsk;

    BX_DEBUG_INT13_HD("%s: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", __func__, AX, BX, CX, DX, ES);

    bios_dsk = read_word(0x0040,0x000E) :> &EbdaData->bdisk;
    write_byte(0x0040, 0x008e, 0);  // clear completion flag
    
    // basic check : device has to be defined
    if ( (GET_ELDL() < 0x80) || (GET_ELDL() >= 0x80 + BX_MAX_STORAGE_DEVICES) ) {
        BX_DEBUG("%s: function %02x, ELDL out of range %02x\n", __func__, GET_AH(), GET_ELDL());
        goto int13_fail;
    }
    
    // Get the ata channel
    device = bios_dsk->hdidmap[GET_ELDL()-0x80];
    
    // basic check : device has to be valid
    if (device >= BX_MAX_STORAGE_DEVICES) {
        BX_DEBUG("%s: function %02x, unmapped device for ELDL=%02x\n", __func__, GET_AH(), GET_ELDL());
        goto int13_fail;
    }

    switch (GET_AH()) {

    case 0x00: /* disk controller reset */
#ifdef VBOX_WITH_SCSI
        /* SCSI controller does not need a reset. */
        if (!VBOX_IS_SCSI_DEVICE(device))
#endif
        ata_reset (device);
        goto int13_success;
        break;

    case 0x01: /* read disk status */
        status = read_byte(0x0040, 0x0074);
        SET_AH(status);
        SET_DISK_RET_STATUS(0);
        /* set CF if error status read */
        if (status) goto int13_fail_nostatus;
        else        goto int13_success_noah;
        break;

    case 0x02: // read disk sectors
    case 0x03: // write disk sectors
    case 0x04: // verify disk sectors

        count       = GET_AL();
        cylinder    = GET_CH();
        cylinder   |= ( ((uint16_t) GET_CL()) << 2) & 0x300;
        sector      = (GET_CL() & 0x3f);
        head        = GET_DH();
        
        /* Segment and offset are in ES:BX. */        
        if ( (count > 128) || (count == 0) ) {
            BX_INFO("%s: function %02x, count out of range!\n", __func__, GET_AH());
            goto int13_fail;
        }

        /* Get the logical CHS geometry. */
        nlc   = bios_dsk->devices[device].lchs.cylinders;
        nlh   = bios_dsk->devices[device].lchs.heads;
        nlspt = bios_dsk->devices[device].lchs.spt;

        /* Sanity check the geometry. */
        if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt )) {
            BX_INFO("%s: function %02x, disk %02x, parameters out of range %04x/%04x/%04x!\n", __func__, GET_AH(), GET_DL(), cylinder, head, sector);
            goto int13_fail;
        }
        
        // FIXME verify
        if ( GET_AH() == 0x04 )
            goto int13_success;

        /* If required, translate LCHS to LBA and execute command. */
        //@todo: The IS_SCSI_DEVICE check should be redundant...
        if (( (bios_dsk->devices[device].pchs.heads != nlh) || (bios_dsk->devices[device].pchs.spt != nlspt)) || VBOX_IS_SCSI_DEVICE(device)) {
            lba = ((((uint32_t)cylinder * (uint32_t)nlh) + (uint32_t)head) * (uint32_t)nlspt) + (uint32_t)sector - 1;
            sector = 0; // this forces the command to be lba
        }

        /* Clear the count of transferred sectors/bytes. */
        bios_dsk->drqp.trsfsectors = 0;
        bios_dsk->drqp.trsfbytes   = 0;

        /* Pass request information to low level disk code. */
        bios_dsk->drqp.lba      = lba;
        bios_dsk->drqp.buffer   = MK_FP(ES, BX);
        bios_dsk->drqp.nsect    = count;
        bios_dsk->drqp.sect_sz  = 512;  //@todo: device specific?
        bios_dsk->drqp.cylinder = cylinder;
        bios_dsk->drqp.head     = head;
        bios_dsk->drqp.sector   = sector;
        bios_dsk->drqp.dev_id   = device;

        status = dskacc[bios_dsk->devices[device].type].a[GET_AH() - 0x02](bios_dsk);

        // Set nb of sector transferred
        SET_AL(bios_dsk->drqp.trsfsectors);
        
        if (status != 0) {
            BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status);
            SET_AH(0x0c);
            goto int13_fail_noah;
        }
        
        goto int13_success;
        break;

    case 0x05: /* format disk track */
          BX_INFO("format disk track called\n");
          goto int13_success;
          return;
          break;

    case 0x08: /* read disk drive parameters */

        /* Get the logical geometry from internal table. */
        nlc   = bios_dsk->devices[device].lchs.cylinders;
        nlh   = bios_dsk->devices[device].lchs.heads;
        nlspt = bios_dsk->devices[device].lchs.spt;

        count = bios_dsk->hdcount;
        /* Maximum cylinder number is just one less than the number of cylinders. */
        nlc = nlc - 1; /* 0 based , last sector not used */
        SET_AL(0);
        SET_CH(nlc & 0xff);
        SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f));
        SET_DH(nlh - 1);
        SET_DL(count); /* FIXME returns 0, 1, or n hard drives */
        
        // FIXME should set ES & DI
        // @todo: Actually, the above comment is nonsense.
        
        goto int13_success;
        break;

    case 0x10: /* check drive ready */
        // should look at 40:8E also???

        // Read the status from controller
        status = inb(bios_dsk->channels[device/2].iobase1 + ATA_CB_STAT);
        if ( (status & ( ATA_CB_STAT_BSY | ATA_CB_STAT_RDY )) == ATA_CB_STAT_RDY ) {
            goto int13_success;
        } else {
            SET_AH(0xAA);
            goto int13_fail_noah;
        }
        break;

    case 0x15: /* read disk drive size */

        /* Get the physical geometry from internal table. */
        cylinder = bios_dsk->devices[device].pchs.cylinders;
        head     = bios_dsk->devices[device].pchs.heads;
        sector   = bios_dsk->devices[device].pchs.spt;

        /* Calculate sector count seen by old style INT 13h. */
        lba = (uint32_t)cylinder * head * sector;
        CX = lba >> 16;
        DX = lba & 0xffff;
        
        SET_AH(3);  // hard disk accessible
        goto int13_success_noah;
        break;

    case 0x09: /* initialize drive parameters */
    case 0x0c: /* seek to specified cylinder */
    case 0x0d: /* alternate disk reset */
    case 0x11: /* recalibrate */
    case 0x14: /* controller internal diagnostic */
        BX_INFO("%s: function %02xh unimplemented, returns success\n", __func__, GET_AH());
        goto int13_success;
        break;

    case 0x0a: /* read disk sectors with ECC */
    case 0x0b: /* write disk sectors with ECC */
    case 0x18: // set media type for format
    default:
        BX_INFO("%s: function %02xh unsupported, returns fail\n", __func__, GET_AH());
        goto int13_fail;
        break;
    }

int13_fail:
    SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
int13_fail_noah:
    SET_DISK_RET_STATUS(GET_AH());
int13_fail_nostatus:
    SET_CF();     // error occurred
    return;

int13_success:
    SET_AH(0x00); // no error
int13_success_noah:
    SET_DISK_RET_STATUS(0x00);
    CLEAR_CF();   // no error
    return;
}
Пример #8
0
int traverse(cluster* curcl, int ep1, double w1, int ep2, double w2)
{
  double max2;
  //data_t* dat;
  cluster* child=NULL;
  cluster* cll = NULL;
  cluster* cl2 = GET_CL(curcl);

  //  printf ("!");
  deprintf("Traverse: %d \n",cl2->id);
  find2max(curcl, &child, &max2,ep1,w1,ep2,w2);
  child = GET_CL(child);
  cll = GET_CL(child);
  switch(curcl->endpoints) {
  case 0:
    deprintf("End Event\n");
    if(child) {
      deprintf("max2 is %lf\n",max2);//dat= thisData(child);
      //deprintf("max is %lf\n",dat->mpath);
      cll= GET_CL(child);
      if(cll->child)
	return traverse(child,curcl->id,max2, -1, -1.0);
      else
	assert(0);
    }
    else
      return curcl->id;
    break;
  case 1:
    deprintf("Rake event\n");
    if(cll->endpoints == 2) {     
      if(cll->child)
	return traverse(child,curcl->id,max2,ep1,w1);
      else {
	deprintf("ep1 is %d \n",ep1);
	deprintf("max2 is %lf \n",max2);
	deprintf("w1 is %lf \n",w1);

	if(w1 > max2)
	  return ep1;
	else
	  return curcl->id;
      }
    }
    else
      if(child->child)
	return traverse(child,curcl->id,max2,-1,-1.0);
      else {
	deprintf("child->child is %p\n",child->child);
	deprintf("child is %p\n",child);
	drun(CRASH);//assert(0);
      }
  case 2:
    deprintf("Compress Event\n");

    if(child->endpoints == 2)
      {
	deprintf("Binary Child\n");
	if(child->child) { 
	  deprintf("with children\n");drun(fflush(stdout));
	  if(child->isEndPoint(ep1)) {
	    deprintf("Ep1 is an endpoint \n");
	    return traverse(child,ep1,w1,curcl->id,max2);
	  }
	  else {
	    deprintf("ep2 is an endpoint\n");
	    return traverse(child,ep2,w2,curcl->id,max2);
	  }
	}
	else {
	  deprintf("no children\n");
	  deprintf("child is %p\n",child);
	  if(child->isEndPoint(ep1)) {
	    deprintf("ep1 is an endpoint\n");drun(fflush(stdout));
	    if(w1 > max2)
	      return ep1;
	    else
	      return curcl->id;
	  }
	  else {
	    deprintf("ep2 is an endpoint\n");drun(fflush(stdout));
	    if(w2 > max2)
	      return ep2;
	    else
	      return curcl->id;
	  }
	}
      }
    else
      {
	if(child->child)
	  return traverse(child,curcl->id,max2,-1,-1.0);
	else
	  assert(0);
      }
 default: assert(0);
  }
}
Пример #9
0
/////////////////////////////////////////////////////////////////////
// doLive (for the initial run  in the inintial run if the node
// is going to live then copy down the neighbor's scars associated 
// with the node, and copy down the empty scars for the node
////////////////////////////////////////////////////////////////////
void doLive(node* thisNode)
{
  int i,new_degree;
  int neighs[MAX_DEGREE];
  node* neigh;
  node* desc;
  scar *neigh_scar, *desc_scar;

  drun(intptr_t j);
  drun(cluster* cl);

  neighs[0]=-1;neighs[1]=-1;

  deprintf("I live!!! I am %d\n",thisNode->nId);
  drun(deprintf("Degree is %d\n",thisNode->degree));
 
  // Compute degree, remember left and right
  new_degree = 0;
  for(i=0;i<MAX_DEGREE;i++) {
    neigh_scar = thisNode->scars[i].backscar;
    
    if (neigh_scar) { 
      neigh = GET_NEIGHBOR(neigh_scar);
      deprintf("i is %d\n",i);
      if(neigh->degree > 1) {
	neighs[new_degree] = i;
	++new_degree;
      }
    }
  }
  
  desc = thisNode->descendant;

  desc->degree = new_degree;
  desc->left   = neighs[0];
  desc->right  = neighs[1];

  // copy node data and your neighbors scars down to the next level
  desc->data = thisNode->data;

  for(i=0;i<MAX_DEGREE; i++) {
    neigh_scar = thisNode->scars[i].backscar;
  
    if (neigh_scar) { 
      neigh = GET_NEIGHBOR(neigh_scar);
      desc_scar= (scar *) ((intptr_t)neigh->descendant+ (intptr_t) neigh_scar - (intptr_t)neigh);

      desc_scar->cl       = neigh_scar->cl;
      desc_scar->backscar = desc->scars+i;     
      deprintf("Wrote %p at address %p\n",desc,GET_NEIGHBOR(desc_scar->backscar));
    }
    else {
      // no neighbor: just copy this scar down
      desc->scars[i].cl    = thisNode->scars[i].cl;
      desc->scars[i].backscar = NULL;

      drun(j= (intptr_t) thisNode->scars->cl & 3);
      drun(cl = GET_CL(thisNode->scars[i].cl));
      drun(deprintf("the cl is %p\n", cl));      
    }
  }
}