source: box/trunk/lib/backupstore/BackupStoreCheckData.cpp @ 2415

Revision 2415, 5.2 KB checked in by chris, 3 years ago (diff)

Rename NDEBUG flag to BOX_RELEASE_BUILD, as other projects use NDEBUG as
well (e.g. wxWidgets) and it causes conflicts which are difficult to
resolve.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    BackupStoreCheckData.cpp
5//              Purpose: Data handling for store checking
6//              Created: 21/4/04
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11
12#include <stdlib.h>
13#include <memory>
14
15#include "BackupStoreCheck.h"
16#include "autogen_BackupStoreException.h"
17
18#include "MemLeakFindOn.h"
19
20
21// --------------------------------------------------------------------------
22//
23// Function
24//              Name:    BackupStoreCheck::FreeInfo()
25//              Purpose: Free all the data stored
26//              Created: 21/4/04
27//
28// --------------------------------------------------------------------------
29void BackupStoreCheck::FreeInfo()
30{
31        // Free all the blocks
32        for(Info_t::iterator i(mInfo.begin()); i != mInfo.end(); ++i)
33        {
34                ::free(i->second);
35        }
36       
37        // Clear the contents of the map
38        mInfo.clear();
39       
40        // Reset the last ID, just in case
41        mpInfoLastBlock = 0;
42        mInfoLastBlockEntries = 0;
43        mLastIDInInfo = 0;
44}
45
46
47// --------------------------------------------------------------------------
48//
49// Function
50//              Name:    BackupStoreCheck::AddID(BackupStoreCheck_ID_t, BackupStoreCheck_ID_t, bool)
51//              Purpose: Add an ID to the list
52//              Created: 21/4/04
53//
54// --------------------------------------------------------------------------
55void BackupStoreCheck::AddID(BackupStoreCheck_ID_t ID,
56        BackupStoreCheck_ID_t Container, BackupStoreCheck_Size_t ObjectSize, bool IsFile)
57{
58        // Check ID is OK.
59        if(ID <= mLastIDInInfo)
60        {
61                THROW_EXCEPTION(BackupStoreException, InternalAlgorithmErrorCheckIDNotMonotonicallyIncreasing)
62        }
63       
64        // Can this go in the current block?
65        if(mpInfoLastBlock == 0 || mInfoLastBlockEntries >= BACKUPSTORECHECK_BLOCK_SIZE)
66        {
67                // No. Allocate a new one
68                IDBlock *pblk = (IDBlock*)::malloc(sizeof(IDBlock));
69                if(pblk == 0)
70                {
71                        throw std::bad_alloc();
72                }
73                // Zero all the flags entries
74                for(int z = 0; z < (BACKUPSTORECHECK_BLOCK_SIZE * Flags__NumFlags / Flags__NumItemsPerEntry); ++z)
75                {
76                        pblk->mFlags[z] = 0;
77                } 
78                // Store in map
79                mInfo[ID] = pblk;
80                // Allocated and stored OK, setup for use
81                mpInfoLastBlock = pblk;
82                mInfoLastBlockEntries = 0;
83        }
84        ASSERT(mpInfoLastBlock != 0 && mInfoLastBlockEntries < BACKUPSTORECHECK_BLOCK_SIZE);
85       
86        // Add to block
87        mpInfoLastBlock->mID[mInfoLastBlockEntries] = ID;
88        mpInfoLastBlock->mContainer[mInfoLastBlockEntries] = Container;
89        mpInfoLastBlock->mObjectSizeInBlocks[mInfoLastBlockEntries] = ObjectSize;
90        SetFlags(mpInfoLastBlock, mInfoLastBlockEntries, IsFile?(0):(Flags_IsDir));
91       
92        // Increment size
93        ++mInfoLastBlockEntries;
94       
95        // Store last ID
96        mLastIDInInfo = ID;
97}
98
99
100// --------------------------------------------------------------------------
101//
102// Function
103//              Name:    BackupStoreCheck::LookupID(BackupStoreCheck_ID_t, int32_t
104//              Purpose: Look up an ID. Return the block it's in, or zero if not found, and the
105//                               index within that block if the thing is found.
106//              Created: 21/4/04
107//
108// --------------------------------------------------------------------------
109BackupStoreCheck::IDBlock *BackupStoreCheck::LookupID(BackupStoreCheck_ID_t ID, int32_t &rIndexOut)
110{
111        IDBlock *pblock = 0;
112
113        // Find the lower matching block who's first entry is not less than ID
114        Info_t::const_iterator ib(mInfo.lower_bound(ID));
115       
116        // Was there a block
117        if(ib == mInfo.end())
118        {
119                // Block wasn't found... could be in last block
120                pblock = mpInfoLastBlock;
121        }
122        else
123        {
124                // Found it as first entry?
125                if(ib->first == ID)
126                {
127                        rIndexOut = 0;
128                        return ib->second;
129                }
130               
131                // Go back one block as it's not the first entry in this one
132                if(ib == mInfo.begin())
133                {
134                        // Was first block, can't go back
135                        return 0;
136                }
137                // Go back...
138                --ib;
139
140                // So, the ID will be in this block, if it's in anything
141                pblock = ib->second;
142        }
143
144        ASSERT(pblock != 0);
145        if(pblock == 0) return 0;
146       
147        // How many entries are there in the block
148        int32_t bentries = (pblock == mpInfoLastBlock)?mInfoLastBlockEntries:BACKUPSTORECHECK_BLOCK_SIZE;
149       
150        // Do binary search within block
151        int high = bentries;
152        int low = -1;
153        while(high - low > 1)
154        {
155                int i = (high + low) / 2;
156                if(ID <= pblock->mID[i])
157                {
158                        high = i;
159                }
160                else
161                {
162                        low = i;
163                }
164        }
165        if(ID == pblock->mID[high])
166        {
167                // Found
168                rIndexOut = high;
169                return pblock;
170        }
171
172        // Not found
173        return 0;
174}
175
176
177#ifndef BOX_RELEASE_BUILD
178// --------------------------------------------------------------------------
179//
180// Function
181//              Name:    BackupStoreCheck::DumpObjectInfo()
182//              Purpose: Debug only. Trace out all object info.
183//              Created: 22/4/04
184//
185// --------------------------------------------------------------------------
186void BackupStoreCheck::DumpObjectInfo()
187{
188        for(Info_t::const_iterator i(mInfo.begin()); i != mInfo.end(); ++i)
189        {
190                IDBlock *pblock = i->second;
191                int32_t bentries = (pblock == mpInfoLastBlock)?mInfoLastBlockEntries:BACKUPSTORECHECK_BLOCK_SIZE;
192                BOX_TRACE("BLOCK @ " << BOX_FORMAT_HEX32(pblock) <<
193                        ", " << bentries << " entries");
194               
195                for(int e = 0; e < bentries; ++e)
196                {
197                        uint8_t flags = GetFlags(pblock, e);
198                        BOX_TRACE(std::hex << 
199                                "id "  << pblock->mID[e] <<
200                                ", c " << pblock->mContainer[e] <<
201                                ", " << ((flags & Flags_IsDir)?"dir":"file") <<
202                                ", " << ((flags & Flags_IsContained) ? 
203                                        "contained":"unattached"));
204                }
205        }
206}
207#endif
208
Note: See TracBrowser for help on using the repository browser.