aboutsummaryrefslogtreecommitdiff
path: root/src/cachestorenids.h
blob: 40213cd374ec79c7ff660142aed9e1e07b8f0876 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#ifndef BU_CACHE_STORE_NIDS_H
#define BU_CACHE_STORE_NIDS_H

#include "bu/fstring.h"
#include "bu/stream.h"
#include "bu/nids.h"
#include "bu/nidsstream.h"
#include "bu/cachestore.h"

#include "bu/file.h"

namespace Bu
{
	template<class obtype, class keytype>
	keytype __cacheGetKey( const obtype *pObj );

	template<class obtype, class keytype>
	obtype *__cacheStoreNidsAlloc( const keytype &key )
	{
		return new obtype();
	}

	template<class obtype, class keytype>
	void __cacheStoreNidsStore( Bu::Stream &s, obtype &rObj,
			const keytype & )
	{
		Bu::Archive ar( s, Bu::Archive::save );
		ar << rObj;
	}

	template<class obtype, class keytype>
	obtype *__cacheStoreNidsLoad( Bu::Stream &s, const keytype &key )
	{
		obtype *pObj = __cacheStoreNidsAlloc<obtype, keytype>( key );
		Bu::Archive ar( s, Bu::Archive::load );
		ar >> (*pObj);
		return pObj;
	}

	template<class obtype, class keytype>
	class CacheStoreNids : public CacheStore<obtype, keytype>
	{
	public:
		CacheStoreNids( Bu::Stream &sArch,
			int iBlockSize=1024, int iPreAllocate=1 ) :
			nStore( sArch )
		{
			try
			{
				nStore.initialize();
				NidsStream ns = nStore.openStream( 0 );
				Bu::Archive ar( ns, Bu::Archive::load );
				ar >> hId;
			}
			catch( Bu::NidsException &e )
			{
				nStore.initialize( iBlockSize, iPreAllocate );
				int iStream = nStore.createStream();
				if( iStream != 0 )
					printf("That's...horrible...id = %d.\n\n", iStream );
				NidsStream ns = nStore.openStream( 0 );
				Bu::Archive ar( ns, Bu::Archive::save );
				ar << hId;
			}
		}

		virtual ~CacheStoreNids()
		{
			NidsStream ns = nStore.openStream( 0 );
			Bu::Archive ar( ns, Bu::Archive::save );
			ar << hId;
		}
		
		virtual obtype *load( const keytype &key )
		{
			int iStream = hId.get( key );
			NidsStream ns = nStore.openStream( iStream );
			obtype *pOb = __cacheStoreNidsLoad<obtype, keytype>( ns, key );
			return pOb;
		}

		virtual void unload( obtype *pObj, const keytype &key )
		{
			int iStream = hId.get( key );
			NidsStream ns = nStore.openStream( iStream );
			__cacheStoreNidsStore<obtype, keytype>( ns, *pObj, key );
			delete pObj;
		}

		virtual keytype create( obtype *pSrc )
		{
			keytype key = __cacheGetKey<obtype,keytype>( pSrc );
			int iStream = nStore.createStream();
			hId.insert( key, iStream );
			NidsStream ns = nStore.openStream( iStream );
			__cacheStoreNidsStore<obtype, keytype>( ns, *pSrc, key );
			return key;
		}

		virtual void destroy( obtype *pObj, const keytype &key )
		{
			int iStream = hId.get( key );
			nStore.deleteStream( iStream );
			hId.erase( key );
			delete pObj;
		}

		virtual Bu::List<keytype> getKeys()
		{
			return hId.getKeys();
		}

	private:
		Nids nStore;
		typedef Bu::Hash<keytype, long> NidHash;
		NidHash hId;
	};
};

#endif