⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbbufferc.nc

📁 nesC写的heed算法
💻 NC
📖 第 1 页 / 共 5 页
字号:
	//see comment at beginning of document for info on slot management & indexing	if (buf->nextFull == buf->nextFree)	  *size = 0;	else if (buf->nextFull > buf->nextFree) {	  *size = (buf->numRows - buf->nextFull) + buf->nextFree;	} else {	  *size = buf->nextFree - buf->nextFull;	}	break;      }      return err_NoError;    }      /** Allocate the buffer with the specified size 	sizes is an array of sizes of each field, with one entry per field	<p>	Note that this may keep a reference to schema or name until after pending is complete (so 	neither may be allocated on the callers stack!)	<p>	Signals allocComplete when allocation is complete if *pending is true on return	@param bufferId The buffer to allocate	@param type The type of the buffer (see DBBuffer.h -- only kRAM and kRADIO are supported)	@param size The size (in rows) of the buffer	@param policy The eviction policy to use with the buffer (see DBBuffer.h)	@param schema The schema (layout) of rows in this buffer (expressed as a query)	@param name The name of the schema (or NULL if it has no name)	@param pending On return, set to true if the buffer is still being allocated (expect allocComplete if	               true).	@param data is currently unused	@return err_UnsupportedPolicy if the specified policy can't be applied    */  command TinyDBError DBBuffer.alloc(uint8_t bufferId, BufferType type, uint16_t size, BufferPolicy policy,				     ParsedQuery *schema, char *name, bool *pending, long data) {        Buffer *buf;        *pending = FALSE;        if (mState != kIDLE) return err_ResultBufferBusy;    if (bufferId >= kNUM_BUFS)      return err_InvalidIndex;        if (type == kRADIO)      return err_UnsupportedBuffer; // can't do these right now    if (mUsedBufs & (1 << bufferId))      return err_ResultBufferInUse;        mState = kALLOC_SCHEMA;    buf = &mBuffers[bufferId];    buf->type = type;    buf->policy = policy;    buf->numRows = size;    buf->nextFree = 0;    buf->nextFull = 0;    buf->u.bufdata = NULL;    buf->qh = NULL;    buf->data = data;    if (name == NULL) {      buf->name = NULL;    }     //we must allocate buffer name    mNamePtr = name;    switch (type) {    case kEEPROM:      if (mNamePtr == NULL) {	mState = kIDLE;	cleanupBuffer(bufferId, __LINE__);	return err_NoUnnamedEepromBuffers;      }    case kRAM:      buf->rowSize = sizeof(Handle); //rows are handles into memory      buf->len = buf->rowSize * buf->numRows;      mCurBuffer = bufferId;      mAllocSchema = schema;            //now, we have to allocate buf->u.bufdata and buf->q      if (call MemAlloc.allocate((HandlePtr)(&buf->qh), call ParsedQueryIntf.pqSize(schema)) == SUCCESS) {	*pending = TRUE;	return err_NoError;      } else {	mState = kIDLE;	cleanupBuffer(bufferId, __LINE__);	return err_OutOfMemory;      }      break;          case kCOMMAND:      mState = kIDLE;      mUsedBufs |= (1 << bufferId);       return err_NoError;      break;    default:       break;    }    return err_NoError;  }      /** @return the number of rows in this buffer */  command uint16_t DBBuffer.maxSize(uint8_t bufferId) {    Buffer *buf;    TinyDBError err = getBuf(bufferId, &buf);    if (err != err_NoError) return 0;        return buf->numRows;  }    /** @return the schema of the result */  command ParsedQuery **DBBuffer.getSchema(uint8_t bufferId) {    Buffer *buf;    TinyDBError err = getBuf(bufferId, &buf);    if (err != err_NoError) return NULL;    return buf->qh;  }  /** Copy the index of the named field f in bufferId (which was generated via a call to getBufferId)      into id, if f exists in the result buffer  */  command TinyDBError DBBuffer.getFieldId(uint8_t bufferId, FieldPtr f, uint8_t *id) {    TinyDBError err = err_NoError;    ParsedQuery **fromPq;    int i;    switch (bufferId) {    case kATTR_BUF:      *id = NULL_QUERY_FIELD;      for (i = 0; i < NUM_ATTR_FIELDS; i++) {	if (strcmp(f->name,ATTR_NAMES[i]) == 0)	  *id = i;      }      break;    default:      fromPq = call DBBuffer.getSchema(bufferId);      if (fromPq == NULL) return err_UnsupportedBuffer;      err = call ParsedQueryIntf.getResultId(*fromPq, f, id);      if (err != err_NoError) {	*id = NULL_QUERY_FIELD;      }      return err;    }    return err_NoError;  }  /** Copy data from the idxth field of qr into resultBuf.  qr must have been produced via a call to      peek() or getResult() on the same bufferId.  */  command TinyDBError DBBuffer.getField(uint8_t bufferId, QueryResult *qr, uint8_t idx, char *resultBuf) {    ParsedQuery **fromPq;    Tuple *t;    char *field;    TinyDBError err = err_NoError;    switch (bufferId) {    case kATTR_BUF:      if (idx >= NUM_ATTR_FIELDS) return err_InvalidIndex;      t = &qr->d.t;      field = call TupleIntf.getFieldPtrNoQuery(t, idx, NUM_ATTR_FIELDS, ATTR_SIZES, ATTR_TYPES);      if (field != NULL) {	  memcpy(resultBuf, field, ATTR_SIZES[idx]);      } else	err = err_InvalidIndex;      break;    default:      fromPq = call DBBuffer.getSchema(bufferId);        if (fromPq == NULL) return err_UnsupportedBuffer;      err = call ParsedQueryIntf.getResultField(*fromPq, 						qr,						idx,						resultBuf);    }    return err;  }  /* Return the next unused buffer id, or err_OutOfMemory,      if no more buffers are available */  command TinyDBError DBBuffer.nextUnusedBuffer(uint8_t *bufferId) {    int i;    for (i = 0; i < kNUM_BUFS; i++) {      if (!(mUsedBufs & (1<<i))) { 	*bufferId = i;	return err_NoError;      }    }        return err_OutOfMemory;  }    /** Looks up the buffer id that corresponds to the specified name      @param name The name of the buffer      @param bufferId (on return) The id of buffer name      @return err_InvalidIndex if no such buffer exists  */  command TinyDBError DBBuffer.getBufferIdFromName(char *name, uint8_t *bufferId) {    int i;        //don't look at the the radio buffer!    for (i = 1; i < kNUM_BUFS; i++) {      if ((mUsedBufs & (1<<i))) {	char *testName = *(mBuffers[i].name);	if (strcmp(testName, name) == 0) {	  //call UartDebugger.writeLine("got buf", 7);	  *bufferId = i;	  return err_NoError;	}      }    }    return err_InvalidIndex;  }  /** Given a buffer id, return the query id which describes its schema */  command TinyDBError DBBuffer.qidFromBufferId(uint8_t bufId, uint8_t *qid) {    if (bufId < kNUM_BUFS && (mUsedBufs & (1<<bufId))) {      *qid = (**(mBuffers[bufId].qh)).qid;      return err_NoError;    } else {      return err_InvalidIndex;    }  }  /** @return the buffer id that corresponds to the specified bufIdx      if special is false, bufIdx is just the query id that we want to read from      otherwise, it's the index into special buffers -- e.g. catalog buffers -- that we want to use  */  command TinyDBError DBBuffer.getBufferId(uint8_t bufIdx, bool special, uint8_t *bufferId) {    int i;    int qid;    if (special)      return getSpecialBufferId(bufIdx, bufferId);    qid = bufIdx;					     //don't look at the the radio buffer!    for (i = 1; i < kNUM_BUFS; i++) {      if ((mUsedBufs & (1<<i))) {	if ((**mBuffers[i].qh).qid == qid) {	  *bufferId = i;	  return err_NoError;	}      }    }    return err_InvalidIndex;  }  /** Return the size of the requested field in a "special" catalog table.      Return 0 if the field number is out of range or bufIdx is an      unknown field.  */  command uint8_t CatalogTable.catalogFieldSize(uint8_t bufIdx, uint8_t fieldNo) {    uint8_t bufferId;    uint8_t numFields;    uint8_t *sizes = NULL;    if (getSpecialBufferId(bufIdx, &bufferId) != err_NoError)      return 0;    switch(bufferId) {    case kATTR_BUF:      numFields = NUM_ATTR_FIELDS; sizes = (char *)ATTR_SIZES;      break;    case kCOMMAND_BUF:      //fill me in...      break;    case kEVENT_BUF:      //fill me in...      break;          case kQUERY_BUF:            //fill me in...      break;    default:      return 0;    }    if (fieldNo < NUM_ATTR_FIELDS && sizes != NULL)      return sizes[fieldNo];    else      return 0;        }#ifdef kMATCHBOX  /* ----------------- EEPROM Catalog Management Routines ----------------------- */  // Erase all files in the EEPROM (be careful!)  command TinyDBError DBBuffer.cleanupEEPROM() {    if (mState == kIDLE) {      mState = kCLEANUP;      if (call FileDir.start() == FAIL)	return err_EepromFailure;      mHasName = FALSE;      if (call FileDir.readNext() == FAIL)	return err_EepromFailure;    }    else      return err_ResultBufferBusy;    return err_NoError;  }  event result_t FileDir.nextFile(const char *name, fileresult_t result) {    if (result == FS_OK) {      if (!mHasName) { //get a name	strcpy(mCurName, name);	DEBUG(mCurName, strlen(mCurName));	mHasName = TRUE;      }      if (call FileDir.readNext() != FAIL) //then skip to the end of the iterator	return SUCCESS;    } //fall through on failure        if (mHasName) {  //if we found a name, there's something to delete      if (call FileDelete.delete(mCurName) == FAIL) {	mState = kIDLE;	signal DBBuffer.cleanupDone(FAIL);      }    } else {  //otherwise, we're all done      mState = kIDLE;      mNumFiles = 0;      DEBUG("clean", 5);      signal DBBuffer.cleanupDone(SUCCESS);    }    return SUCCESS;  }#endif  /** Open the specified buffer for writing */  command TinyDBError DBBuffer.openBuffer(uint8_t bufIdx, bool *pending) {    Buffer *buf;    if ( bufIdx >= kNUM_BUFS || !(mUsedBufs & (1<<bufIdx))) {            return err_IndexOutOfBounds;    }    if (mState == kIDLE) {      mState = kOPEN_BUFFER;      mCurBuffer = bufIdx;    } else return err_ResultBufferBusy;    buf = &mBuffers[bufIdx];    if (buf->type == kEEPROM) {#ifdef kMATCHBOX      *pending = TRUE;      if (call FileWrite.open(*(buf->name), FS_FCREATE | FS_FTRUNCATE) == FAIL) {	return err_EepromFailure;	mState = kIDLE;      } else	return err_NoError;#else      mState = kIDLE;      *pending = FALSE;      return err_NoMatchbox;#endif    } else {      *pending = FALSE;      mState = kIDLE;      return err_NoError;    }  }#ifdef kMATCHBOX  /** Read information about a particular buffer in from the EEPROM */  command TinyDBError DBBuffer.loadEEPROMBuffer(char *name) {      mCurBufName = name;      mNameSearch = TRUE;      return doLoad();  }  command TinyDBError DBBuffer.loadEEPROMBufferIdx(int i) {    mNameSearch = FALSE;    mSearchFile = i;    if (i < 0 || i >= mNumFiles)      return err_IndexOutOfBounds;    return doLoad();  }  //shared routine for handling reading info about a specific buffer  TinyDBError doLoad() {    // we can get here from headerFileWrite, which is OK    //  must be careful, however, to leave mState == kWRITE_BUFFER on exit    if (mHeaderFileState == kIDLE && (mState == kIDLE || mState == kWRITE_BUFFER)) {      result_t err;      mHeaderFileState = kREAD_OPEN;      if (mState == kIDLE) mState = kHEADER_READ;      mCurFile = 0; //index so far      if (call DBBuffer.nextUnusedBuffer(&mCurBufId) != err_NoError) {	if (mState == kHEADER_READ) mState = kIDLE;	return err_OutOfMemory;      }            //allocate this thing      mUsedBufs |= (1 << mCurBufId);      err = call HeaderFileRead.open("tdbBufs");      if (err != SUCCESS) {	//DEBUG("fail",4);	mHeaderFileState = kIDLE;	if (mState == kHEADER_READ) mState = kIDLE;	return err_EepromFailure;      }      return err_NoError;    }  else      return err_ResultBufferBusy;  }  /* Task to read info about the buffer named mCurBufName into buffer mCurBufId     Scans the buffers in the eeprom file HeaderFileRead, looking for buffers of the     appropriate name.          signals loadBufferDone, with err_NoError on success, or some other error code     on failure (including buffer not found).     This is pretty ugly;  we have to (through a long series of split phase steps)     - read length of name and query handle     - allocate name     - read name     - compare name to mCurBufName     - if not equal, skip remaining data and repeat     - if equal,      - allocate query handle     - read query handle     - read buffer data     - set handle and name in buffer data  */  #define min(x,y) ((x) < (y) ? (x) : (y))  task void loadBufferTask() {    int numBytes;    TinyDBError err = err_NoError;    switch (mHeaderFileState) {    case kREAD_OPEN:      //now, we need to read the length of the name and the parsed query, which follow      mHeaderFileState = kREAD_LENGTHS;      if (call HeaderFileRead.read(mLenBytes, 3) != SUCCESS) {	//DEBUG("fail_len", 8);	err = err_EepromFailure;	goto fail;      }      break;    case kREAD_LENGTHS:      //DEBUG("READLENGTH",10);      //now allocate storage for the name      mHeaderFileState = kALLOC_NAME;      //could check version code here?      if (call MemAlloc.allocate(&mNameHand, mLenBytes[1] + 1) == FAIL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -