summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cachestorefiles.cpp9
-rw-r--r--src/cachestorefiles.h192
-rw-r--r--src/queuebuf.cpp60
-rw-r--r--src/tests/list2.cpp19
-rw-r--r--src/tests/queuebuf.cpp42
5 files changed, 300 insertions, 22 deletions
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 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/cachestorefiles.h"
9
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 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_CACHE_STORE_FILES_H
9#define BU_CACHE_STORE_FILES_H
10
11#include "bu/fstring.h"
12#include "bu/file.h"
13#include "bu/cachestore.h"
14#include "bu/archive.h"
15#include "bu/membuf.h"
16#include "bu/formatter.h"
17#include "bu/sio.h"
18
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <dirent.h>
22#include <unistd.h>
23
24namespace Bu
25{
26 template<class keytype, class obtype>
27 keytype __cacheGetKey( const obtype *pObj );
28
29 template<class keytype, class obtype>
30 obtype *__cacheStoreFilesAlloc( const keytype &key )
31 {
32 return new obtype();
33 }
34
35 template<class keytype, class obtype>
36 void __cacheStoreFilesStore( Bu::Stream &s, obtype &rObj,
37 const keytype & )
38 {
39 Bu::Archive ar( s, Bu::Archive::save );
40 ar << rObj;
41 }
42
43 template<class keytype, class obtype>
44 obtype *__cacheStoreFilesLoad( Bu::Stream &s, const keytype &key )
45 {
46 obtype *pObj = __cacheStoreFilesAlloc<keytype, obtype>( key );
47 Bu::Archive ar( s, Bu::Archive::load );
48 ar >> (*pObj);
49 return pObj;
50 }
51
52 template<class keytype, class obtype>
53 class CacheStoreFiles : public CacheStore<keytype, obtype>
54 {
55 public:
56 CacheStoreFiles( const Bu::FString &sPrefix ) :
57 sPrefix( sPrefix )
58 {
59 if( access( sPrefix.getStr(), W_OK|R_OK|X_OK ) )
60 {
61 mkdir( sPrefix.getStr(), 0755 );
62 }
63 }
64
65 virtual ~CacheStoreFiles()
66 {
67 }
68
69 virtual obtype *load( const keytype &key )
70 {
71 Bu::MemBuf mb;
72 Bu::Formatter f( mb );
73 f << sPrefix << "/" << key;
74 Bu::File fIn( mb.getString(), Bu::File::Read );
75 obtype *pOb = __cacheStoreFilesLoad<keytype, obtype>( fIn, key );
76 return pOb;
77 }
78
79 virtual void unload( obtype *pObj, const keytype &key )
80 {
81 delete pObj;
82 }
83
84 virtual keytype create( obtype *pSrc )
85 {
86 keytype key = __cacheGetKey<keytype, obtype>( pSrc );
87 Bu::MemBuf mb;
88 Bu::Formatter f( mb );
89 f << sPrefix << "/" << key;
90
91 Bu::File fTouch( mb.getString(), Bu::File::WriteNew );
92
93 return key;
94 }
95
96 virtual void sync()
97 {
98 }
99
100 virtual void sync( obtype *pSrc, const keytype &key )
101 {
102 Bu::MemBuf mb;
103 Bu::Formatter f( mb );
104 f << sPrefix << "/" << key;
105
106 Bu::File fOut( mb.getString(), Bu::File::WriteNew );
107 __cacheStoreFilesStore<keytype, obtype>( fOut, *pSrc, key );
108 }
109
110 virtual void destroy( obtype *pObj, const keytype &key )
111 {
112 Bu::MemBuf mb;
113 Bu::Formatter f( mb );
114 f << sPrefix << "/" << key;
115
116 unlink( mb.getString().getStr() );
117 delete pObj;
118 }
119
120 virtual void destroy( const keytype &key )
121 {
122 Bu::MemBuf mb;
123 Bu::Formatter f( mb );
124 f << sPrefix << "/" << key;
125
126 unlink( mb.getString().getStr() );
127 }
128
129 virtual bool has( const keytype &key )
130 {
131 Bu::MemBuf mb;
132 Bu::Formatter f( mb );
133 f << sPrefix << "/" << key;
134
135 return access( mb.getString().getStr(), F_OK ) == 0;
136 }
137
138 virtual Bu::List<keytype> getKeys()
139 {
140 DIR *dir = opendir( sPrefix.getStr() );
141 struct dirent *de;
142 Bu::List<keytype> lKeys;
143
144 while( (de = readdir( dir ) ) )
145 {
146 if( de->d_type != DT_REG )
147 continue;
148
149 keytype tmp;
150 Bu::MemBuf mb( de->d_name );
151 Bu::Formatter f( mb );
152 try
153 {
154 f >> tmp;
155 }
156 catch( Bu::ExceptionBase &e )
157 {
158 Bu::sio << "Parse error in dir-scan: " << e.what()
159 << Bu::sio.nl;
160 }
161 lKeys.append( tmp );
162 }
163 closedir( dir );
164
165 return lKeys;
166 }
167
168 virtual int getSize()
169 {
170 DIR *dir = opendir( sPrefix.getStr() );
171 struct dirent *de;
172 int iCount = 0;
173
174 while( (de = readdir( dir ) ) )
175 {
176 if( de->d_type != DT_REG )
177 continue;
178
179 iCount++;
180 }
181 closedir( dir );
182
183 return iCount;
184 }
185
186 private:
187 Bu::FString sPrefix;
188 };
189
190};
191
192#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 )
70 iLeft -= iCopy; 70 iLeft -= iCopy;
71 pBuf += iCopy; 71 pBuf += iCopy;
72 iTotalSize -= iCopy; 72 iTotalSize -= iCopy;
73 sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; 73// sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl;
74 } 74 }
75 75
76 return nBytes - iLeft; 76 return nBytes - iLeft;
77} 77}
78 78
79size_t QueueBuf::peek( void *pBuf, size_t nBytes ) 79size_t Bu::QueueBuf::peek( void *pRawBuf, size_t nBytes )
80{ 80{
81 if( nBytes <= 0 ) 81 if( nBytes <= 0 )
82 return 0; 82 return 0;
@@ -88,31 +88,33 @@ size_t QueueBuf::peek( void *pBuf, size_t nBytes )
88 char *pBuf = (char *)pRawBuf; 88 char *pBuf = (char *)pRawBuf;
89 89
90 int iTmpReadOffset = iReadOffset; 90 int iTmpReadOffset = iReadOffset;
91 int iTmpRemSize = iTotalSize; 91 size_t iTmpRemSize = iTotalSize;
92 BlockList::iterator iBlock = lBlocks.begin();
92 while( iLeft > 0 && iTmpRemSize > 0 ) 93 while( iLeft > 0 && iTmpRemSize > 0 )
93 { 94 {
94
95 // Switching to use temp variables instead of iReadOffset and iTotalSize 95 // Switching to use temp variables instead of iReadOffset and iTotalSize
96 if( iReadOffset == iBlockSize ) 96 if( iTmpReadOffset == iBlockSize )
97 { 97 {
98 if( lBlocks.isEmpty() ) 98 iBlock++;
99 if( iBlock == lBlocks.end() )
99 { 100 {
100 return nBytes-iLeft; 101 return nBytes-iLeft;
101 } 102 }
102 iReadOffset = 0; 103 iTmpReadOffset = 0;
103 } 104 }
104 char *pBlock = lBlocks.first(); 105 char *pBlock = *iBlock;
105 size_t iCopy = iBlockSize-iReadOffset; 106 size_t iCopy = iBlockSize-iTmpReadOffset;
106 if( iLeft < iCopy ) 107 if( iLeft < iCopy )
107 iCopy = iLeft; 108 iCopy = iLeft;
108 if( iTotalSize < iCopy ) 109 if( iTmpRemSize < iCopy )
109 iCopy = iTotalSize; 110 iCopy = iTmpRemSize;
110 memcpy( pBuf, pBlock+iReadOffset, iCopy ); 111 memcpy( pBuf, pBlock+iTmpReadOffset, iCopy );
111 iReadOffset += iCopy; 112 iTmpReadOffset += iCopy;
112 iLeft -= iCopy; 113 iLeft -= iCopy;
113 pBuf += iCopy; 114 pBuf += iCopy;
114 iTotalSize -= iCopy; 115 iTmpRemSize -= iCopy;
115 sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; 116// sio << "Read (peek) " << iCopy << " bytes, new temp size: "
117// << iTmpRemSize << sio.nl;
116 } 118 }
117 119
118 return nBytes - iLeft; 120 return nBytes - iLeft;
@@ -147,7 +149,8 @@ size_t Bu::QueueBuf::write( const void *pRawBuf, size_t nBytes )
147 iLeft -= iCopy; 149 iLeft -= iCopy;
148 pBuf += iCopy; 150 pBuf += iCopy;
149 iTotalSize += iCopy; 151 iTotalSize += iCopy;
150 sio << "Wrote " << iCopy << " bytes, new size: " << iTotalSize << sio.nl; 152// sio << "Wrote " << iCopy << " bytes, new size: " << iTotalSize
153// << sio.nl;
151 } 154 }
152 155
153 return nBytes; 156 return nBytes;
@@ -158,8 +161,27 @@ long Bu::QueueBuf::tell()
158 return -1; 161 return -1;
159} 162}
160 163
161void Bu::QueueBuf::seek( long ) 164void Bu::QueueBuf::seek( long iAmnt )
162{ 165{
166 if( iAmnt <= 0 )
167 return;
168
169 if( iAmnt >= iTotalSize )
170 {
171// sio << "seek: clear all data (" << iAmnt << ">=" << iTotalSize
172// << ")." << sio.nl;
173 close();
174 return;
175 }
176
177 iReadOffset += iAmnt;
178 iTotalSize -= iAmnt;
179 while( iReadOffset >= iBlockSize )
180 {
181 removeBlock();
182 iReadOffset -= iBlockSize;
183// sio << "seek: removal step (" << iReadOffset << ")" << sio.nl;
184 }
163} 185}
164 186
165void Bu::QueueBuf::setPos( long ) 187void Bu::QueueBuf::setPos( long )
@@ -221,13 +243,13 @@ void Bu::QueueBuf::setBlocking( bool )
221void Bu::QueueBuf::addBlock() 243void Bu::QueueBuf::addBlock()
222{ 244{
223 lBlocks.append( new char[iBlockSize] ); 245 lBlocks.append( new char[iBlockSize] );
224 sio << "Added new block." << sio.nl; 246// sio << "Added new block." << sio.nl;
225} 247}
226 248
227void Bu::QueueBuf::removeBlock() 249void Bu::QueueBuf::removeBlock()
228{ 250{
229 delete[] lBlocks.first(); 251 delete[] lBlocks.first();
230 lBlocks.erase( lBlocks.begin() ); 252 lBlocks.erase( lBlocks.begin() );
231 sio << "Removed block." << sio.nl; 253// sio << "Removed block." << sio.nl;
232} 254}
233 255
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 @@
1#include <bu/list.h>
2#include <bu/sio.h>
3
4using namespace Bu;
5
6int main()
7{
8 List<int64_t> lInt;
9
10 lInt.append( 512 );
11 lInt.append( 1024 );
12 lInt.append( 4096 );
13 lInt.append( 12 );
14 lInt.erase( 12 );
15 lInt.append( 12 );
16 lInt.erase( 12 );
17 lInt.append( 12 );
18}
19
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()
13 qb.write( src, 60 ); 13 qb.write( src, 60 );
14 } 14 }
15 15
16 char buf[11]; 16 char buf[11], bufp[11];
17 while( !qb.isEos() ) 17 while( !qb.isEos() )
18 { 18 {
19 buf[qb.read( buf, 9 )] = '\0'; 19 int iAmntPeek = qb.peek( bufp, 9 );
20 sio << "Read: >>" << buf << "<<" << sio.nl; 20 int iAmntRead = qb.read( buf, 9 );
21 if( iAmntPeek != iAmntRead )
22 sio << "Differ: " << iAmntPeek << " vs " << iAmntRead << sio.nl;
23 buf[iAmntRead] = '\0';
24 bufp[iAmntPeek] = '\0';
25 if( memcmp( buf, bufp, iAmntPeek ) )
26 {
27 sio << "Buffers differ" << sio.nl
28 << " " << buf << sio.nl
29 << " " << bufp << sio.nl;
30 }
31 else
32 sio << "Read: >>" << buf << "<<" << sio.nl;
33 }
34
35 sio << sio.nl << sio.nl << sio.nl << "Seek test:" << sio.nl << sio.nl;
36
37 for( int j = 0; j < 5; j++ )
38 {
39 qb.write( src, 25 );
40 qb.write( src+10, 25 );
41 }
42
43 char bufa[26];
44 char bufb[26];
45 ::memcpy( bufb, src+10, 15 );
46 ::memcpy( bufb+15, src+10, 10 );
47 bufb[25] = '\0';
48 sio << "Comparing to '" << bufb << "'" << sio.nl;
49 qb.seek( 10 );
50 while( !qb.isEos() )
51 {
52 bufa[qb.read( bufa, 25 )] = '\0';
53 qb.seek( 25 );
54 if( memcmp( bufa, bufb, 25 ) )
55 sio << "Differ?" << sio.nl;
56 sio << "=== '" << bufa << "' == '" << bufb << "'" << sio.nl;
21 } 57 }
22} 58}
23 59