summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cachestoremyriad.cpp9
-rw-r--r--src/cachestoremyriad.h156
-rw-r--r--src/myriad.cpp69
-rw-r--r--src/myriad.h4
-rw-r--r--src/tafcomment.cpp7
-rw-r--r--src/tafcomment.h1
-rw-r--r--src/tafgroup.cpp23
-rw-r--r--src/tafgroup.h1
-rw-r--r--src/tafproperty.cpp7
-rw-r--r--src/tafproperty.h1
10 files changed, 258 insertions, 20 deletions
diff --git a/src/cachestoremyriad.cpp b/src/cachestoremyriad.cpp
new file mode 100644
index 0000000..b08aea1
--- /dev/null
+++ b/src/cachestoremyriad.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/cachestoremyriad.h"
9
diff --git a/src/cachestoremyriad.h b/src/cachestoremyriad.h
new file mode 100644
index 0000000..a40ffb2
--- /dev/null
+++ b/src/cachestoremyriad.h
@@ -0,0 +1,156 @@
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_MYRIAD_H
9#define BU_CACHE_STORE_MYRIAD_H
10
11#include "bu/fstring.h"
12#include "bu/stream.h"
13#include "bu/myriad.h"
14#include "bu/cachestore.h"
15#include "bu/myriadstream.h"
16
17#include "bu/archive.h"
18
19#include "bu/sio.h"
20
21namespace Bu
22{
23 template<class keytype, class obtype>
24 keytype __cacheGetKey( const obtype *pObj );
25
26 template<class keytype, class obtype>
27 obtype *__cacheStoreMyriadAlloc( const keytype &key )
28 {
29 return new obtype();
30 }
31
32 template<class keytype, class obtype>
33 void __cacheStoreMyriadStore( Bu::Stream &s, obtype &rObj,
34 const keytype & )
35 {
36 Bu::Archive ar( s, Bu::Archive::save );
37 ar << rObj;
38 }
39
40 template<class keytype, class obtype>
41 obtype *__cacheStoreMyriadLoad( Bu::Stream &s, const keytype &key )
42 {
43 obtype *pObj = __cacheStoreMyriadAlloc<keytype, obtype>( key );
44 Bu::Archive ar( s, Bu::Archive::load );
45 ar >> (*pObj);
46 return pObj;
47 }
48
49 template<class keytype, class obtype>
50 class CacheStoreMyriad : public CacheStore<keytype, obtype>
51 {
52 public:
53 CacheStoreMyriad( Bu::Stream &sArch,
54 int iBlockSize=1024, int iPreAllocate=1 ) :
55 mStore( sArch )
56 {
57 try
58 {
59 mStore.initialize();
60 MyriadStream ns = mStore.openStream( 1 );
61 Bu::Archive ar( ns, Bu::Archive::load );
62 ar >> hId;
63 Bu::sio << hId << Bu::sio.nl;
64 }
65 catch( Bu::MyriadException &e )
66 {
67 mStore.initialize( iBlockSize, iPreAllocate );
68 int iStream = mStore.createStream();
69 if( iStream != 1 )
70 throw Bu::ExceptionBase("That's...horrible...id = %d.\n\n", iStream );
71 MyriadStream ns = mStore.openStream( 1 );
72 Bu::Archive ar( ns, Bu::Archive::save );
73 ar << hId;
74 }
75 }
76
77 virtual ~CacheStoreMyriad()
78 {
79 MyriadStream ns = mStore.openStream( 1 );
80 Bu::Archive ar( ns, Bu::Archive::save );
81 ar << hId;
82 }
83
84 virtual obtype *load( const keytype &key )
85 {
86 int iStream = hId.get( key );
87 MyriadStream ns = mStore.openStream( iStream );
88 obtype *pOb = __cacheStoreMyriadLoad<keytype, obtype>( ns, key );
89 return pOb;
90 }
91
92 virtual void unload( obtype *pObj, const keytype &key )
93 {
94 int iStream = hId.get( key );
95 MyriadStream ns = mStore.openStream( iStream );
96 __cacheStoreMyriadStore<keytype, obtype>( ns, *pObj, key );
97 delete pObj;
98 }
99
100 virtual keytype create( obtype *pSrc )
101 {
102 keytype key = __cacheGetKey<keytype, obtype>( pSrc );
103 int iStream = mStore.createStream();
104 hId.insert( key, iStream );
105 MyriadStream ns = mStore.openStream( iStream );
106 __cacheStoreMyriadStore<keytype, obtype>( ns, *pSrc, key );
107 return key;
108 }
109
110 virtual void sync()
111 {
112 MyriadStream ns = mStore.openStream( 1 );
113 Bu::Archive ar( ns, Bu::Archive::save );
114 ar << hId;
115
116 mStore.sync();
117 }
118
119 virtual void sync( obtype *pSrc, const keytype &key )
120 {
121 int iStream = hId.get( key );
122 MyriadStream ns = mStore.openStream( iStream );
123 __cacheStoreMyriadStore<keytype, obtype>( ns, *pSrc, key );
124 }
125
126 virtual void destroy( obtype *pObj, const keytype &key )
127 {
128 int iStream = hId.get( key );
129 mStore.deleteStream( iStream );
130 hId.erase( key );
131 delete pObj;
132 }
133
134 virtual bool has( const keytype &key )
135 {
136 return hId.has( key );
137 }
138
139 virtual Bu::List<keytype> getKeys()
140 {
141 return hId.getKeys();
142 }
143
144 virtual int getSize()
145 {
146 return hId.getSize();
147 }
148
149 private:
150 Myriad mStore;
151 typedef Bu::Hash<keytype, long> StreamHash;
152 StreamHash hId;
153 };
154};
155
156#endif
diff --git a/src/myriad.cpp b/src/myriad.cpp
index 58270c5..77b481d 100644
--- a/src/myriad.cpp
+++ b/src/myriad.cpp
@@ -34,7 +34,12 @@ Bu::Myriad::Myriad( Bu::Stream &sStore ) :
34 34
35Bu::Myriad::~Myriad() 35Bu::Myriad::~Myriad()
36{ 36{
37 updateHeader(); 37 if( !hActiveBlocks.isEmpty() )
38 {
39 sio << "Bu::Myriad::~Myriad(): Error: There are "
40 << hActiveBlocks.getSize() << " unsynced blocks!" << sio.nl;
41 }
42 sync();
38 43
39 for( StreamArray::iterator i = aStreams.begin(); i; i++ ) 44 for( StreamArray::iterator i = aStreams.begin(); i; i++ )
40 { 45 {
@@ -46,7 +51,13 @@ void Bu::Myriad::sync()
46{ 51{
47 updateHeader(); 52 updateHeader();
48 53
49 // Later, also flush all caches. 54 for( BlockHash::iterator i = hActiveBlocks.begin(); i; i++ )
55 {
56 if( (*i)->bChanged )
57 {
58 syncBlock( *i );
59 }
60 }
50} 61}
51 62
52void Bu::Myriad::initialize() 63void Bu::Myriad::initialize()
@@ -206,16 +217,19 @@ void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate )
206 this->iBlocks = iPreAllocate; 217 this->iBlocks = iPreAllocate;
207 218
208 pStr->iSize = sStore.tell(); 219 pStr->iSize = sStore.tell();
209 sio << "Myriad: Actual end of header stream = " << pStr->iSize << sio.nl; 220// sio << "Myriad: Actual end of header stream = " << pStr->iSize << sio.nl;
210 221
211 pStr->iSize = iHeaderSize; 222 pStr->iSize = iHeaderSize;
212 for( int j = 0; j < iHeaderBlocks; j++ ) 223 for( int j = 0; j < iHeaderBlocks; j++ )
213 { 224 {
214 pStr->aBlocks.append( j ); 225 pStr->aBlocks.append( j );
226 bsBlockUsed.setBit( j );
215 } 227 }
216 228
217 aStreams.append( pStr ); 229 aStreams.append( pStr );
218 230
231 sio << bsBlockUsed.toString() << sio.nl;
232
219 //hStreams.insert( 0, BlockArray( 0 ) ); 233 //hStreams.insert( 0, BlockArray( 0 ) );
220} 234}
221 235
@@ -227,31 +241,36 @@ void Bu::Myriad::updateHeader()
227 char cBuf; 241 char cBuf;
228 int iBuf; 242 int iBuf;
229 243
244 for( StreamArray::iterator i = aStreams.begin(); i; i++ )
245 {
246 sio << "Myriad: Stream " << Fmt(4) << (*i)->iId << ": " << (*i)->aBlocks << sio.nl;
247 }
248
230 // Compute the new size of the header. 249 // Compute the new size of the header.
231 int iHeaderSize = 14 + 8*aStreams.getSize(); 250 int iHeaderSize = 14 + 8*aStreams.getSize();
232 sio << "Myriad: updateHeader: aStreams.getSize() = " << aStreams.getSize() 251// sio << "Myriad: updateHeader: aStreams.getSize() = " << aStreams.getSize()
233 << sio.nl; 252// << sio.nl;
234 for( StreamArray::iterator i = aStreams.begin(); i; i++ ) 253 for( StreamArray::iterator i = aStreams.begin(); i; i++ )
235 { 254 {
236 iHeaderSize += 4*(*i)->aBlocks.getSize(); 255 iHeaderSize += 4*(*i)->aBlocks.getSize();
237 sio << "Myriad: updateHeader: (*i)->aBlocks.getSize() = " 256// sio << "Myriad: updateHeader: (*i)->aBlocks.getSize() = "
238 << (*i)->aBlocks.getSize() << sio.nl; 257// << (*i)->aBlocks.getSize() << sio.nl;
239 } 258 }
240 int iNewBlocks = blkDiv( iHeaderSize, iBlockSize ); 259 int iNewBlocks = blkDiv( iHeaderSize, iBlockSize );
241 while( iNewBlocks > aStreams[0]->aBlocks.getSize() ) 260 while( iNewBlocks > aStreams[0]->aBlocks.getSize() )
242 { 261 {
243 int iBlock = findEmptyBlock(); 262 int iBlock = findEmptyBlock();
244 sio << "Myriad: updateHeader: Appending block " << iBlock 263// sio << "Myriad: updateHeader: Appending block " << iBlock
245 << " to header." << sio.nl; 264// << " to header." << sio.nl;
246 aStreams[0]->aBlocks.append( iBlock ); 265 aStreams[0]->aBlocks.append( iBlock );
247 bsBlockUsed.setBit( iBlock ); 266 bsBlockUsed.setBit( iBlock );
248 iHeaderSize += 4; 267 iHeaderSize += 4;
249 iNewBlocks = blkDiv( iHeaderSize, iBlockSize ); 268 iNewBlocks = blkDiv( iHeaderSize, iBlockSize );
250 } 269 }
251 aStreams[0]->iSize = iHeaderSize; 270 aStreams[0]->iSize = iHeaderSize;
252 sio << "Myriad: updateHeader: iHeaderSize=" << iHeaderSize 271// sio << "Myriad: updateHeader: iHeaderSize=" << iHeaderSize
253 << ", iNewBlocks=" << iNewBlocks << ", curBlocks=" 272// << ", iNewBlocks=" << iNewBlocks << ", curBlocks="
254 << aStreams[0]->aBlocks.getSize() << sio.nl; 273// << aStreams[0]->aBlocks.getSize() << sio.nl;
255 274
256 MyriadStream sHdr( *this, aStreams[0] ); 275 MyriadStream sHdr( *this, aStreams[0] );
257 sHdr.write( Myriad_MAGIC_CODE, 4 ); 276 sHdr.write( Myriad_MAGIC_CODE, 4 );
@@ -296,7 +315,7 @@ int Bu::Myriad::createStream( int iPreAllocate )
296 for( int j = 0; j < iPreAllocate; j++ ) 315 for( int j = 0; j < iPreAllocate; j++ )
297 { 316 {
298 int iFreeBlock = findEmptyBlock(); 317 int iFreeBlock = findEmptyBlock();
299 sio << "Myriad: Adding block " << iFreeBlock << sio.nl; 318// sio << "Myriad: Adding block " << iFreeBlock << sio.nl;
300 pStr->aBlocks.append( iFreeBlock ); 319 pStr->aBlocks.append( iFreeBlock );
301 bsBlockUsed.setBit( iFreeBlock ); 320 bsBlockUsed.setBit( iFreeBlock );
302 } 321 }
@@ -311,7 +330,7 @@ int Bu::Myriad::findEmptyBlock()
311 if( bsBlockUsed.getBit( j ) == false ) 330 if( bsBlockUsed.getBit( j ) == false )
312 return j; 331 return j;
313 } 332 }
314 sio << "Myriad: findEmptyBlock(): No empty blocks, adding new one." << sio.nl; 333// sio << "Myriad: findEmptyBlock(): No empty blocks, adding new one." << sio.nl;
315 334
316 bsBlockUsed.setSize( bsBlockUsed.getSize()+1, false ); 335 bsBlockUsed.setSize( bsBlockUsed.getSize()+1, false );
317 sStore.setPos( iBlockSize*iBlocks ); 336 sStore.setPos( iBlockSize*iBlocks );
@@ -330,6 +349,7 @@ void Bu::Myriad::deleteStream( int /*iID*/ )
330 349
331Bu::MyriadStream Bu::Myriad::openStream( int iId ) 350Bu::MyriadStream Bu::Myriad::openStream( int iId )
332{ 351{
352 sio << "Myriad: Request to open stream: " << iId << sio.nl;
333 return MyriadStream( *this, findStream( iId ) ); 353 return MyriadStream( *this, findStream( iId ) );
334} 354}
335 355
@@ -361,8 +381,8 @@ Bu::Myriad::Stream *Bu::Myriad::findStream( int iId )
361 381
362Bu::Myriad::Block *Bu::Myriad::getBlock( int iBlock ) 382Bu::Myriad::Block *Bu::Myriad::getBlock( int iBlock )
363{ 383{
364 sio << "Myriad: Reading block " << iBlock << ", bytes " 384// sio << "Myriad: Reading block " << iBlock << ", bytes "
365 << iBlockSize*iBlock << "-" << iBlockSize*(iBlock+1) << sio.nl; 385// << iBlockSize*iBlock << "-" << iBlockSize*(iBlock+1) << sio.nl;
366 Block *pBlock = new Block; 386 Block *pBlock = new Block;
367 pBlock->pData = new char[iBlockSize]; 387 pBlock->pData = new char[iBlockSize];
368 sStore.setPos( iBlockSize * iBlock ); 388 sStore.setPos( iBlockSize * iBlock );
@@ -370,6 +390,8 @@ Bu::Myriad::Block *Bu::Myriad::getBlock( int iBlock )
370 pBlock->bChanged = false; 390 pBlock->bChanged = false;
371 pBlock->iBlockIndex = iBlock; 391 pBlock->iBlockIndex = iBlock;
372 392
393 hActiveBlocks.insert( iBlock, pBlock );
394
373 return pBlock; 395 return pBlock;
374} 396}
375 397
@@ -377,14 +399,21 @@ void Bu::Myriad::releaseBlock( Bu::Myriad::Block *pBlock )
377{ 399{
378 if( pBlock == NULL ) 400 if( pBlock == NULL )
379 return; 401 return;
380 sio << "Myriad: Releasing block " << pBlock->iBlockIndex << sio.nl; 402// sio << "Myriad: Releasing block " << pBlock->iBlockIndex << sio.nl;
403 syncBlock( pBlock );
404 hActiveBlocks.erase( pBlock->iBlockIndex );
405 delete[] pBlock->pData;
406 delete pBlock;
407}
408
409void Bu::Myriad::syncBlock( Block *pBlock )
410{
381 if( pBlock->bChanged ) 411 if( pBlock->bChanged )
382 { 412 {
383 sio << "Myriad: - Block changed, writing back to stream." << sio.nl; 413// sio << "Myriad: - Block changed, writing back to stream." << sio.nl;
384 sStore.setPos( iBlockSize * pBlock->iBlockIndex ); 414 sStore.setPos( iBlockSize * pBlock->iBlockIndex );
385 sStore.write( pBlock->pData, iBlockSize ); 415 sStore.write( pBlock->pData, iBlockSize );
416 pBlock->bChanged = false;
386 } 417 }
387 delete[] pBlock->pData;
388 delete pBlock;
389} 418}
390 419
diff --git a/src/myriad.h b/src/myriad.h
index 0344057..8f626a4 100644
--- a/src/myriad.h
+++ b/src/myriad.h
@@ -12,6 +12,7 @@
12#include "bu/bitstring.h" 12#include "bu/bitstring.h"
13#include "bu/exceptionbase.h" 13#include "bu/exceptionbase.h"
14#include "bu/array.h" 14#include "bu/array.h"
15#include "bu/hash.h"
15 16
16namespace Bu 17namespace Bu
17{ 18{
@@ -147,6 +148,7 @@ namespace Bu
147 148
148 Block *getBlock( int iBlock ); 149 Block *getBlock( int iBlock );
149 void releaseBlock( Block *pBlock ); 150 void releaseBlock( Block *pBlock );
151 void syncBlock( Block *pBlock );
150 152
151 private: 153 private:
152 Bu::Stream &sStore; 154 Bu::Stream &sStore;
@@ -155,6 +157,8 @@ namespace Bu
155 int iUsed; 157 int iUsed;
156 Bu::BitString bsBlockUsed; 158 Bu::BitString bsBlockUsed;
157 StreamArray aStreams; 159 StreamArray aStreams;
160 typedef Bu::Hash<int, Block *> BlockHash;
161 BlockHash hActiveBlocks;
158 }; 162 };
159}; 163};
160 164
diff --git a/src/tafcomment.cpp b/src/tafcomment.cpp
index 4e0da9f..77b7ee4 100644
--- a/src/tafcomment.cpp
+++ b/src/tafcomment.cpp
@@ -7,6 +7,13 @@
7 7
8#include "bu/tafcomment.h" 8#include "bu/tafcomment.h"
9 9
10Bu::TafComment::TafComment( const Bu::TafComment &rSrc ) :
11 TafNode( typeComment ),
12 sText( rSrc.sText ),
13 bEOL( rSrc.bEOL )
14{
15}
16
10Bu::TafComment::TafComment( const Bu::FString &sText, bool bEOL ) : 17Bu::TafComment::TafComment( const Bu::FString &sText, bool bEOL ) :
11 TafNode( typeComment ), 18 TafNode( typeComment ),
12 sText( sText ), 19 sText( sText ),
diff --git a/src/tafcomment.h b/src/tafcomment.h
index d1e200f..5b51f99 100644
--- a/src/tafcomment.h
+++ b/src/tafcomment.h
@@ -20,6 +20,7 @@ namespace Bu
20 class TafComment : public TafNode 20 class TafComment : public TafNode
21 { 21 {
22 public: 22 public:
23 TafComment( const Bu::TafComment &rSrc );
23 TafComment( const Bu::FString &sText, bool bEOL=false ); 24 TafComment( const Bu::FString &sText, bool bEOL=false );
24 virtual ~TafComment(); 25 virtual ~TafComment();
25 26
diff --git a/src/tafgroup.cpp b/src/tafgroup.cpp
index 7c1c818..c3f5b1e 100644
--- a/src/tafgroup.cpp
+++ b/src/tafgroup.cpp
@@ -9,6 +9,29 @@
9#include "bu/tafproperty.h" 9#include "bu/tafproperty.h"
10#include "bu/tafcomment.h" 10#include "bu/tafcomment.h"
11 11
12Bu::TafGroup::TafGroup( const TafGroup &rSrc ) :
13 TafNode( typeGroup ),
14 sName( rSrc.sName )
15{
16 for( NodeList::const_iterator i = rSrc.lChildren.begin(); i; i++ )
17 {
18 switch( (*i)->getType() )
19 {
20 case typeGroup:
21 addChild( new TafGroup( *dynamic_cast<const TafGroup *>(*i) ) );
22 break;
23
24 case typeProperty:
25 addChild( new TafProperty( *dynamic_cast<const TafProperty *>(*i) ) );
26 break;
27
28 case typeComment:
29 addChild( new TafComment( *dynamic_cast<const TafComment *>(*i) ) );
30 break;
31 }
32 }
33}
34
12Bu::TafGroup::TafGroup( const Bu::FString &sName ) : 35Bu::TafGroup::TafGroup( const Bu::FString &sName ) :
13 TafNode( typeGroup ), 36 TafNode( typeGroup ),
14 sName( sName ) 37 sName( sName )
diff --git a/src/tafgroup.h b/src/tafgroup.h
index f76e5f9..ed70e8c 100644
--- a/src/tafgroup.h
+++ b/src/tafgroup.h
@@ -32,6 +32,7 @@ namespace Bu
32 typedef Bu::Hash<Bu::FString, GroupList> GroupHash; 32 typedef Bu::Hash<Bu::FString, GroupList> GroupHash;
33 typedef Bu::List<class Bu::TafNode *> NodeList; 33 typedef Bu::List<class Bu::TafNode *> NodeList;
34 34
35 TafGroup( const TafGroup &rSrc );
35 TafGroup( const Bu::FString &sName ); 36 TafGroup( const Bu::FString &sName );
36 virtual ~TafGroup(); 37 virtual ~TafGroup();
37 38
diff --git a/src/tafproperty.cpp b/src/tafproperty.cpp
index 4c7ab28..c847344 100644
--- a/src/tafproperty.cpp
+++ b/src/tafproperty.cpp
@@ -7,6 +7,13 @@
7 7
8#include "bu/tafproperty.h" 8#include "bu/tafproperty.h"
9 9
10Bu::TafProperty::TafProperty( const Bu::TafProperty &rSrc ) :
11 TafNode( typeProperty ),
12 sName( rSrc.sName ),
13 sValue( rSrc.sValue )
14{
15}
16
10Bu::TafProperty::TafProperty( const Bu::FString &sName, const Bu::FString &sValue ) : 17Bu::TafProperty::TafProperty( const Bu::FString &sName, const Bu::FString &sValue ) :
11 TafNode( typeProperty ), 18 TafNode( typeProperty ),
12 sName( sName ), 19 sName( sName ),
diff --git a/src/tafproperty.h b/src/tafproperty.h
index 7dbeee2..62cc517 100644
--- a/src/tafproperty.h
+++ b/src/tafproperty.h
@@ -20,6 +20,7 @@ namespace Bu
20 class TafProperty : public TafNode 20 class TafProperty : public TafNode
21 { 21 {
22 public: 22 public:
23 TafProperty( const Bu::TafProperty &rSrc );
23 TafProperty( const Bu::FString &sName, const Bu::FString &sValue ); 24 TafProperty( const Bu::FString &sName, const Bu::FString &sValue );
24 virtual ~TafProperty(); 25 virtual ~TafProperty();
25 26