Exemplo n.º 1
0
portable_off_t Store::alloc()
{
  STORE_ASSERT(m_state==Reading);
  m_state=Writing;
  portable_off_t pos;
  if (m_head==0) // allocate new block
  {
    //printf("alloc: new block, pos=%lld\n",(long long)m_front);
    if (portable_fseek(m_file,0,SEEK_END)==-1) // go to end of the file
    {
      fprintf(stderr,"Store::alloc: Error seeking to end of file: %s\n",strerror(errno));
      exit(1);
    }
#if USE_FTELL
    pos = portable_ftell(m_file);
    STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
    m_front = pos + BLOCK_SIZE; // move front to end of this block
#else
    m_cur = m_front;
    pos   = m_cur;
    STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
    m_front = pos + BLOCK_SIZE;
#endif
  }
  else // reuse freed block
  {
    //printf("alloc: reuse block: pos=%lld\n",(long long)m_head->pos);
    Node *node = m_head;
    pos = node->pos;
    // point head to next free item
    m_head = node->next;
    delete node;
    // move to start of the block
    if (portable_fseek(m_file,pos,SEEK_SET)==-1)
    {
      fprintf(stderr,"Store::alloc: Error seeking to position %d: %s\n",
          (int)pos,strerror(errno));
      exit(1);
    }
    m_cur = pos;
    STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
  }
  //printf("%x: Store::alloc\n",(int)pos);
  return pos;
}
Exemplo n.º 2
0
void Store::end()
{
   STORE_ASSERT(m_state == Writing);
#if USE_FTELL
   portable_off_t curPos = portable_ftell(m_file);
#else
   portable_off_t curPos = m_cur;
#endif
   int bytesInBlock = (int)(BLOCK_SIZE - (curPos & (BLOCK_SIZE - 1)));
   //printf("%x: Store::end erasing %x bytes\n",(int)curPos&~(BLOCK_SIZE-1),bytesInBlock);
   //printf("end: bytesInBlock=%x\n",bytesInBlock);
   // zero out rest of the block
   int i;
   for (i = 0; i < bytesInBlock; i++) {
      fputc(0, m_file);
   }
   m_state = Reading;
}
Exemplo n.º 3
0
int Store::read(char *buf,uint size)
{
  STORE_ASSERT(m_state==Reading);
  //printf("%x: Store::read total=%d\n",(int)portable_ftell(m_file),size);
  do
  {
#if USE_FTELL
    portable_off_t curPos = portable_ftell(m_file);
#else
    portable_off_t curPos = m_cur;
#endif
    int bytesInBlock = (int)(BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1)));
    int bytesLeft    = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0;
    int numBytes     = size - bytesLeft;
    //printf("  Store::read: pos=%x num=%d left=%d\n",(int)curPos,numBytes,bytesLeft);

    if (numBytes>0)
    {
      //printf("%x: Store::read: %d out of %d bytes\n",(int)portable_ftell(m_file),numBytes,size);
      if ((int)fread(buf,1,numBytes,m_file)!=numBytes)
      {
        fprintf(stderr,"Error reading from store: %s\n",strerror(errno));
        exit(1);
      }
      m_cur+=numBytes;
      m_reads++;
    }
    if (bytesLeft>0)
    {
      portable_off_t newPos;
      // read offset of the next block
#if USE_FTELL
      STORE_ASSERT(((portable_ftell(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
#else
      STORE_ASSERT(((m_cur+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
#endif
      if (fread((char *)&newPos,BLOCK_POINTER_SIZE,1,m_file)!=1)
      {
        fprintf(stderr,"Error reading from store: %s\n",strerror(errno));
        exit(1);
      }
      //printf("%x: Store::read: continue in next block, %d bytes to go\n",(int)newPos,bytesLeft);
      //printf("  Store::read: next block=%x\n",(int)newPos);
      STORE_ASSERT(newPos!=0);
      STORE_ASSERT((newPos&(BLOCK_SIZE-1))==0);
      curPos = newPos;
      // move to next block
      if (portable_fseek(m_file,curPos,SEEK_SET)==-1)
      {
        fprintf(stderr,"Store::read: Error seeking to position %d: %s\n",
            (int)curPos,strerror(errno));
        exit(1);
      }
      m_cur = curPos;
    }

    size-=numBytes;
    buf+=numBytes;
  }
  while (size>0);
  return size;
}
Exemplo n.º 4
0
int Store::write(const char *buf,uint size)
{
  STORE_ASSERT(m_state==Writing);
  //printf("%x: Store::write\n",(int)portable_ftell(m_file));
  do
  {
#if USE_FTELL
    portable_off_t curPos = portable_ftell(m_file);
#else
    portable_off_t curPos = m_cur;
#endif
    int bytesInBlock = (int)(BLOCK_SIZE - BLOCK_POINTER_SIZE - (curPos & (BLOCK_SIZE-1)));
    int bytesLeft    = bytesInBlock<(int)size ? (int)size-bytesInBlock : 0;
    int numBytes     = size - bytesLeft;
    STORE_ASSERT(bytesInBlock>=0);
    STORE_ASSERT(numBytes<=(int)(BLOCK_SIZE-BLOCK_POINTER_SIZE));
    if (numBytes>0)
    {
      if ((int)fwrite(buf,1,numBytes,m_file)!=numBytes)
      {
        fprintf(stderr,"Error writing: %s\n",strerror(errno));
        exit(1);
      }
      m_cur+=numBytes;
      m_writes++;
    }
    if (bytesLeft>0) // still more bytes to write
    {
#if USE_FTELL
      STORE_ASSERT(((portable_ftell(m_file)+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
#else
      STORE_ASSERT(((m_cur+BLOCK_POINTER_SIZE)&(BLOCK_SIZE-1))==0);
#endif
      // allocate new block
      if (m_head==0) // no free blocks to reuse
      {
        //printf("%x: Store::write: new: pos=%x\n",(int)m_front,(int)portable_ftell(m_file));
        // write pointer to next block
        if (fwrite(&m_front,BLOCK_POINTER_SIZE,1,m_file)!=1)
        {
          fprintf(stderr,"Error writing to store: %s\n",strerror(errno));
          exit(1);
        }
        m_cur+=BLOCK_POINTER_SIZE;
#if USE_FTELL
        STORE_ASSERT(portable_ftell(m_file)==(curPos&~(BLOCK_SIZE-1))+BLOCK_SIZE);
#else
        STORE_ASSERT(m_cur==(curPos&~(BLOCK_SIZE-1))+BLOCK_SIZE);
#endif
        // move to next block
        if (portable_fseek(m_file,0,SEEK_END)==-1) // go to end of the file
        {
          fprintf(stderr,"Store::alloc: Error seeking to end of file: %s\n",strerror(errno));
          exit(1);
        }
        m_cur=m_front;
#if USE_FTELL
        STORE_ASSERT(portable_ftell(m_file)==m_front);
#else
        STORE_ASSERT(m_cur==m_front);
#endif
        // move front to the next of the block
        m_front+=BLOCK_SIZE;
      }
      else // reuse block from the free list
      {
        // write pointer to next block
        if (fwrite(&m_head->pos,BLOCK_POINTER_SIZE,1,m_file)!=1)
        {
          fprintf(stderr,"Error writing to store: %s\n",strerror(errno));
          exit(1);
        }
        Node *node = m_head;
        portable_off_t pos = node->pos;
        // point head to next free item
        m_head = node->next;
        delete node;
        // move to start of the block
        if (portable_fseek(m_file,pos,SEEK_SET)==-1)
        {
          fprintf(stderr,"Store::write: Error seeking to position %d: %s\n",
              (int)pos,strerror(errno));
          exit(1);
        }
        m_cur = pos;
        //printf("%x: Store::write: reuse\n",(int)pos);
      }
    }
    size-=numBytes;
    buf+=numBytes;
  }
  while (size>0);
  return size;
}