summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2008-12-03 17:05:26 +0000
committerMike Buland <eichlan@xagasoft.com>2008-12-03 17:05:26 +0000
commit0bd8b8cf19687229b53e37468dfe36c4217fbbf1 (patch)
tree9597c83c6770473b7dc43b6917a8787f0d4c87c6
parent6f3b85c5af1855e1695885fb28220c34f6a0673f (diff)
downloadlibbu++-0bd8b8cf19687229b53e37468dfe36c4217fbbf1.tar.gz
libbu++-0bd8b8cf19687229b53e37468dfe36c4217fbbf1.tar.bz2
libbu++-0bd8b8cf19687229b53e37468dfe36c4217fbbf1.tar.xz
libbu++-0bd8b8cf19687229b53e37468dfe36c4217fbbf1.zip
Alright, the caching system now passes the basic CRUD tests with arbitrary
keytypes. It doesn't yet use the stackable CacheStore concept, but the code is all in place to make it easy to switch to. There also needs to be some more accounting code in place, so that we can actually use the Schedulers, whatever they happen to be called in the future. A whacky side note, it turns out that we totally need to ensure an object is loaded from the cache in order to delete it, we can't ensure that any references to other objects that are in the cache will be loaded otherwise.
-rw-r--r--src/cache.cpp1
-rw-r--r--src/cache.h58
-rw-r--r--src/cachestore.h6
-rw-r--r--src/cptr.h11
-rw-r--r--src/tests/cache.cpp125
-rw-r--r--src/trace.cpp12
-rw-r--r--src/trace.h37
7 files changed, 198 insertions, 52 deletions
diff --git a/src/cache.cpp b/src/cache.cpp
index e69de29..fd1082b 100644
--- a/src/cache.cpp
+++ b/src/cache.cpp
@@ -0,0 +1 @@
#include "bu/cache.h"
diff --git a/src/cache.h b/src/cache.h
index 0c3994c..9488044 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -38,6 +38,20 @@ namespace Bu
38 virtual ~Cache() 38 virtual ~Cache()
39 { 39 {
40 TRACE(); 40 TRACE();
41 for( typename CidHash::iterator i = hEnt.begin();
42 i != hEnt.end(); i++ )
43 {
44 if( i.getValue().iRefs > 0 )
45 {
46 printf("Error? iRefs=%d for key ", i.getValue().iRefs );
47 __tracer_format( i.getKey() );
48 printf("!\n");
49 }
50 lStore.first()->unload(
51 i.getValue().pData,
52 i.getKey()
53 );
54 }
41 for( typename StoreList::iterator i = lStore.begin(); 55 for( typename StoreList::iterator i = lStore.begin();
42 i != lStore.end(); i++ ) 56 i != lStore.end(); i++ )
43 { 57 {
@@ -47,44 +61,72 @@ namespace Bu
47 61
48 void appendStore( Store *pHand ) 62 void appendStore( Store *pHand )
49 { 63 {
64 TRACE();
50 lStore.append( pHand ); 65 lStore.append( pHand );
51 } 66 }
52 67
53 void prependStore( Store *pHand ) 68 void prependStore( Store *pHand )
54 { 69 {
70 TRACE();
55 lStore.prepend( pHand ); 71 lStore.prepend( pHand );
56 } 72 }
57 73
58 Ptr insert( obtype *pData ) 74 Ptr insert( obtype *pData )
59 { 75 {
60 TRACE(); 76 TRACE( pData );
61 CacheEntry e = {pData, 0}; 77 CacheEntry e = {pData, 0};
62 hEnt.insert( 0 , e ); 78 keytype k = lStore.first()->create( pData );
63 return Ptr( *this, pData ); 79 hEnt.insert( k, e );
80
81 return Ptr( *this, pData, k );
64 } 82 }
65 83
66 Ptr get( keytype cId ) 84 Ptr get( keytype cId )
67 { 85 {
68 TRACE(); 86 TRACE( cId );
69 return Ptr( *this, hEnt.get( cId ).pData ); 87 try {
88 return Ptr( *this, hEnt.get( cId ).pData, cId );
89 }
90 catch( Bu::HashException &e ) {
91 CacheEntry e = {lStore.first()->load( cId ), 0};
92 hEnt.insert( cId, e );
93 return Ptr( *this, e.pData, cId );
94 }
95 }
96
97 void erase( keytype cId )
98 {
99 TRACE( cId );
100 try {
101 if( hEnt.get( cId ).iRefs > 0 )
102 {
103 printf("Shouldn't delete, references still exist!\n");
104 return;
105 }
106 }
107 catch( Bu::HashException &e ) {
108 get( cId );
109 }
110 lStore.first()->destroy( hEnt.get( cId ).pData, cId );
111 hEnt.erase( cId );
70 } 112 }
71 113
72 int getRefCnt( keytype cId ) 114 int getRefCnt( keytype cId )
73 { 115 {
74 TRACE(); 116 TRACE( cId );
75 return hEnt.get( cId ).iRefs; 117 return hEnt.get( cId ).iRefs;
76 } 118 }
77 119
78 private: 120 private:
79 void incRef( keytype cId ) 121 void incRef( keytype cId )
80 { 122 {
81 TRACE(); 123 TRACE( cId );
82 hEnt.get( cId ).iRefs++; 124 hEnt.get( cId ).iRefs++;
83 } 125 }
84 126
85 void decRef( keytype cId ) 127 void decRef( keytype cId )
86 { 128 {
87 TRACE(); 129 TRACE( cId );
88 CacheEntry &e = hEnt.get( cId ); 130 CacheEntry &e = hEnt.get( cId );
89 e.iRefs--; 131 e.iRefs--;
90 } 132 }
diff --git a/src/cachestore.h b/src/cachestore.h
index 3211b6a..5b52359 100644
--- a/src/cachestore.h
+++ b/src/cachestore.h
@@ -1,8 +1,6 @@
1#ifndef BU_CACHE_STORE_H 1#ifndef BU_CACHE_STORE_H
2#define BU_CACHE_STORE_H 2#define BU_CACHE_STORE_H
3 3
4#include "bu/cptr.h"
5
6namespace Bu 4namespace Bu
7{ 5{
8 /** 6 /**
@@ -21,10 +19,8 @@ namespace Bu
21 { 19 {
22 } 20 }
23 21
24 typedef Bu::CPtr<obtype, keytype> Ptr;
25
26 virtual obtype *load( const keytype &key )=0; 22 virtual obtype *load( const keytype &key )=0;
27 virtual void unload( obtype *pObj )=0; 23 virtual void unload( obtype *pObj, const keytype &key )=0;
28 virtual keytype create( obtype *pSrc )=0; 24 virtual keytype create( obtype *pSrc )=0;
29 virtual void destroy( obtype *pObj, const keytype &key )=0; 25 virtual void destroy( obtype *pObj, const keytype &key )=0;
30 26
diff --git a/src/cptr.h b/src/cptr.h
index 8f35a03..97f5e17 100644
--- a/src/cptr.h
+++ b/src/cptr.h
@@ -15,9 +15,11 @@ namespace Bu
15 { 15 {
16 friend class Bu::Cache<obtype, keytype>; 16 friend class Bu::Cache<obtype, keytype>;
17 private: 17 private:
18 CPtr( Cache<obtype, keytype> &rCache, obtype *pData ) : 18 CPtr( Cache<obtype, keytype> &rCache, obtype *pData,
19 const keytype &kId ) :
19 rCache( rCache ), 20 rCache( rCache ),
20 pData( pData ) 21 pData( pData ),
22 kId( kId )
21 { 23 {
22 rCache.incRef( kId ); 24 rCache.incRef( kId );
23 } 25 }
@@ -38,6 +40,11 @@ namespace Bu
38 return pData; 40 return pData;
39 } 41 }
40 42
43 const keytype &getKey()
44 {
45 return kId;
46 }
47
41 private: 48 private:
42 Bu::Cache<obtype, keytype> &rCache; 49 Bu::Cache<obtype, keytype> &rCache;
43 obtype *pData; 50 obtype *pData;
diff --git a/src/tests/cache.cpp b/src/tests/cache.cpp
index 1cc008a..18e6a95 100644
--- a/src/tests/cache.cpp
+++ b/src/tests/cache.cpp
@@ -1,9 +1,12 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stdlib.h>
2#include <sys/stat.h> 3#include <sys/stat.h>
3#include <sys/types.h> 4#include <sys/types.h>
4#include <errno.h> 5#include <errno.h>
5 6
6#include "bu/cache.h" 7#include "bu/cache.h"
8#include "bu/file.h"
9#include "bu/fstring.h"
7 10
8class Bob 11class Bob
9{ 12{
@@ -13,6 +16,12 @@ public:
13 TRACE(); 16 TRACE();
14 } 17 }
15 18
19 Bob( int i ) :
20 iInt( i )
21 {
22 TRACE( i );
23 }
24
16 virtual ~Bob() 25 virtual ~Bob()
17 { 26 {
18 TRACE(); 27 TRACE();
@@ -20,7 +29,7 @@ public:
20 29
21 void setInt( int i ) 30 void setInt( int i )
22 { 31 {
23 TRACE(); 32 TRACE( i );
24 iInt = i; 33 iInt = i;
25 } 34 }
26 35
@@ -29,15 +38,17 @@ public:
29 return iInt; 38 return iInt;
30 } 39 }
31 40
32 long getCacheId() const
33 {
34 TRACE();
35 return 0;
36 }
37
38 int iInt; 41 int iInt;
39}; 42};
40 43
44namespace Bu {
45 template<>
46 void __tracer_format<Bob*>( Bob* const &c )
47 {
48 printf("%08X=%d", (uint32_t)c, c->getInt() );
49 }
50}
51
41class BobStore : public Bu::CacheStore<Bob, long> 52class BobStore : public Bu::CacheStore<Bob, long>
42{ 53{
43public: 54public:
@@ -45,34 +56,79 @@ public:
45 cLastId( 0 ) 56 cLastId( 0 )
46 { 57 {
47 TRACE(); 58 TRACE();
59 if( access( "bobcache/last", R_OK|W_OK ) )
60 {
61 mkdir("bobcache", 0755 );
62 Bu::File f("bobcache/last", Bu::File::Write|Bu::File::Create );
63 f.write("0", 1);
64 printf("Initializing cache: %s\n", strerror( errno ) );
65 }
66 else
67 {
68 cLastId = readNum("bobcache/last");
69 }
48 } 70 }
49 71
50 ~BobStore() 72 ~BobStore()
51 { 73 {
52 TRACE(); 74 TRACE();
75 writeNum("bobcache/last", cLastId );
76 }
77
78 long readNum( const Bu::FString &sFile )
79 {
80 TRACE( sFile );
81 Bu::File f( sFile, Bu::File::Read );
82 char buf[80];
83 buf[f.read( buf, 80 )] = '\0';
84 return strtol( buf, NULL, 0 );
85 }
86
87 void writeNum( const Bu::FString &sFile, long num )
88 {
89 TRACE( sFile, num );
90 Bu::File f( sFile,
91 Bu::File::Write|Bu::File::Create|Bu::File::Truncate
92 );
93 Bu::FString s;
94 s.format("%d", num );
95 f.write( s );
53 } 96 }
54 97
55 virtual Bob *load( const long &key ) 98 virtual Bob *load( const long &key )
56 { 99 {
57 TRACE(); 100 TRACE( key );
58 return NULL; 101 Bu::FString sDest;
102 sDest.format("bobcache/%d", key );
103 return new Bob( readNum( sDest ) );
59 } 104 }
60 105
61 virtual void unload( Bob *pObj ) 106 virtual void unload( Bob *pObj, const long &key )
62 { 107 {
63 TRACE(); 108 TRACE( pObj, key );
109 Bu::FString sDest;
110 sDest.format("bobcache/%d", key );
111 writeNum( sDest, pObj->getInt() );
64 delete pObj; 112 delete pObj;
65 } 113 }
66 114
67 virtual long create( Bob *rSrc ) 115 virtual long create( Bob *rSrc )
68 { 116 {
69 TRACE(); 117 TRACE( rSrc );
70 return ++cLastId; 118 long id = ++cLastId;
119 Bu::FString sDest;
120 sDest.format("bobcache/%d", id );
121 writeNum( sDest, rSrc->getInt() );
122 return id;
71 } 123 }
72 124
73 virtual void destroy( Bob *pObj, const long &key ) 125 virtual void destroy( Bob *pObj, const long &key )
74 { 126 {
75 TRACE(); 127 TRACE( pObj, key );
128 Bu::FString sDest;
129 sDest.format("bobcache/%d", key );
130 if( !access( sDest.getStr(), F_OK ) )
131 unlink( sDest.getStr() );
76 delete pObj; 132 delete pObj;
77 } 133 }
78 134
@@ -82,28 +138,47 @@ private:
82 138
83int main( int argc, char *argv[] ) 139int main( int argc, char *argv[] )
84{ 140{
85 TRACE(); 141 TRACE( argc, argv );
142 typedef Bu::Cache<Bob, long> BobCache;
143 typedef BobCache::Ptr BobPtr;
144
86 if( argc < 3 ) 145 if( argc < 3 )
87 { 146 {
88 printf("Try: %s [icufd] [<id/value>]\n\n", argv[0] ); 147 printf("Try: %s [crud] [<id/value>]\n\n", argv[0] );
89 return 0; 148 return 0;
90 } 149 }
91 150
151 BobCache cBob;
152 cBob.appendStore( new BobStore() );
92 switch( argv[1][0] ) 153 switch( argv[1][0] )
93 { 154 {
94 case 'i':
95 mkdir("bobcache", 0755 );
96 printf("Initialized cache: %s\n", strerror( errno ) );
97 return 0;
98
99 case 'c': 155 case 'c':
100 typedef Bu::Cache<Bob, long> BobCache; 156 {
101 typedef BobCache::Ptr BobPtr; 157 BobCache::Ptr pBob = cBob.insert(
158 new Bob( strtol( argv[2], NULL, 0 ) )
159 );
160 printf("Key = %ld\n", pBob.getKey() );
161 }
162 return 0;
102 163
103 BobCache cBob; 164 case 'r':
165 {
166 BobCache::Ptr pBob = cBob.get( strtol( argv[2], NULL, 0 ) );
167 printf("Value = %d\n", pBob->getInt() );
168 }
169 return 0;
104 170
105 cBob.appendStore( new BobStore() ); 171 case 'u':
172 {
173 BobCache::Ptr pBob = cBob.get( strtol( argv[2], NULL, 0 ) );
174 pBob->setInt( strtol( argv[3], NULL, 0 ) );
175 }
176 return 0;
106 177
178 case 'd':
179 {
180 cBob.erase( strtol( argv[2], NULL, 0 ) );
181 }
107 return 0; 182 return 0;
108 } 183 }
109 184
diff --git a/src/trace.cpp b/src/trace.cpp
index dab53d6..242d110 100644
--- a/src/trace.cpp
+++ b/src/trace.cpp
@@ -58,7 +58,7 @@ template<> void Bu::__tracer_format<char>( const char &v )
58{ 58{
59 printf("%hhd", v ); 59 printf("%hhd", v );
60} 60}
61/* 61
62template<> void Bu::__tracer_format<long>( const long &v ) 62template<> void Bu::__tracer_format<long>( const long &v )
63{ 63{
64 printf("%ld", v ); 64 printf("%ld", v );
@@ -67,7 +67,7 @@ template<> void Bu::__tracer_format<long>( const long &v )
67template<> void Bu::__tracer_format<unsigned long>( const unsigned long &v ) 67template<> void Bu::__tracer_format<unsigned long>( const unsigned long &v )
68{ 68{
69 printf("%lu", v ); 69 printf("%lu", v );
70}*/ 70}
71 71
72template<> void Bu::__tracer_format<float>( const float &v ) 72template<> void Bu::__tracer_format<float>( const float &v )
73{ 73{
@@ -93,7 +93,11 @@ template<> void Bu::__tracer_format<char **>( char ** const &v )
93{ 93{
94 printf("["); 94 printf("[");
95 for( int j = 0; v[j]; j++ ) 95 for( int j = 0; v[j]; j++ )
96 {
97 if( j > 0 )
98 printf(", ");
96 printf("\"%s\"", v[j] ); 99 printf("\"%s\"", v[j] );
100 }
97 printf("]"); 101 printf("]");
98} 102}
99 103
@@ -111,6 +115,10 @@ template<> void Bu::__tracer_format<char const **>( char const ** const &v )
111{ 115{
112 printf("["); 116 printf("[");
113 for( int j = 0; v[j]; j++ ) 117 for( int j = 0; v[j]; j++ )
118 {
119 if( j > 0 )
120 printf(", ");
114 printf("\"%s\"", v[j] ); 121 printf("\"%s\"", v[j] );
122 }
115 printf("]"); 123 printf("]");
116} 124}
diff --git a/src/trace.h b/src/trace.h
index 82399c2..049d138 100644
--- a/src/trace.h
+++ b/src/trace.h
@@ -11,6 +11,7 @@
11#include <stdio.h> 11#include <stdio.h>
12#include <stdint.h> 12#include <stdint.h>
13#include <stddef.h> 13#include <stddef.h>
14#include <string.h>
14 15
15namespace Bu 16namespace Bu
16{ 17{
@@ -26,7 +27,12 @@ namespace Bu
26 #define looper( vv ) \ 27 #define looper( vv ) \
27 for( ; *n; n++ ) \ 28 for( ; *n; n++ ) \
28 { \ 29 { \
29 if( *n == ',' || *n == ')' ) \ 30 if( bInBracket == true ) \
31 { \
32 if( *n == '>' ) \
33 bInBracket = false; \
34 } \
35 else if( *n == ',' || *n == ')' ) \
30 { \ 36 { \
31 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); \ 37 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); \
32 fwrite("=", 1, 1, stdout); \ 38 fwrite("=", 1, 1, stdout); \
@@ -35,6 +41,10 @@ namespace Bu
35 n++; \ 41 n++; \
36 break; \ 42 break; \
37 } \ 43 } \
44 else if( *n == '<' ) \
45 { \
46 bInBracket = true; \
47 } \
38 } (void)0 48 } (void)0
39 49
40 template<typename t1> void __tracer( const char *pf, t1 &v1 ) 50 template<typename t1> void __tracer( const char *pf, t1 &v1 )
@@ -42,8 +52,9 @@ namespace Bu
42 printf("trace: "); 52 printf("trace: ");
43 const char *s = pf; 53 const char *s = pf;
44 const char *n = pf; 54 const char *n = pf;
55 bool bInBracket = false;
45 looper( v1 ); 56 looper( v1 );
46 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); 57 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, strlen(s), stdout );
47 fwrite( "\n", 1, 1, stdout ); 58 fwrite( "\n", 1, 1, stdout );
48 fflush( stdout ); 59 fflush( stdout );
49 } 60 }
@@ -54,9 +65,10 @@ namespace Bu
54 printf("trace: "); 65 printf("trace: ");
55 const char *s = pf; 66 const char *s = pf;
56 const char *n = pf; 67 const char *n = pf;
68 bool bInBracket = false;
57 looper( v1 ); 69 looper( v1 );
58 looper( v2 ); 70 looper( v2 );
59 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); 71 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, strlen(s), stdout );
60 fwrite( "\n", 1, 1, stdout ); 72 fwrite( "\n", 1, 1, stdout );
61 fflush( stdout ); 73 fflush( stdout );
62 } 74 }
@@ -67,10 +79,11 @@ namespace Bu
67 printf("trace: "); 79 printf("trace: ");
68 const char *s = pf; 80 const char *s = pf;
69 const char *n = pf; 81 const char *n = pf;
82 bool bInBracket = false;
70 looper( v1 ); 83 looper( v1 );
71 looper( v2 ); 84 looper( v2 );
72 looper( v3 ); 85 looper( v3 );
73 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); 86 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, strlen(s), stdout );
74 fwrite( "\n", 1, 1, stdout ); 87 fwrite( "\n", 1, 1, stdout );
75 fflush( stdout ); 88 fflush( stdout );
76 } 89 }
@@ -81,11 +94,12 @@ namespace Bu
81 printf("trace: "); 94 printf("trace: ");
82 const char *s = pf; 95 const char *s = pf;
83 const char *n = pf; 96 const char *n = pf;
97 bool bInBracket = false;
84 looper( v1 ); 98 looper( v1 );
85 looper( v2 ); 99 looper( v2 );
86 looper( v3 ); 100 looper( v3 );
87 looper( v4 ); 101 looper( v4 );
88 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); 102 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, strlen(s), stdout );
89 fwrite( "\n", 1, 1, stdout ); 103 fwrite( "\n", 1, 1, stdout );
90 fflush( stdout ); 104 fflush( stdout );
91 } 105 }
@@ -96,12 +110,13 @@ namespace Bu
96 printf("trace: "); 110 printf("trace: ");
97 const char *s = pf; 111 const char *s = pf;
98 const char *n = pf; 112 const char *n = pf;
113 bool bInBracket = false;
99 looper( v1 ); 114 looper( v1 );
100 looper( v2 ); 115 looper( v2 );
101 looper( v3 ); 116 looper( v3 );
102 looper( v4 ); 117 looper( v4 );
103 looper( v5 ); 118 looper( v5 );
104 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); 119 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, strlen(s), stdout );
105 fwrite( "\n", 1, 1, stdout ); 120 fwrite( "\n", 1, 1, stdout );
106 fflush( stdout ); 121 fflush( stdout );
107 } 122 }
@@ -114,13 +129,14 @@ namespace Bu
114 printf("trace: "); 129 printf("trace: ");
115 const char *s = pf; 130 const char *s = pf;
116 const char *n = pf; 131 const char *n = pf;
132 bool bInBracket = false;
117 looper( v1 ); 133 looper( v1 );
118 looper( v2 ); 134 looper( v2 );
119 looper( v3 ); 135 looper( v3 );
120 looper( v4 ); 136 looper( v4 );
121 looper( v5 ); 137 looper( v5 );
122 looper( v6 ); 138 looper( v6 );
123 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); 139 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, strlen(s), stdout );
124 fwrite( "\n", 1, 1, stdout ); 140 fwrite( "\n", 1, 1, stdout );
125 fflush( stdout ); 141 fflush( stdout );
126 } 142 }
@@ -133,6 +149,7 @@ namespace Bu
133 printf("trace: "); 149 printf("trace: ");
134 const char *s = pf; 150 const char *s = pf;
135 const char *n = pf; 151 const char *n = pf;
152 bool bInBracket = false;
136 looper( v1 ); 153 looper( v1 );
137 looper( v2 ); 154 looper( v2 );
138 looper( v3 ); 155 looper( v3 );
@@ -140,7 +157,7 @@ namespace Bu
140 looper( v5 ); 157 looper( v5 );
141 looper( v6 ); 158 looper( v6 );
142 looper( v7 ); 159 looper( v7 );
143 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, 1, stdout ); 160 fwrite( s, (ptrdiff_t)n-(ptrdiff_t)s, strlen(s), stdout );
144 fwrite( "\n", 1, 1, stdout ); 161 fwrite( "\n", 1, 1, stdout );
145 fflush( stdout ); 162 fflush( stdout );
146 } 163 }
@@ -156,8 +173,8 @@ namespace Bu
156 template<> void __tracer_format<uint64_t>( const uint64_t &v ); 173 template<> void __tracer_format<uint64_t>( const uint64_t &v );
157 template<> void __tracer_format<bool>( const bool &v ); 174 template<> void __tracer_format<bool>( const bool &v );
158 template<> void __tracer_format<char>( const char &v ); 175 template<> void __tracer_format<char>( const char &v );
159 //template<> void __tracer_format<long>( const long &v ); 176 template<> void __tracer_format<long>( const long &v );
160 //template<> void __tracer_format<unsigned long>( const unsigned long &v ); 177 template<> void __tracer_format<unsigned long>( const unsigned long &v );
161 template<> void __tracer_format<float>( const float &v ); 178 template<> void __tracer_format<float>( const float &v );
162 template<> void __tracer_format<double>( const double &v ); 179 template<> void __tracer_format<double>( const double &v );
163 template<> void __tracer_format<void *>( void * const &v ); 180 template<> void __tracer_format<void *>( void * const &v );