diff options
author | Mike Buland <eichlan@xagasoft.com> | 2009-01-27 21:45:03 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2009-01-27 21:45:03 +0000 |
commit | 67ec9d667ab0c3f2258f6f69308d0731e74a74d0 (patch) | |
tree | eaaccf38aeecbb22b06b0156a40cf0dbb66c7bdc /src | |
parent | 00bb8c39b97638c872ebccc6aee7f3c5fb57d7d6 (diff) | |
download | libbu++-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.
Diffstat (limited to '')
-rw-r--r-- | src/cachestorenids.h | 13 | ||||
-rw-r--r-- | src/nids.cpp | 16 | ||||
-rw-r--r-- | src/nids.h | 8 | ||||
-rw-r--r-- | src/tests/nidstool.cpp | 115 |
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 | ||
12 | static int iCnt = 0; | ||
13 | |||
14 | namespace Bu | 12 | namespace 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 | ||
124 | void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock, | 124 | void 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 | ||
145 | uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, | 145 | uint32_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 | ||
163 | int Bu::Nids::createStream( int iPreAllocate ) | 163 | int Bu::Nids::createStream( int iPreAllocate ) |
164 | { | 164 | { |
165 | return createBlock( blockUnused, blockUnused, iPreAllocate ); | 165 | return createBlock( blockUnused, /*blockUnused,*/ iPreAllocate ); |
166 | } | 166 | } |
167 | 167 | ||
168 | void Bu::Nids::deleteStream( int /*iID*/ ) | 168 | void 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 | ||
@@ -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 | ||
8 | typedef struct Block | ||
9 | { | ||
10 | uint32_t uFirstBlock; | ||
11 | uint32_t uNextBlock; | ||
12 | uint32_t uBytesUsed; | ||
13 | } Block; | ||
14 | |||
8 | class Param : public Bu::ParamProc | 15 | class Param : public Bu::ParamProc |
9 | { | 16 | { |
10 | public: | 17 | public: |
@@ -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 | ||