source: box/trunk/bin/bbackupd/BackupClientInodeToIDMap.cpp @ 2794

Revision 2794, 6.0 KB checked in by chris, 19 months ago (diff)

Revert [2710] and [2717], remove TDB and replace with QDBM again, to fix
build on Windows and make it easier to merge Charles' work.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    BackupClientInodeToIDMap.cpp
5//              Purpose: Map of inode numbers to file IDs on the store
6//              Created: 11/11/03
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11
12#include <stdlib.h>
13#include <depot.h>
14
15#define BACKIPCLIENTINODETOIDMAP_IMPLEMENTATION
16#include "BackupClientInodeToIDMap.h"
17#undef BACKIPCLIENTINODETOIDMAP_IMPLEMENTATION
18
19#include "BackupStoreException.h"
20
21#include "MemLeakFindOn.h"
22
23typedef struct
24{
25        int64_t mObjectID;
26        int64_t mInDirectory;
27} IDBRecord;
28
29#define BOX_DBM_MESSAGE(stuff) stuff << " (qdbm): " << dperrmsg(dpecode)
30
31#define BOX_LOG_DBM_ERROR(stuff) \
32        BOX_ERROR(BOX_DBM_MESSAGE(stuff))
33
34#define THROW_DBM_ERROR(message, filename, exception, subtype) \
35        BOX_LOG_DBM_ERROR(message << ": " << filename); \
36        THROW_EXCEPTION_MESSAGE(exception, subtype, \
37                BOX_DBM_MESSAGE(message << ": " << filename));
38
39#define ASSERT_DBM_OK(operation, message, filename, exception, subtype) \
40        if(!(operation)) \
41        { \
42                THROW_DBM_ERROR(message, filename, exception, subtype); \
43        }
44
45#define ASSERT_DBM_OPEN() \
46        if(mpDepot == 0) \
47        { \
48                THROW_EXCEPTION_MESSAGE(BackupStoreException, InodeMapNotOpen, \
49                        "Inode database not open"); \
50        }
51
52#define ASSERT_DBM_CLOSED() \
53        if(mpDepot != 0) \
54        { \
55                THROW_EXCEPTION_MESSAGE(CommonException, Internal, \
56                        "Inode database already open: " << mFilename); \
57        }
58
59// --------------------------------------------------------------------------
60//
61// Function
62//              Name:    BackupClientInodeToIDMap::BackupClientInodeToIDMap()
63//              Purpose: Constructor
64//              Created: 11/11/03
65//
66// --------------------------------------------------------------------------
67BackupClientInodeToIDMap::BackupClientInodeToIDMap()
68        : mReadOnly(true),
69          mEmpty(false),
70          mpDepot(0)
71{
72}
73
74// --------------------------------------------------------------------------
75//
76// Function
77//              Name:    BackupClientInodeToIDMap::~BackupClientInodeToIDMap()
78//              Purpose: Destructor
79//              Created: 11/11/03
80//
81// --------------------------------------------------------------------------
82BackupClientInodeToIDMap::~BackupClientInodeToIDMap()
83{
84        if(mpDepot != 0)
85        {
86                Close();
87        }
88}
89
90// --------------------------------------------------------------------------
91//
92// Function
93//              Name:    BackupClientInodeToIDMap::Open(const char *, bool, bool)
94//              Purpose: Open the database map, creating a file on disc to store everything
95//              Created: 20/11/03
96//
97// --------------------------------------------------------------------------
98void BackupClientInodeToIDMap::Open(const char *Filename, bool ReadOnly,
99        bool CreateNew)
100{
101        mFilename = Filename;
102
103        // Correct arguments?
104        ASSERT(!(CreateNew && ReadOnly));
105       
106        // Correct usage?
107        ASSERT_DBM_CLOSED();
108        ASSERT(!mEmpty);
109       
110        // Open the database file
111        int mode = ReadOnly ? DP_OREADER : DP_OWRITER;
112        if(CreateNew)
113        {
114                mode |= DP_OCREAT;
115        }
116       
117        mpDepot = dpopen(Filename, mode, 0);
118       
119        ASSERT_DBM_OK(mpDepot, "Failed to open inode database", mFilename,
120                BackupStoreException, BerkelyDBFailure);
121       
122        // Read only flag
123        mReadOnly = ReadOnly;
124}
125
126// --------------------------------------------------------------------------
127//
128// Function
129//              Name:    BackupClientInodeToIDMap::OpenEmpty()
130//              Purpose: 'Open' this map. Not associated with a disc file.
131//                       Useful for when a map is required, but is against
132//                       an empty file on disc which shouldn't be created.
133//                       Implies read only.
134//              Created: 20/11/03
135//
136// --------------------------------------------------------------------------
137void BackupClientInodeToIDMap::OpenEmpty()
138{
139        ASSERT_DBM_CLOSED();
140        ASSERT(mpDepot == 0);
141        mEmpty = true;
142        mReadOnly = true;
143}
144
145// --------------------------------------------------------------------------
146//
147// Function
148//              Name:    BackupClientInodeToIDMap::Close()
149//              Purpose: Close the database file
150//              Created: 20/11/03
151//
152// --------------------------------------------------------------------------
153void BackupClientInodeToIDMap::Close()
154{
155        ASSERT_DBM_OPEN();
156        ASSERT_DBM_OK(dpclose(mpDepot), "Failed to close inode database",
157                mFilename, BackupStoreException, BerkelyDBFailure);
158        mpDepot = 0;
159}
160
161// --------------------------------------------------------------------------
162//
163// Function
164//              Name:    BackupClientInodeToIDMap::AddToMap(InodeRefType,
165//                       int64_t, int64_t)
166//              Purpose: Adds an entry to the map. Overwrites any existing
167//                       entry.
168//              Created: 11/11/03
169//
170// --------------------------------------------------------------------------
171void BackupClientInodeToIDMap::AddToMap(InodeRefType InodeRef, int64_t ObjectID,
172        int64_t InDirectory)
173{
174        if(mReadOnly)
175        {
176                THROW_EXCEPTION(BackupStoreException, InodeMapIsReadOnly);
177        }
178
179        if(mpDepot == 0)
180        {
181                THROW_EXCEPTION(BackupStoreException, InodeMapNotOpen);
182        }
183
184        ASSERT_DBM_OPEN();
185
186        // Setup structures
187        IDBRecord rec;
188        rec.mObjectID = ObjectID;
189        rec.mInDirectory = InDirectory;
190
191        ASSERT_DBM_OK(dpput(mpDepot, (const char *)&InodeRef, sizeof(InodeRef),
192                (const char *)&rec, sizeof(rec), DP_DOVER),
193                "Failed to add record to inode database", mFilename,
194                BackupStoreException, BerkelyDBFailure);
195}
196
197// --------------------------------------------------------------------------
198//
199// Function
200//              Name:    BackupClientInodeToIDMap::Lookup(InodeRefType,
201//                       int64_t &, int64_t &) const
202//              Purpose: Looks up an inode in the map, returning true if it
203//                       exists, and the object ids of it and the directory
204//                       it's in the reference arguments.
205//              Created: 11/11/03
206//
207// --------------------------------------------------------------------------
208bool BackupClientInodeToIDMap::Lookup(InodeRefType InodeRef,
209        int64_t &rObjectIDOut, int64_t &rInDirectoryOut) const
210{
211        if(mEmpty)
212        {
213                // Map is empty
214                return false;
215        }
216
217        if(mpDepot == 0)
218        {
219                THROW_EXCEPTION(BackupStoreException, InodeMapNotOpen);
220        }
221       
222        ASSERT_DBM_OPEN();
223
224        IDBRecord rec;
225       
226        if(dpgetwb(mpDepot, (const char *)&InodeRef, sizeof(InodeRef),
227                0, sizeof(IDBRecord), (char *)&rec) == -1)
228        {
229                // key not in file
230                return false;
231        }
232               
233        // Return data
234        rObjectIDOut = rec.mObjectID;
235        rInDirectoryOut = rec.mInDirectory;
236
237        // Found
238        return true;
239}
Note: See TracBrowser for help on using the repository browser.