diff options
Diffstat (limited to 'src')
| -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 | ||
