From 9731dc86fa9b12adc064b99910dddb58932c71cf Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 10 May 2010 07:15:05 +0000 Subject: Added the new Bu::CacheStoreFiles, it's an uber-simple cache storage system that maybe would be better to call an example than a fully fledged storage strategy. It just names files based on your keys. It's very slow, and very wasteful, and shouldn't be used long-term in most normal cache systems. --- src/cachestorefiles.cpp | 9 +++ src/cachestorefiles.h | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ src/queuebuf.cpp | 60 ++++++++++----- src/tests/list2.cpp | 19 +++++ src/tests/queuebuf.cpp | 42 ++++++++++- 5 files changed, 300 insertions(+), 22 deletions(-) create mode 100644 src/cachestorefiles.cpp create mode 100644 src/cachestorefiles.h create mode 100644 src/tests/list2.cpp (limited to 'src') diff --git a/src/cachestorefiles.cpp b/src/cachestorefiles.cpp new file mode 100644 index 0000000..7f9d76d --- /dev/null +++ b/src/cachestorefiles.cpp @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2007-2010 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/cachestorefiles.h" + diff --git a/src/cachestorefiles.h b/src/cachestorefiles.h new file mode 100644 index 0000000..6b37d0a --- /dev/null +++ b/src/cachestorefiles.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2007-2010 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#ifndef BU_CACHE_STORE_FILES_H +#define BU_CACHE_STORE_FILES_H + +#include "bu/fstring.h" +#include "bu/file.h" +#include "bu/cachestore.h" +#include "bu/archive.h" +#include "bu/membuf.h" +#include "bu/formatter.h" +#include "bu/sio.h" + +#include +#include +#include +#include + +namespace Bu +{ + template + keytype __cacheGetKey( const obtype *pObj ); + + template + obtype *__cacheStoreFilesAlloc( const keytype &key ) + { + return new obtype(); + } + + template + void __cacheStoreFilesStore( Bu::Stream &s, obtype &rObj, + const keytype & ) + { + Bu::Archive ar( s, Bu::Archive::save ); + ar << rObj; + } + + template + obtype *__cacheStoreFilesLoad( Bu::Stream &s, const keytype &key ) + { + obtype *pObj = __cacheStoreFilesAlloc( key ); + Bu::Archive ar( s, Bu::Archive::load ); + ar >> (*pObj); + return pObj; + } + + template + class CacheStoreFiles : public CacheStore + { + public: + CacheStoreFiles( const Bu::FString &sPrefix ) : + sPrefix( sPrefix ) + { + if( access( sPrefix.getStr(), W_OK|R_OK|X_OK ) ) + { + mkdir( sPrefix.getStr(), 0755 ); + } + } + + virtual ~CacheStoreFiles() + { + } + + virtual obtype *load( const keytype &key ) + { + Bu::MemBuf mb; + Bu::Formatter f( mb ); + f << sPrefix << "/" << key; + Bu::File fIn( mb.getString(), Bu::File::Read ); + obtype *pOb = __cacheStoreFilesLoad( fIn, key ); + return pOb; + } + + virtual void unload( obtype *pObj, const keytype &key ) + { + delete pObj; + } + + virtual keytype create( obtype *pSrc ) + { + keytype key = __cacheGetKey( pSrc ); + Bu::MemBuf mb; + Bu::Formatter f( mb ); + f << sPrefix << "/" << key; + + Bu::File fTouch( mb.getString(), Bu::File::WriteNew ); + + return key; + } + + virtual void sync() + { + } + + virtual void sync( obtype *pSrc, const keytype &key ) + { + Bu::MemBuf mb; + Bu::Formatter f( mb ); + f << sPrefix << "/" << key; + + Bu::File fOut( mb.getString(), Bu::File::WriteNew ); + __cacheStoreFilesStore( fOut, *pSrc, key ); + } + + virtual void destroy( obtype *pObj, const keytype &key ) + { + Bu::MemBuf mb; + Bu::Formatter f( mb ); + f << sPrefix << "/" << key; + + unlink( mb.getString().getStr() ); + delete pObj; + } + + virtual void destroy( const keytype &key ) + { + Bu::MemBuf mb; + Bu::Formatter f( mb ); + f << sPrefix << "/" << key; + + unlink( mb.getString().getStr() ); + } + + virtual bool has( const keytype &key ) + { + Bu::MemBuf mb; + Bu::Formatter f( mb ); + f << sPrefix << "/" << key; + + return access( mb.getString().getStr(), F_OK ) == 0; + } + + virtual Bu::List getKeys() + { + DIR *dir = opendir( sPrefix.getStr() ); + struct dirent *de; + Bu::List lKeys; + + while( (de = readdir( dir ) ) ) + { + if( de->d_type != DT_REG ) + continue; + + keytype tmp; + Bu::MemBuf mb( de->d_name ); + Bu::Formatter f( mb ); + try + { + f >> tmp; + } + catch( Bu::ExceptionBase &e ) + { + Bu::sio << "Parse error in dir-scan: " << e.what() + << Bu::sio.nl; + } + lKeys.append( tmp ); + } + closedir( dir ); + + return lKeys; + } + + virtual int getSize() + { + DIR *dir = opendir( sPrefix.getStr() ); + struct dirent *de; + int iCount = 0; + + while( (de = readdir( dir ) ) ) + { + if( de->d_type != DT_REG ) + continue; + + iCount++; + } + closedir( dir ); + + return iCount; + } + + private: + Bu::FString sPrefix; + }; + +}; + +#endif diff --git a/src/queuebuf.cpp b/src/queuebuf.cpp index 9404164..9577793 100644 --- a/src/queuebuf.cpp +++ b/src/queuebuf.cpp @@ -70,13 +70,13 @@ size_t Bu::QueueBuf::read( void *pRawBuf, size_t nBytes ) iLeft -= iCopy; pBuf += iCopy; iTotalSize -= iCopy; - sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; +// sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; } return nBytes - iLeft; } -size_t QueueBuf::peek( void *pBuf, size_t nBytes ) +size_t Bu::QueueBuf::peek( void *pRawBuf, size_t nBytes ) { if( nBytes <= 0 ) return 0; @@ -88,31 +88,33 @@ size_t QueueBuf::peek( void *pBuf, size_t nBytes ) char *pBuf = (char *)pRawBuf; int iTmpReadOffset = iReadOffset; - int iTmpRemSize = iTotalSize; + size_t iTmpRemSize = iTotalSize; + BlockList::iterator iBlock = lBlocks.begin(); while( iLeft > 0 && iTmpRemSize > 0 ) { - // Switching to use temp variables instead of iReadOffset and iTotalSize - if( iReadOffset == iBlockSize ) + if( iTmpReadOffset == iBlockSize ) { - if( lBlocks.isEmpty() ) + iBlock++; + if( iBlock == lBlocks.end() ) { return nBytes-iLeft; } - iReadOffset = 0; + iTmpReadOffset = 0; } - char *pBlock = lBlocks.first(); - size_t iCopy = iBlockSize-iReadOffset; + char *pBlock = *iBlock; + size_t iCopy = iBlockSize-iTmpReadOffset; if( iLeft < iCopy ) iCopy = iLeft; - if( iTotalSize < iCopy ) - iCopy = iTotalSize; - memcpy( pBuf, pBlock+iReadOffset, iCopy ); - iReadOffset += iCopy; + if( iTmpRemSize < iCopy ) + iCopy = iTmpRemSize; + memcpy( pBuf, pBlock+iTmpReadOffset, iCopy ); + iTmpReadOffset += iCopy; iLeft -= iCopy; pBuf += iCopy; - iTotalSize -= iCopy; - sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; + iTmpRemSize -= iCopy; +// sio << "Read (peek) " << iCopy << " bytes, new temp size: " +// << iTmpRemSize << sio.nl; } return nBytes - iLeft; @@ -147,7 +149,8 @@ size_t Bu::QueueBuf::write( const void *pRawBuf, size_t nBytes ) iLeft -= iCopy; pBuf += iCopy; iTotalSize += iCopy; - sio << "Wrote " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; +// sio << "Wrote " << iCopy << " bytes, new size: " << iTotalSize +// << sio.nl; } return nBytes; @@ -158,8 +161,27 @@ long Bu::QueueBuf::tell() return -1; } -void Bu::QueueBuf::seek( long ) +void Bu::QueueBuf::seek( long iAmnt ) { + if( iAmnt <= 0 ) + return; + + if( iAmnt >= iTotalSize ) + { +// sio << "seek: clear all data (" << iAmnt << ">=" << iTotalSize +// << ")." << sio.nl; + close(); + return; + } + + iReadOffset += iAmnt; + iTotalSize -= iAmnt; + while( iReadOffset >= iBlockSize ) + { + removeBlock(); + iReadOffset -= iBlockSize; +// sio << "seek: removal step (" << iReadOffset << ")" << sio.nl; + } } void Bu::QueueBuf::setPos( long ) @@ -221,13 +243,13 @@ void Bu::QueueBuf::setBlocking( bool ) void Bu::QueueBuf::addBlock() { lBlocks.append( new char[iBlockSize] ); - sio << "Added new block." << sio.nl; +// sio << "Added new block." << sio.nl; } void Bu::QueueBuf::removeBlock() { delete[] lBlocks.first(); lBlocks.erase( lBlocks.begin() ); - sio << "Removed block." << sio.nl; +// sio << "Removed block." << sio.nl; } diff --git a/src/tests/list2.cpp b/src/tests/list2.cpp new file mode 100644 index 0000000..cd02aef --- /dev/null +++ b/src/tests/list2.cpp @@ -0,0 +1,19 @@ +#include +#include + +using namespace Bu; + +int main() +{ + List lInt; + + lInt.append( 512 ); + lInt.append( 1024 ); + lInt.append( 4096 ); + lInt.append( 12 ); + lInt.erase( 12 ); + lInt.append( 12 ); + lInt.erase( 12 ); + lInt.append( 12 ); +} + diff --git a/src/tests/queuebuf.cpp b/src/tests/queuebuf.cpp index accc723..677df16 100644 --- a/src/tests/queuebuf.cpp +++ b/src/tests/queuebuf.cpp @@ -13,11 +13,47 @@ int main() qb.write( src, 60 ); } - char buf[11]; + char buf[11], bufp[11]; while( !qb.isEos() ) { - buf[qb.read( buf, 9 )] = '\0'; - sio << "Read: >>" << buf << "<<" << sio.nl; + int iAmntPeek = qb.peek( bufp, 9 ); + int iAmntRead = qb.read( buf, 9 ); + if( iAmntPeek != iAmntRead ) + sio << "Differ: " << iAmntPeek << " vs " << iAmntRead << sio.nl; + buf[iAmntRead] = '\0'; + bufp[iAmntPeek] = '\0'; + if( memcmp( buf, bufp, iAmntPeek ) ) + { + sio << "Buffers differ" << sio.nl + << " " << buf << sio.nl + << " " << bufp << sio.nl; + } + else + sio << "Read: >>" << buf << "<<" << sio.nl; + } + + sio << sio.nl << sio.nl << sio.nl << "Seek test:" << sio.nl << sio.nl; + + for( int j = 0; j < 5; j++ ) + { + qb.write( src, 25 ); + qb.write( src+10, 25 ); + } + + char bufa[26]; + char bufb[26]; + ::memcpy( bufb, src+10, 15 ); + ::memcpy( bufb+15, src+10, 10 ); + bufb[25] = '\0'; + sio << "Comparing to '" << bufb << "'" << sio.nl; + qb.seek( 10 ); + while( !qb.isEos() ) + { + bufa[qb.read( bufa, 25 )] = '\0'; + qb.seek( 25 ); + if( memcmp( bufa, bufb, 25 ) ) + sio << "Differ?" << sio.nl; + sio << "=== '" << bufa << "' == '" << bufb << "'" << sio.nl; } } -- cgit v1.2.3