aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-01-27 21:45:03 +0000
committerMike Buland <eichlan@xagasoft.com>2009-01-27 21:45:03 +0000
commit67ec9d667ab0c3f2258f6f69308d0731e74a74d0 (patch)
treeeaaccf38aeecbb22b06b0156a40cf0dbb66c7bdc
parent00bb8c39b97638c872ebccc6aee7f3c5fb57d7d6 (diff)
downloadlibbu++-67ec9d667ab0c3f2258f6f69308d0731e74a74d0.tar.gz
libbu++-67ec9d667ab0c3f2258f6f69308d0731e74a74d0.tar.bz2
libbu++-67ec9d667ab0c3f2258f6f69308d0731e74a74d0.tar.xz
libbu++-67ec9d667ab0c3f2258f6f69308d0731e74a74d0.zip
Nids is even better, all fixed, no problems. And you can define you're own
creator functions for the cache store...soon, you'll also be able to define you're own loader/writer functions, but the default will still work exactly like this. I also did more work on nidstool, I think I may actually have to create a tools dir that will just compile some executables for the libbu++ root, because this thing is handy. You can get info on the system, trace streams' blocks, and I'm working on an analysis function that will help you figure out how to optomize your nids files. Plus, it'll have a function soon for re-writing a nids stream, which will let you change the block size, defragment, and remove unused blocks.
-rw-r--r--src/cachestorenids.h13
-rw-r--r--src/nids.cpp16
-rw-r--r--src/nids.h8
-rw-r--r--src/tests/nidstool.cpp115
4 files changed, 114 insertions, 38 deletions
diff --git a/src/cachestorenids.h b/src/cachestorenids.h
index 9288008..a5fa402 100644
--- a/src/cachestorenids.h
+++ b/src/cachestorenids.h
@@ -9,14 +9,18 @@
9 9
10#include "bu/file.h" 10#include "bu/file.h"
11 11
12static int iCnt = 0;
13
14namespace Bu 12namespace Bu
15{ 13{
16 template<class obtype, class keytype> 14 template<class obtype, class keytype>
17 keytype __cacheGetKey( const obtype *pObj ); 15 keytype __cacheGetKey( const obtype *pObj );
18 16
19 template<class obtype, class keytype> 17 template<class obtype, class keytype>
18 obtype *__cacheStoreNidsAlloc( const keytype &key )
19 {
20 return new obtype();
21 }
22
23 template<class obtype, class keytype>
20 class CacheStoreNids : public CacheStore<obtype, keytype> 24 class CacheStoreNids : public CacheStore<obtype, keytype>
21 { 25 {
22 public: 26 public:
@@ -55,7 +59,7 @@ namespace Bu
55 int iStream = hId.get( key ); 59 int iStream = hId.get( key );
56 NidsStream ns = nStore.openStream( iStream ); 60 NidsStream ns = nStore.openStream( iStream );
57 Bu::Archive ar( ns, Bu::Archive::load ); 61 Bu::Archive ar( ns, Bu::Archive::load );
58 obtype *pOb = new obtype(); 62 obtype *pOb = __cacheStoreNidsAlloc<obtype, keytype>( key );
59 ar >> (*pOb); 63 ar >> (*pOb);
60 return pOb; 64 return pOb;
61 } 65 }
@@ -76,8 +80,7 @@ namespace Bu
76 hId.insert( key, iStream ); 80 hId.insert( key, iStream );
77 NidsStream ns = nStore.openStream( iStream ); 81 NidsStream ns = nStore.openStream( iStream );
78 Bu::Archive ar( ns, Bu::Archive::save ); 82 Bu::Archive ar( ns, Bu::Archive::save );
79 obtype *pOb = new obtype(); 83 ar << (*pSrc);
80 ar << (*pOb);
81 return key; 84 return key;
82 } 85 }
83 86
diff --git a/src/nids.cpp b/src/nids.cpp
index 23c11b0..26a7964 100644
--- a/src/nids.cpp
+++ b/src/nids.cpp
@@ -104,7 +104,7 @@ void Bu::Nids::initialize( int iBlockSize, int iPreAllocate )
104 104
105 Block *block = (Block *)new char[iBlockSize]; 105 Block *block = (Block *)new char[iBlockSize];
106 memset( block, 0, iBlockSize ); 106 memset( block, 0, iBlockSize );
107 block->uFirstBlock = block->uNextBlock = block->uPrevBlock = blockUnused; 107 block->uFirstBlock = block->uNextBlock /*=block->uPrevBlock*/ = blockUnused;
108 for( int j = 0; j < iPreAllocate; j++ ) 108 for( int j = 0; j < iPreAllocate; j++ )
109 { 109 {
110 sStore.write( block, iBlockSize ); 110 sStore.write( block, iBlockSize );
@@ -122,9 +122,9 @@ void Bu::Nids::updateHeader()
122} 122}
123 123
124void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock, 124void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock,
125 uint32_t uPrevBlock, bool bNew ) 125 /*uint32_t uPrevBlock,*/ bool bNew )
126{ 126{
127 Block b = { uPos, blockUnused, uPrevBlock, 0, 0, { } }; 127 Block b = { uPos, blockUnused, /*uPrevBlock, 0,*/ 0, { } };
128 if( uFirstBlock != blockUnused ) 128 if( uFirstBlock != blockUnused )
129 b.uFirstBlock = uFirstBlock; 129 b.uFirstBlock = uFirstBlock;
130 bsBlockUsed.setBit( uPos ); 130 bsBlockUsed.setBit( uPos );
@@ -142,27 +142,27 @@ void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock,
142 iUsed++; 142 iUsed++;
143} 143}
144 144
145uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, 145uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, /*uint32_t uPrevBlock,*/
146 int /*iPreAllocate*/ ) 146 int /*iPreAllocate*/ )
147{ 147{
148 for( int j = 0; j < iBlocks; j++ ) 148 for( int j = 0; j < iBlocks; j++ )
149 { 149 {
150 if( !bsBlockUsed.getBit( j ) ) 150 if( !bsBlockUsed.getBit( j ) )
151 { 151 {
152 initBlock( j, uFirstBlock, uPrevBlock ); 152 initBlock( j, uFirstBlock/*, uPrevBlock*/ );
153 return j; 153 return j;
154 } 154 }
155 } 155 }
156 // Oh, we don't have any blocks left...allocate a new one. 156 // Oh, we don't have any blocks left...allocate a new one.
157 iBlocks++; 157 iBlocks++;
158 bsBlockUsed.setSize( iBlocks, false ); 158 bsBlockUsed.setSize( iBlocks, false );
159 initBlock( iBlocks-1, uFirstBlock, uPrevBlock, true ); 159 initBlock( iBlocks-1, uFirstBlock/*, uPrevBlock*/, true );
160 return iBlocks-1; 160 return iBlocks-1;
161} 161}
162 162
163int Bu::Nids::createStream( int iPreAllocate ) 163int Bu::Nids::createStream( int iPreAllocate )
164{ 164{
165 return createBlock( blockUnused, blockUnused, iPreAllocate ); 165 return createBlock( blockUnused, /*blockUnused,*/ iPreAllocate );
166} 166}
167 167
168void Bu::Nids::deleteStream( int /*iID*/ ) 168void Bu::Nids::deleteStream( int /*iID*/ )
@@ -224,7 +224,7 @@ void Bu::Nids::updateStreamSize( uint32_t uIndex, uint32_t uSize )
224{ 224{
225 if( !sStore.canWrite() ) 225 if( !sStore.canWrite() )
226 return; 226 return;
227 sStore.setPos( iBlockStart + (iBlockSize*uIndex)+4*3 ); 227 sStore.setPos( iBlockStart + (iBlockSize*uIndex)+4*2 );
228 sStore.write( &uSize, 4 ); 228 sStore.write( &uSize, 4 );
229} 229}
230 230
diff --git a/src/nids.h b/src/nids.h
index 63d7061..262d9c1 100644
--- a/src/nids.h
+++ b/src/nids.h
@@ -75,9 +75,9 @@ namespace Bu
75 { 75 {
76 uint32_t uFirstBlock; 76 uint32_t uFirstBlock;
77 uint32_t uNextBlock; 77 uint32_t uNextBlock;
78 uint32_t uPrevBlock; 78 // uint32_t uPrevBlock;
79 uint32_t uBytesUsed; 79 uint32_t uBytesUsed;
80 uint32_t uReserved; 80 // uint32_t uReserved;
81 unsigned char pData[0]; 81 unsigned char pData[0];
82 } Block; 82 } Block;
83 83
@@ -87,8 +87,8 @@ namespace Bu
87 }; 87 };
88 88
89 void initBlock( uint32_t uPos, uint32_t uFirstBlock, 89 void initBlock( uint32_t uPos, uint32_t uFirstBlock,
90 uint32_t uPrevBlock, bool bNew=false ); 90 /*uint32_t uPrevBlock,*/ bool bNew=false );
91 uint32_t createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, 91 uint32_t createBlock( uint32_t uFirstBlock, /*uint32_t uPrevBlock,*/
92 int iPreAllocate=1 ); 92 int iPreAllocate=1 );
93 void getBlock( uint32_t uIndex, struct Nids::Block *pBlock ); 93 void getBlock( uint32_t uIndex, struct Nids::Block *pBlock );
94 void setBlock( uint32_t uIndex, struct Nids::Block *pBlock ); 94 void setBlock( uint32_t uIndex, struct Nids::Block *pBlock );
diff --git a/src/tests/nidstool.cpp b/src/tests/nidstool.cpp
index 546534e..1becba5 100644
--- a/src/tests/nidstool.cpp
+++ b/src/tests/nidstool.cpp
@@ -5,6 +5,13 @@
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7 7
8typedef struct Block
9{
10 uint32_t uFirstBlock;
11 uint32_t uNextBlock;
12 uint32_t uBytesUsed;
13} Block;
14
8class Param : public Bu::ParamProc 15class Param : public Bu::ParamProc
9{ 16{
10public: 17public:
@@ -14,7 +21,9 @@ public:
14 addParam("info", 'i', mkproc(Param::procInfo), 21 addParam("info", 'i', mkproc(Param::procInfo),
15 "Print some info about the file."); 22 "Print some info about the file.");
16 addParam("dump", 'd', mkproc(Param::procDump), 23 addParam("dump", 'd', mkproc(Param::procDump),
17 "Dump a stream to a file"); 24 "Dump a stream to a file.");
25 addParam("analyze", 'a', mkproc(Param::procAnalyze),
26 "Analyze a nids file.");
18 addParam("help", 'h', mkproc(Bu::ParamProc::help), "This help."); 27 addParam("help", 'h', mkproc(Bu::ParamProc::help), "This help.");
19 process( argc, argv ); 28 process( argc, argv );
20 } 29 }
@@ -23,6 +32,20 @@ public:
23 { 32 {
24 } 33 }
25 34
35 void printInfo( Bu::Nids &n )
36 {
37 printf("File info:\n");
38 printf(" Header overhead: %db\n", n.getBlockStart() );
39 printf(" Block size: %db\n", n.getBlockSize() );
40 printf(" Block count: %d\n", n.getNumBlocks() );
41 printf(" Blocks used: %d (%d%%)\n", n.getNumUsedBlocks(),
42 n.getNumUsedBlocks()*100/n.getNumBlocks() );
43 printf(" Block overhead: %db\n", n.getBlockOverhead() );
44 printf(" Block storage: %db (%d%%)\n",
45 n.getBlockSize()-n.getBlockOverhead(),
46 (n.getBlockSize()-n.getBlockOverhead())*100/n.getBlockSize() );
47 }
48
26 int procInfo( int argc, char *argv[] ) 49 int procInfo( int argc, char *argv[] )
27 { 50 {
28 if( argc < 1 ) 51 if( argc < 1 )
@@ -35,27 +58,10 @@ public:
35 Bu::Nids n( fIn ); 58 Bu::Nids n( fIn );
36 n.initialize(); 59 n.initialize();
37 60
38 printf("Block size: %db\n", n.getBlockSize() ); 61 printInfo( n );
39 printf("Block count: %d\n", n.getNumBlocks() );
40 printf("Blocks used: %d (%d%%)\n", n.getNumUsedBlocks(),
41 n.getNumUsedBlocks()*100/n.getNumBlocks() );
42 printf("Block start: %db\n", n.getBlockStart() );
43 printf("Block overhead: %db\n", n.getBlockOverhead() );
44 printf("Block storage: %db (%d%%)\n",
45 n.getBlockSize()-n.getBlockOverhead(),
46 (n.getBlockSize()-n.getBlockOverhead())*100/n.getBlockSize() );
47 62
48 if( argc >= 2 ) 63 if( argc >= 2 )
49 { 64 {
50 typedef struct Block
51 {
52 uint32_t uFirstBlock;
53 uint32_t uNextBlock;
54 uint32_t uPrevBlock;
55 uint32_t uBytesUsed;
56 uint32_t uReserved;
57 } Block;
58
59 uint32_t uStream = strtoul( argv[1], NULL, 0 ); 65 uint32_t uStream = strtoul( argv[1], NULL, 0 );
60 uint32_t uBlock = uStream; 66 uint32_t uBlock = uStream;
61 67
@@ -65,8 +71,8 @@ public:
65 { 71 {
66 fIn.setPos( n.getBlockStart()+n.getBlockSize()*uBlock ); 72 fIn.setPos( n.getBlockStart()+n.getBlockSize()*uBlock );
67 fIn.read( &b, sizeof(Block) ); 73 fIn.read( &b, sizeof(Block) );
68 printf("Stream %u: block %u, next %u, prev %u, %ub used.\n", 74 printf("Stream %u: block %u, next %u, %ub used.\n",
69 uStream, uBlock, b.uNextBlock, b.uPrevBlock, b.uBytesUsed 75 uStream, uBlock, b.uNextBlock, b.uBytesUsed
70 ); 76 );
71 if( b.uNextBlock == 0xFFFFFFFFUL ) 77 if( b.uNextBlock == 0xFFFFFFFFUL )
72 break; 78 break;
@@ -112,6 +118,73 @@ public:
112 return 3; 118 return 3;
113 } 119 }
114 120
121 int procAnalyze( int argc, char *argv[] )
122 {
123 if( argc < 1 )
124 {
125 printf("You must provide a file name.\n");
126 exit( 1 );
127 }
128
129 Bu::File fIn( argv[0], Bu::File::Read );
130 Bu::Nids n( fIn );
131 n.initialize();
132
133 printInfo( n );
134
135 int iStreamCnt = 0;
136 int iStreamTotal = 0;
137 int iOneBlock = 0;
138 uint32_t iLargest = 0;
139 uint32_t iSmallest = 0;
140 int iWaste = 0;
141 int iUsable = n.getBlockSize()-n.getBlockOverhead();
142 Block b;
143 for( int j = 0; j < n.getNumBlocks(); j++ )
144 {
145 fIn.setPos( n.getBlockStart()+n.getBlockSize()*j );
146 fIn.read( &b, sizeof(Block) );
147 if( b.uFirstBlock != (uint32_t)j )
148 continue;
149
150 iStreamCnt++;
151 iStreamTotal += b.uBytesUsed;
152
153 if( b.uNextBlock == 0xFFFFFFFFUL )
154 {
155 iOneBlock++;
156 iWaste += iUsable - b.uBytesUsed;
157 }
158 else
159 {
160 iWaste += iUsable - (b.uBytesUsed%iUsable);
161 }
162
163 if( j == 0 )
164 {
165 iSmallest = iLargest = b.uBytesUsed;
166 }
167 else
168 {
169 if( iLargest < b.uBytesUsed )
170 iLargest = b.uBytesUsed;
171 if( iSmallest > b.uBytesUsed )
172 iSmallest = b.uBytesUsed;
173 }
174 }
175 printf("Steam analysis:\n");
176 printf(" Stream count: %d\n", iStreamCnt );
177 printf(" Stream size: %db/%db/%db (min/avr/max)\n",
178 iSmallest, iStreamTotal/iStreamCnt, iLargest );
179 printf(" One-block streams: %d (%d%%)\n",
180 iOneBlock, iOneBlock*100/iStreamCnt );
181 printf(" Total wasted space: %db (%d%%)\n",
182 iWaste, iWaste*100/iStreamTotal );
183 printf(" Avr blocks-per-stream: %f%%\n",
184 (float)n.getNumBlocks()/(float)iStreamCnt );
185
186 return 1;
187 }
115}; 188};
116 189
117 190