My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
Store Class Reference

The Store is a file based memory manager. More...

#include <store.h>

Inheritance diagram for Store:
StorageIntf

Classes

struct  Node
 

Public Member Functions

 Store ()
 
 ~Store ()
 
int open (const char *name)
 
portable_off_t alloc ()
 
int write (const char *buf, uint size)
 
void end ()
 
void release (portable_off_t handle)
 
void close ()
 
void seek (portable_off_t handle)
 
int read (char *buf, uint size)
 
void printStats ()
 
portable_off_t pos () const
 
void dumpBlock (portable_off_t start, portable_off_t end)
 
- Public Member Functions inherited from StorageIntf
virtual ~StorageIntf ()
 

Private Types

enum  State { Init, Reading, Writing }
 

Private Member Functions

void printFreeList ()
 

Private Attributes

FILE * m_file
 
portable_off_t m_front
 
portable_off_t m_cur
 
Nodem_head
 
State m_state
 
int m_reads
 
int m_writes
 

Detailed Description

The Store is a file based memory manager.

You can open the store using open(). Then obtain a handle via alloc() followed by a sequence of write() commands to store information, and finalize it using end().

Later on you locate the information with seek() using the handle obtained with alloc(), and then use a sequence of read() calls to read the information back.

If no longer needed the storage space can be freed using release().

The store will dynamically grow the file on disk if needed.

Definition at line 52 of file store.h.

Member Enumeration Documentation

enum Store::State
private
Enumerator
Init 
Reading 
Writing 

Definition at line 102 of file store.h.

Constructor & Destructor Documentation

Store::Store ( )

Creates a store.

Definition at line 50 of file store.cpp.

References Init, m_cur, m_file, m_front, m_head, m_reads, m_state, and m_writes.

{
m_file = 0;
m_front = 0;
m_cur = 0;
m_head = 0;
m_reads = 0;
m_writes = 0;
}
Store::~Store ( )

Releases the store object. Will close the underlying file if opened.

Definition at line 61 of file store.cpp.

References m_file, m_head, and Store::Node::next.

{
if (m_file) fclose(m_file);
// clean up free list
while (m_head)
{
Node *node = m_head;
m_head = node->next;
delete node;
}
}

Member Function Documentation

portable_off_t Store::alloc ( )

Allocates a handle to write to and read from.

Definition at line 108 of file store.cpp.

References BLOCK_SIZE, m_cur, m_file, m_front, m_head, m_state, Store::Node::next, portable_fseek(), portable_ftell(), pos(), Store::Node::pos, Reading, STORE_ASSERT, and Writing.

{
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
STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
m_front = pos + BLOCK_SIZE; // move front to end of this block
#else
pos = m_cur;
STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
#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);
}
STORE_ASSERT( (pos & (BLOCK_SIZE-1))==0 );
}
//printf("%x: Store::alloc\n",(int)pos);
return pos;
}
void Store::close ( )

Closes the store

Definition at line 101 of file store.cpp.

References Init, m_file, and m_state.

Referenced by generateOutput().

{
if (m_file) fclose(m_file);
m_file=0;
}
void Store::dumpBlock ( portable_off_t  start,
portable_off_t  end 
)

Definition at line 400 of file store.cpp.

References m_cur, m_file, and portable_fseek().

{
portable_fseek(m_file,s,SEEK_SET);
int size = (int)(e-s);
uchar *buf = new uchar[size];
if (fread(buf,size,1,m_file)==(size_t)size)
{
int i,j;
for (i=0;i<size;i+=16)
{
printf("%08x: ",(int)s+i);
for (j=i;j<QMIN(size,i+16);j++)
{
printf("%02x ",buf[i+j]);
}
printf(" ");
for (j=i;j<QMIN(size,i+16);j++)
{
printf("%c",(buf[i+j]>=32 && buf[i+j]<128)?buf[i+j]:'.');
}
printf("\n");
}
}
delete[] buf;
}
void Store::end ( )

Ends the sequence of writes.

Note
After this call, first alloc() has to be called before new writes can be done.

Definition at line 249 of file store.cpp.

References BLOCK_SIZE, m_cur, m_file, m_state, portable_ftell(), Reading, STORE_ASSERT, and Writing.

{
#if USE_FTELL
#else
#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);
}
}
int Store::open ( const char *  name)

Opens the file underlying the store using name as the file name. Returns 0 upon success, or -1 otherwise.

Definition at line 74 of file store.cpp.

References BLOCK_SIZE, Init, m_cur, m_file, m_front, m_head, m_state, portable_fopen(), Reading, and STORE_ASSERT.

{
int i;
if (m_file) return 0; // already open
if (m_file==0) return -1;
// first block serves as header, so offset=0 can be used as the end of the list.
for (i=0;i<BLOCK_SIZE/8;i++)
{
fputc('D',m_file);
fputc('O',m_file);
fputc('X',m_file);
fputc('Y',m_file);
fputc('G',m_file);
fputc('E',m_file);
fputc('N',m_file);
fputc(0,m_file);
}
m_head = 0;
return 0;
}
portable_off_t Store::pos ( ) const
inline

Definition at line 97 of file store.h.

References m_cur.

Referenced by alloc(), printFreeList(), release(), seek(), and write().

{ return m_cur; }
void Store::printFreeList ( )
private

Definition at line 382 of file store.cpp.

References m_head, Store::Node::next, pos(), and Store::Node::pos.

{
printf("FreeList: ");
while (m_head)
{
printf("%x ",(int)pos);
}
printf("\n");
}
void Store::printStats ( )

Definition at line 394 of file store.cpp.

References BLOCK_SIZE, m_front, m_reads, and m_writes.

{
printf("ObjStore: block size %d bytes, total size %ld blocks, wrote %d blocks, read %d blocks\n",
}
int Store::read ( char *  buf,
uint  size 
)
virtual

Reads size bytes from the store into the array pointed to be buf.

Note
Before reading seek() has to be called to set the right start of the store.

Implements StorageIntf.

Definition at line 319 of file store.cpp.

References BLOCK_POINTER_SIZE, BLOCK_SIZE, m_cur, m_file, m_reads, m_state, portable_fseek(), portable_ftell(), Reading, and STORE_ASSERT.

{
//printf("%x: Store::read total=%d\n",(int)portable_ftell(m_file),size);
do
{
#if USE_FTELL
#else
#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;
}
if (bytesLeft>0)
{
// read offset of the next block
#if USE_FTELL
#else
#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;
}
void Store::release ( portable_off_t  handle)

Releases the memory corresponding to the handle returned with alloc()

Definition at line 269 of file store.cpp.

References BLOCK_POINTER_SIZE, BLOCK_SIZE, m_cur, m_file, m_head, m_state, Store::Node::next, portable_fseek(), pos(), Store::Node::pos, Reading, and STORE_ASSERT.

{
//printf("release: block pos=%lld\n",(long long)pos);
STORE_ASSERT(pos>0 && (pos & (BLOCK_SIZE-1))==0);
// goto end of the block
portable_off_t cur = pos, next;
while (1)
{
// add new node to the free list
Node *node = new Node;
node->next = m_head;
node->pos = cur;
m_head = node;
// goto the end of cur block
{
fprintf(stderr,"Store::release: Error seeking to position %d: %s\n",
(int)(cur+BLOCK_SIZE-BLOCK_POINTER_SIZE),strerror(errno));
exit(1);
}
// read pointer to next block
if (fread(&next,BLOCK_POINTER_SIZE,1,m_file)!=1)
{
fprintf(stderr,"Store::release: Error reading from store: %s\n",strerror(errno));
exit(1);
}
if (next==0) break; // found end of list -> cur is last element
STORE_ASSERT((next & (BLOCK_SIZE-1))==0);
cur = next;
//printf("%x: Store::release\n",(int)cur);
}
}
void Store::seek ( portable_off_t  handle)

Goes to the start of information corresponding to handle pos

Definition at line 305 of file store.cpp.

References BLOCK_SIZE, m_cur, m_file, m_state, portable_fseek(), pos(), Reading, and STORE_ASSERT.

{
//printf("%x: Store::seek\n",(int)pos);
if (portable_fseek(m_file,pos,SEEK_SET)==-1)
{
fprintf(stderr,"Store::seek: Error seeking to position %d: %s\n",
(int)pos,strerror(errno));
exit(1);
}
}
int Store::write ( const char *  buf,
uint  size 
)
virtual

Writes size bytes in array buf to the store. First alloc() has to be called.

Note
The information can only be read after end() has been called.

Implements StorageIntf.

Definition at line 154 of file store.cpp.

References BLOCK_POINTER_SIZE, BLOCK_SIZE, m_cur, m_file, m_front, m_head, m_state, m_writes, Store::Node::next, portable_fseek(), portable_ftell(), pos(), Store::Node::pos, STORE_ASSERT, and Writing.

{
//printf("%x: Store::write\n",(int)portable_ftell(m_file));
do
{
#if USE_FTELL
#else
#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);
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;
}
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);
}
#if USE_FTELL
#else
#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);
}
#if USE_FTELL
#else
#endif
// move front to the next of the block
}
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);
}
//printf("%x: Store::write: reuse\n",(int)pos);
}
}
size-=numBytes;
buf+=numBytes;
}
while (size>0);
return size;
}

Member Data Documentation

portable_off_t Store::m_cur
private

Definition at line 116 of file store.h.

Referenced by alloc(), dumpBlock(), end(), open(), pos(), read(), release(), seek(), Store(), and write().

FILE* Store::m_file
private

Definition at line 114 of file store.h.

Referenced by alloc(), close(), dumpBlock(), end(), open(), read(), release(), seek(), Store(), write(), and ~Store().

portable_off_t Store::m_front
private

Definition at line 115 of file store.h.

Referenced by alloc(), open(), printStats(), Store(), and write().

Node* Store::m_head
private

Definition at line 117 of file store.h.

Referenced by alloc(), open(), printFreeList(), release(), Store(), write(), and ~Store().

int Store::m_reads
private

Definition at line 119 of file store.h.

Referenced by printStats(), read(), and Store().

State Store::m_state
private

Definition at line 118 of file store.h.

Referenced by alloc(), close(), end(), open(), read(), release(), seek(), Store(), and write().

int Store::m_writes
private

Definition at line 120 of file store.h.

Referenced by printStats(), Store(), and write().


The documentation for this class was generated from the following files: