aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2024-11-06 16:45:09 -0800
committerMike Buland <mike@xagasoft.com>2024-11-06 16:45:09 -0800
commit6c066b6bbd4a44ae7c5874abf6bd3a3e04f76b88 (patch)
treed6abea40ac9b1a194ab06a52e341b0452918ae40
parent700d4bbcbf59c4447becbab21a6aa7204a8da2f4 (diff)
downloadlibbu++-6c066b6bbd4a44ae7c5874abf6bd3a3e04f76b88.tar.gz
libbu++-6c066b6bbd4a44ae7c5874abf6bd3a3e04f76b88.tar.bz2
libbu++-6c066b6bbd4a44ae7c5874abf6bd3a3e04f76b88.tar.xz
libbu++-6c066b6bbd4a44ae7c5874abf6bd3a3e04f76b88.zip
Tests are back, minor fixes.
There is a cache tracking bug exposed in cachedel test, it is unclear if this is a regression yet.
-rw-r--r--src/stable/myriad.cpp22
-rw-r--r--src/tests/cache.cpp289
-rw-r--r--src/tests/cachedel.cpp291
-rw-r--r--src/tests/mfstest.cpp88
-rw-r--r--src/unstable/myriadcache.h6
5 files changed, 683 insertions, 13 deletions
diff --git a/src/stable/myriad.cpp b/src/stable/myriad.cpp
index 492676e..53250c2 100644
--- a/src/stable/myriad.cpp
+++ b/src/stable/myriad.cpp
@@ -152,19 +152,21 @@ void Bu::Myriad::erase( Bu::Myriad::StreamId iStream )
152 "No such stream exists."); 152 "No such stream exists.");
153 } 153 }
154 Stream *pStream = hStream.get( iStream ); 154 Stream *pStream = hStream.get( iStream );
155 Bu::MutexLocker sl( pStream->mAccess );
156 if( pStream->iOpenCount > 0 )
157 { 155 {
158 throw Bu::MyriadException( Bu::MyriadException::streamOpen, 156 Bu::MutexLocker sl( pStream->mAccess );
159 "Cannot currently erase a stream while it is open."); 157 if( pStream->iOpenCount > 0 )
160 } 158 {
159 throw Bu::MyriadException( Bu::MyriadException::streamOpen,
160 "Cannot currently erase a stream while it is open.");
161 }
161 162
162 for( Bu::Array<int32_t>::iterator i = pStream->aBlocks.begin(); i; i++ ) 163 for( Bu::Array<int32_t>::iterator i = pStream->aBlocks.begin(); i; i++ )
163 { 164 {
164 releaseBlock( *i, false ); 165 releaseBlock( *i, false );
166 }
167 pStream->aBlocks.clear();
168 hStream.erase( iStream );
165 } 169 }
166 pStream->aBlocks.clear();
167 hStream.erase( iStream );
168 delete pStream; 170 delete pStream;
169} 171}
170 172
diff --git a/src/tests/cache.cpp b/src/tests/cache.cpp
new file mode 100644
index 0000000..4751559
--- /dev/null
+++ b/src/tests/cache.cpp
@@ -0,0 +1,289 @@
1#include "bu/myriadcache.h"
2#include "bu/uuid.h"
3#include "bu/string.h"
4#include "bu/sio.h"
5
6class Something : public Bu::CacheObject<Bu::Uuid, Something>
7{
8friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Something &s );
9friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Something &s );
10public:
11 Something()
12 {
13 }
14
15 Something( const Bu::String &sName ) :
16 uId( Bu::Uuid::generate() ),
17 sName( sName )
18 {
19 }
20
21 virtual ~Something()
22 {
23 }
24
25 virtual Bu::Uuid getKey() const
26 {
27 return uId;
28 }
29
30 Bu::String getName() const
31 {
32 return sName;
33 }
34
35 void setName( const Bu::String &sNewName )
36 {
37 sName = sNewName;
38 changed();
39 }
40
41 virtual Bu::String toString() const=0;
42
43private:
44 Bu::Uuid uId;
45 Bu::String sName;
46};
47
48class SubSomethingA : public Something
49{
50friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingA &s );
51friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingA &s );
52public:
53 SubSomethingA()
54 {
55 }
56
57 SubSomethingA( const Bu::String &sName, int iNumber ) :
58 Something( sName ),
59 iNumber( iNumber )
60 {
61 }
62
63 virtual Bu::String toString() const
64 {
65 return Bu::String("[typeA] %1 (%2)").arg( getName() ).arg( iNumber );
66 }
67
68private:
69 int iNumber;
70};
71
72class SubSomethingB : public Something
73{
74friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingB &s );
75friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingB &s );
76public:
77 SubSomethingB()
78 {
79 }
80
81 SubSomethingB( const Bu::String &sName, const Bu::String &sString ) :
82 Something( sName ),
83 sString( sString )
84 {
85 }
86
87 virtual Bu::String toString() const
88 {
89 return Bu::String("[typeB] %1 (%2)").arg( getName() ).arg( sString );
90 }
91
92private:
93 Bu::String sString;
94};
95
96Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Something &s )
97{
98 return ar >> s.uId >> s.sName;
99}
100
101Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Something &s )
102{
103 return ar << s.uId << s.sName;
104}
105
106Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingA &s )
107{
108 return ar >> (Something &)s >> s.iNumber;
109}
110
111Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingA &s )
112{
113 return ar << (Something &)s << s.iNumber;
114}
115
116Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingB &s )
117{
118 return ar >> (Something &)s >> s.sString;
119}
120
121Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingB &s )
122{
123 return ar << (Something &)s << s.sString;
124}
125
126namespace Bu
127{
128 template<>
129 void _cacheObjectSave<const Something>( Bu::Stream &s, const Something *pObject )
130 {
131 Bu::Archive ar( s, Bu::Archive::save );
132 if( typeid(*pObject) == typeid(SubSomethingA) )
133 {
134 ar << (uint8_t)1 << (SubSomethingA &)*pObject;
135 }
136 else if( typeid(*pObject) == typeid(SubSomethingB) )
137 {
138 ar << (uint8_t)2 << (SubSomethingB &)*pObject;
139 }
140 else
141 {
142 Bu::println("Not a recognized type!");
143 throw Bu::ExceptionBase("Not recognized type!");
144 }
145 }
146
147 template<>
148 Something *_cacheObjectLoad<Bu::Uuid, Something>( Bu::CacheObject<Bu::Uuid, Something>::Initializer &initObj, const Bu::Uuid &rKey, Bu::Stream &s )
149 {
150 Bu::Archive ar( s, Bu::Archive::load );
151 uint8_t uType;
152 ar >> uType;
153 switch( uType )
154 {
155 case 1:
156 {
157 SubSomethingA *ret = initObj(new SubSomethingA());
158 ar >> *ret;
159 return ret;
160 }
161 break;
162
163 case 2:
164 {
165 SubSomethingB *ret = initObj(new SubSomethingB());
166 ar >> *ret;
167 return ret;
168 }
169 break;
170
171 default:
172 throw Bu::ExceptionBase("Flagrant error! Invalid type!");
173 }
174
175 return NULL;
176 }
177}
178
179typedef Bu::CachePtr<Bu::Uuid, Something> SomethingPtr;
180typedef Bu::CachePtr<Bu::Uuid, SubSomethingA, Something> SomethingAPtr;
181typedef Bu::CachePtr<Bu::Uuid, SubSomethingB, Something> SomethingBPtr;
182typedef Bu::MyriadCache<Bu::Uuid, Something> SomethingCache;
183
184int main( int, char *[] )
185{
186 Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite);
187 SomethingCache c( fStore );
188
189 SomethingPtr ptr;
190 if( time(NULL)%2 )
191 ptr = c.insert( new SubSomethingA("Hello", 55) ).cast<Something>();
192 else
193 ptr = c.insert( new SubSomethingB("Goodbye", "Things") ).cast<Something>();
194
195 Bu::println("Something[%1]: %2").
196 arg( ptr.getKey() ).
197 arg( ptr->getName() );
198
199 SomethingCache::KeyList lKeys = c.getKeys();
200 Bu::println("Count: %1").arg( lKeys.getSize() );
201 for( SomethingCache::KeyList::iterator i = lKeys.begin(); i; i++ )
202 {
203 Bu::println(" - %1: '%2'").arg( *i ).arg( c.get( *i )->toString() );
204 }
205 Bu::println("Count: %1").arg( c.getSize() );
206
207 SomethingPtr p2 = c.get( ptr.getKey() );
208 Bu::println("%1 == %2").arg( p2->getName() ).arg( ptr->getName() );
209 SomethingPtr p3 = ptr.cast<Something>();
210 Bu::println("%1: %2").arg( p3.getKey() ).arg( p3->getName() );
211
212 return 0;
213}
214
215/*
216int main( int argc, char *argv[] )
217{
218 Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite);
219 SomethingCache c( fStore );
220
221 for( int j = 1; j < argc; j++ )
222 {
223 SomethingPtr ptr = c.insert( new Something(argv[j]) );
224
225 Bu::println("Something[%1]: %2").
226 arg( ptr.getKey() ).
227 arg( ptr->getName() );
228 }
229
230 SomethingCache::KeyList lKeys = c.getKeys();
231 Bu::println("Count: %1").arg( lKeys.getSize() );
232 int j = 0;
233 for( SomethingCache::KeyList::iterator i = lKeys.begin(); i; i++ )
234 {
235 Bu::println(" - %1: '%2'").arg( *i ).arg( c.get( *i )->getName() );
236 if( ((j++)%2) )
237 c.erase( *i );
238 }
239 Bu::println("Count: %1").arg( c.getSize() );
240
241 c._debug();
242
243 SomethingPtr p2;
244 SomethingPtr p1( c.get( lKeys.first() ) );
245
246 c._debug();
247
248 {
249 SomethingPtr p2( p1 );
250 c._debug();
251 }
252
253 c._debug();
254
255 p2 = p1;
256
257 c._debug();
258
259 p1.unbind();
260
261 c._debug();
262
263 Bu::println("Name: %1").arg( p1->getName() );
264
265 p1.unbind();
266 p1.lock();
267 p1.unlock();
268
269 c._debug();
270
271 SomethingPtr p3 = c.getLazy( lKeys.first() );
272
273 c._debug();
274
275 {
276 SomethingPtr::Locker l( p3 );
277
278 Bu::println("Name again: %1").arg( p3->getName() );
279
280 p3->setName( p3->getName() + " - again" );
281 }
282
283 c.sync();
284
285 c._debug();
286
287 return 0;
288}
289*/
diff --git a/src/tests/cachedel.cpp b/src/tests/cachedel.cpp
new file mode 100644
index 0000000..3fa3e86
--- /dev/null
+++ b/src/tests/cachedel.cpp
@@ -0,0 +1,291 @@
1#include "bu/myriadcache.h"
2#include "bu/uuid.h"
3#include "bu/string.h"
4#include "bu/sio.h"
5#include "bu/membuf.h"
6
7class Something : public Bu::CacheObject<Bu::Uuid, Something>
8{
9friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Something &s );
10friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Something &s );
11public:
12 Something()
13 {
14 }
15
16 Something( const Bu::String &sName ) :
17 uId( Bu::Uuid::generate() ),
18 sName( sName )
19 {
20 }
21
22 virtual ~Something()
23 {
24 }
25
26 virtual Bu::Uuid getKey() const
27 {
28 return uId;
29 }
30
31 Bu::String getName() const
32 {
33 return sName;
34 }
35
36 void setName( const Bu::String &sNewName )
37 {
38 sName = sNewName;
39 changed();
40 }
41
42 virtual Bu::String toString() const=0;
43
44private:
45 Bu::Uuid uId;
46 Bu::String sName;
47};
48
49class SubSomethingA : public Something
50{
51friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingA &s );
52friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingA &s );
53public:
54 SubSomethingA()
55 {
56 }
57
58 SubSomethingA( const Bu::String &sName, int iNumber ) :
59 Something( sName ),
60 iNumber( iNumber )
61 {
62 }
63
64 virtual Bu::String toString() const
65 {
66 return Bu::String("[typeA] %1 (%2)").arg( getName() ).arg( iNumber );
67 }
68
69private:
70 int iNumber;
71};
72
73class SubSomethingB : public Something
74{
75friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingB &s );
76friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingB &s );
77public:
78 SubSomethingB()
79 {
80 }
81
82 SubSomethingB( const Bu::String &sName, const Bu::String &sString ) :
83 Something( sName ),
84 sString( sString )
85 {
86 }
87
88 virtual Bu::String toString() const
89 {
90 return Bu::String("[typeB] %1 (%2)").arg( getName() ).arg( sString );
91 }
92
93private:
94 Bu::String sString;
95};
96
97Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Something &s )
98{
99 return ar >> s.uId >> s.sName;
100}
101
102Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Something &s )
103{
104 return ar << s.uId << s.sName;
105}
106
107Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingA &s )
108{
109 return ar >> (Something &)s >> s.iNumber;
110}
111
112Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingA &s )
113{
114 return ar << (Something &)s << s.iNumber;
115}
116
117Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, SubSomethingB &s )
118{
119 return ar >> (Something &)s >> s.sString;
120}
121
122Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const SubSomethingB &s )
123{
124 return ar << (Something &)s << s.sString;
125}
126
127namespace Bu
128{
129 template<>
130 void _cacheObjectSave<const Something>( Bu::Stream &s, const Something *pObject )
131 {
132 Bu::Archive ar( s, Bu::Archive::save );
133 if( typeid(*pObject) == typeid(SubSomethingA) )
134 {
135 ar << (uint8_t)1 << (SubSomethingA &)*pObject;
136 }
137 else if( typeid(*pObject) == typeid(SubSomethingB) )
138 {
139 ar << (uint8_t)2 << (SubSomethingB &)*pObject;
140 }
141 else
142 {
143 Bu::println("Not a recognized type!");
144 throw Bu::ExceptionBase("Not recognized type!");
145 }
146 }
147
148 template<>
149 Something *_cacheObjectLoad<Bu::Uuid, Something>( Bu::CacheObject<Bu::Uuid, Something>::Initializer &initObj, const Bu::Uuid &rKey, Bu::Stream &s )
150 {
151 Bu::Archive ar( s, Bu::Archive::load );
152 uint8_t uType;
153 ar >> uType;
154 switch( uType )
155 {
156 case 1:
157 {
158 SubSomethingA *ret = initObj(new SubSomethingA());
159 ar >> *ret;
160 return ret;
161 }
162 break;
163
164 case 2:
165 {
166 SubSomethingB *ret = initObj(new SubSomethingB());
167 ar >> *ret;
168 return ret;
169 }
170 break;
171
172 default:
173 throw Bu::ExceptionBase("Flagrant error! Invalid type!");
174 }
175
176 return NULL;
177 }
178}
179
180typedef Bu::CachePtr<Bu::Uuid, Something> SomethingPtr;
181typedef Bu::CachePtr<Bu::Uuid, SubSomethingA, Something> SomethingAPtr;
182typedef Bu::CachePtr<Bu::Uuid, SubSomethingB, Something> SomethingBPtr;
183typedef Bu::MyriadCache<Bu::Uuid, Something> SomethingCache;
184
185int main( int, char *[] )
186{
187 Bu::MemBuf mbStore;
188 SomethingCache c( mbStore );
189
190 SomethingPtr ptr;
191 if( time(NULL)%2 )
192 ptr = c.insert( new SubSomethingA("Hello", 55) ).cast<Something>();
193 else
194 ptr = c.insert( new SubSomethingB("Goodbye", "Things") ).cast<Something>();
195
196 Bu::Uuid id = ptr.getKey();
197 Bu::println("Something[%1]: %2").
198 arg( ptr.getKey() ).
199 arg( ptr->getName() );
200
201 Bu::println("has %1: %2").arg( id ).arg( c.has( id ) );
202 c.erase( ptr.getKey() );
203 Bu::println("has %1: %2").arg( id ).arg( c.has( id ) );
204 SomethingPtr b = ptr;
205
206 SomethingPtr p2 = c.insert( new SubSomethingA("new test", 123) ).cast<Something>();
207 id = p2.getKey();
208 Bu::println("p2 %1: %2").arg( id ).arg( c.has( id ) );
209 p2.unbind();
210 Bu::println("p2 %1: %2").arg( id ).arg( c.has( id ) );
211 c.erase( id );
212 Bu::println("p2 %1: %2").arg( id ).arg( c.has( id ) );
213
214 return 0;
215}
216
217/*
218int main( int argc, char *argv[] )
219{
220 Bu::File fStore("test.myr", Bu::File::Create|Bu::File::ReadWrite);
221 SomethingCache c( fStore );
222
223 for( int j = 1; j < argc; j++ )
224 {
225 SomethingPtr ptr = c.insert( new Something(argv[j]) );
226
227 Bu::println("Something[%1]: %2").
228 arg( ptr.getKey() ).
229 arg( ptr->getName() );
230 }
231
232 SomethingCache::KeyList lKeys = c.getKeys();
233 Bu::println("Count: %1").arg( lKeys.getSize() );
234 int j = 0;
235 for( SomethingCache::KeyList::iterator i = lKeys.begin(); i; i++ )
236 {
237 Bu::println(" - %1: '%2'").arg( *i ).arg( c.get( *i )->getName() );
238 if( ((j++)%2) )
239 c.erase( *i );
240 }
241 Bu::println("Count: %1").arg( c.getSize() );
242
243 c._debug();
244
245 SomethingPtr p2;
246 SomethingPtr p1( c.get( lKeys.first() ) );
247
248 c._debug();
249
250 {
251 SomethingPtr p2( p1 );
252 c._debug();
253 }
254
255 c._debug();
256
257 p2 = p1;
258
259 c._debug();
260
261 p1.unbind();
262
263 c._debug();
264
265 Bu::println("Name: %1").arg( p1->getName() );
266
267 p1.unbind();
268 p1.lock();
269 p1.unlock();
270
271 c._debug();
272
273 SomethingPtr p3 = c.getLazy( lKeys.first() );
274
275 c._debug();
276
277 {
278 SomethingPtr::Locker l( p3 );
279
280 Bu::println("Name again: %1").arg( p3->getName() );
281
282 p3->setName( p3->getName() + " - again" );
283 }
284
285 c.sync();
286
287 c._debug();
288
289 return 0;
290}
291*/
diff --git a/src/tests/mfstest.cpp b/src/tests/mfstest.cpp
new file mode 100644
index 0000000..813ef8e
--- /dev/null
+++ b/src/tests/mfstest.cpp
@@ -0,0 +1,88 @@
1#include <bu/file.h>
2#include <bu/myriadfs.h>
3#include <bu/myriadstream.h>
4#include <bu/sio.h>
5
6class Obstore
7{
8public:
9 Obstore() :
10 fStore("test.mfs", Bu::File::WriteNew|Bu::File::Read ),
11 fsOb( fStore, 1024 )
12 {
13 }
14
15 virtual ~Obstore()
16 {
17 }
18
19 Bu::String getObject( const Bu::String &sPath )
20 {
21 try
22 {
23 Bu::MyriadStream s = fsOb.open(
24 sPath,
25 Bu::MyriadFs::Read
26 );
27 return s.readAll();
28 }
29 catch( Bu::ExceptionBase &e )
30 {
31 Bu::println("Exception opening file: %1").arg( e.what() );
32 return Bu::String();
33 }
34 }
35
36 void storeObject( const Bu::String &sPath, const Bu::String &sData )
37 {
38 for( Bu::String::const_iterator i = sPath.begin()+1; i; i++ )
39 {
40 if( *i == '/' )
41 {
42 Bu::String sChunk( sPath.begin(), i );
43 fsOb.mkDir( sChunk, 0664 );
44 }
45 }
46 try
47 {
48 Bu::MyriadStream s = fsOb.open(
49 sPath,
50 Bu::MyriadFs::Write|Bu::MyriadFs::Create|Bu::MyriadFs::Truncate
51 );
52 s.write( sData );
53 }
54 catch(Bu::ExceptionBase &e )
55 {
56 Bu::println("Exception opening file: %1").arg( e.what() );
57 }
58 }
59
60 Bu::File fStore;
61 Bu::MyriadFs fsOb;
62};
63
64int main( int, char *[] )
65{
66 Obstore os;
67
68 os.storeObject("/killTeamState.json", "This is a json file.");
69 os.storeObject("/appCredentials/local", "App credentials");
70 os.storeObject("/appCredentials/inckybot", "App credentials");
71 os.storeObject("/appCredentials/playwith", "App credentials");
72 os.storeObject("/restreamIo/users", "User data");
73 os.storeObject("/youTube/users", "User data");
74 os.storeObject("/topTippers.json", "{\"people\": [\"sam\", \"joe\", \"bob\"]}");
75 os.storeObject("/wh40kDecks.json", "");
76
77 Bu::MyriadStream s = os.fsOb.open(
78 "/appCredentials/inckybot",
79 Bu::MyriadFs::Write|Bu::MyriadFs::Create|Bu::MyriadFs::Truncate
80 );
81 s.write("Some new credentials, this is a bigger bit of data.");
82
83 os.storeObject("/wh40kDecks.json", "{ \"op\": \"replaceDecks\", \"decks\": { \"lev\": { \"name\": \"Leviathan\", \"primary\": { \"pt\": {\"name\": \"Priority Targets\"}, \"vg\": {\"name\": \"Vital Ground\"}, \"se\": {\"name\": \"Scorched Earth\"}, \"pf\": {\"name\": \"Purge the Foe\"}, \"th\": {\"name\": \"Take and Hold\"}, \"sd\": {\"name\": \"Supply Drop\"}, \"tr\": {\"name\": \"The Ritual\"}, \"ds\": {\"name\": \"Deploy Servo-Skulls\"}, \"sp\": {\"name\": \"Sites of Power\"}, }, \"secondary\": { \"tt\": {\"name\": \"A Tempting Target\"}, \"ad\": {\"name\": \"Area Denial\"}, \"as\": {\"name\": \"Assassination\"}, \"be\": {\"name\": \"Behind Enemy Lines\"}, \"bd\": {\"name\": \"Bring It Down\"}, \"ce\": {\"name\": \"Capture Enemy Outpost\"}, \"cl\": {\"name\": \"Cleanse\"}, \"ds\": {\"name\": \"Defend Stronghold\"}, \"dt\": {\"name\": \"Deploy Teleport Homer\"}, \"ef\": {\"name\": \"Engage On All Fronts\"}, \"eb\": {\"name\": \"Extend Battle Lines\"}, \"is\": {\"name\": \"Investigate Signals\"}, \"np\": {\"name\": \"No Prisoners\"}, \"of\": {\"name\": \"Overwhelming Force\"}, \"sl\": {\"name\": \"Secure No Man’s Land\"}, \"sh\": {\"name\": \"Storm Hostile Objective\"}, }, \"gambit\": { \"dt\": {\"name\": \"Delaying Tactics\"}, \"ee\": {\"name\": \"Emergency Evacuation\"}, \"oc\": {\"name\": \"Orbital Strike Coordinates\"}, \"pp\": {\"name\": \"Proceed As Planned\"}, }, \"missionRule\": { \"cr\": {\"name\": \"Chilling Rain\"}, \"sc\": {\"name\": \"Sweep and Clear\"}, \"hs\": {\"name\": \"Hidden Supplies\"}, \"mi\": {\"name\": \"Minefields\"}, \"to\": {\"name\": \"Targets of Opportunity\"}, \"sf\": {\"name\": \"Scrambler Fields\"}, \"dr\": {\"name\": \"Delayed Reserves\"}, \"cb\": {\"name\": \"Chosen Battlefield\"}, \"mb\": {\"name\": \"Maelstrom of Battle\"}, \"sl\": {\"name\": \"Supply Lines\"}, \"si\": {\"name\": \"Secret Intel\"}, \"vs\": {\"name\": \"Vox Static\"}, }, }, } }");
84 os.storeObject("/wh40kState.json", "{\"cards\": \"hello\"}");
85
86 return 0;
87}
88
diff --git a/src/unstable/myriadcache.h b/src/unstable/myriadcache.h
index f71f9b5..289ab05 100644
--- a/src/unstable/myriadcache.h
+++ b/src/unstable/myriadcache.h
@@ -108,13 +108,13 @@ namespace Bu
108 const keytype &k 108 const keytype &k
109 ) 109 )
110 { 110 {
111 Bu::MyriadStream ms = mStore.openStream( hIndex.get( k ) ); 111 Bu::MyriadStream ms = mStore.open( hIndex.get( k ), Bu::Myriad::Read );
112 return _cacheObjectLoad<keytype, obtype>( initObj, k, ms ); 112 return _cacheObjectLoad<keytype, obtype>( initObj, k, ms );
113 } 113 }
114 114
115 virtual void _save( const obtype *o ) 115 virtual void _save( const obtype *o )
116 { 116 {
117 Bu::MyriadStream ms = mStore.openStream( hIndex.get( o->getKey() ) ); 117 Bu::MyriadStream ms = mStore.open( hIndex.get( o->getKey() ), Bu::Myriad::WriteNew );
118 _cacheObjectSave( ms, o ); 118 _cacheObjectSave( ms, o );
119 ms.setSize( ms.tell() ); 119 ms.setSize( ms.tell() );
120 120
@@ -127,7 +127,7 @@ namespace Bu
127 if( !bStructureChanged ) 127 if( !bStructureChanged )
128 return; 128 return;
129 129
130 Bu::MyriadStream ms = mStore.openStream( 1 ); 130 Bu::MyriadStream ms = mStore.open( 1, Bu::Myriad::WriteNew );
131 Bu::Archive ar( ms, Bu::Archive::save ); 131 Bu::Archive ar( ms, Bu::Archive::save );
132 ar << (uint8_t)0 << hIndex; 132 ar << (uint8_t)0 << hIndex;
133 ar.close(); 133 ar.close();