aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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