source: box/trunk/lib/raidfile/RaidFileController.cpp @ 2411

Revision 2411, 6.4 KB checked in by chris, 3 years ago (diff)

Allow reinitialising the RaidFileController? by removing any existing
disc sets before adding new ones.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    RaidFileController.cpp
5//              Purpose: Controls config and daemon comms for RaidFile classes
6//              Created: 2003/07/08
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11
12#include <stdio.h>
13
14#include "RaidFileController.h"
15#include "RaidFileException.h"
16#include "Configuration.h"
17
18#include "MemLeakFindOn.h"
19
20RaidFileController RaidFileController::mController;
21
22// --------------------------------------------------------------------------
23//
24// Function
25//              Name:    RaidFileController::RaidFileController()
26//              Purpose: Constructor
27//              Created: 2003/07/08
28//
29// --------------------------------------------------------------------------
30RaidFileController::RaidFileController()
31{
32}
33
34// --------------------------------------------------------------------------
35//
36// Function
37//              Name:    RaidFileController::~RaidFileController()
38//              Purpose: Destructor
39//              Created: 2003/07/08
40//
41// --------------------------------------------------------------------------
42RaidFileController::~RaidFileController()
43{
44}
45
46// --------------------------------------------------------------------------
47//
48// Function
49//              Name:    RaidFileController::RaidFileController()
50//              Purpose: Copy constructor
51//              Created: 2003/07/08
52//
53// --------------------------------------------------------------------------
54RaidFileController::RaidFileController(const RaidFileController &rController)
55{
56        THROW_EXCEPTION(RaidFileException, Internal)
57}
58
59// --------------------------------------------------------------------------
60//
61// Function
62//              Name:    RaidFileController::Initialise(const std::string&)
63//              Purpose: Initialises the system, loading the configuration file.
64//              Created: 2003/07/08
65//
66// --------------------------------------------------------------------------
67void RaidFileController::Initialise(const std::string& rConfigFilename)
68{
69        MEMLEAKFINDER_NO_LEAKS;
70
71        static const ConfigurationVerifyKey verifykeys[] =
72        {
73                ConfigurationVerifyKey("SetNumber",
74                        ConfigTest_Exists | ConfigTest_IsInt),
75                ConfigurationVerifyKey("BlockSize",
76                        ConfigTest_Exists | ConfigTest_IsInt),
77                ConfigurationVerifyKey("Dir0", ConfigTest_Exists),
78                ConfigurationVerifyKey("Dir1", ConfigTest_Exists),
79                ConfigurationVerifyKey("Dir2",
80                        ConfigTest_Exists | ConfigTest_LastEntry)
81        };
82       
83        static const ConfigurationVerify subverify = 
84        {
85                "*",
86                0,
87                verifykeys,
88                ConfigTest_LastEntry,
89                0
90        };
91       
92        static const ConfigurationVerify verify = 
93        {
94                "RAID FILE CONFIG",
95                &subverify,
96                0,
97                ConfigTest_LastEntry,
98                0
99        };
100       
101        // Load the configuration
102        std::string err;
103        std::auto_ptr<Configuration> pconfig = Configuration::LoadAndVerify(
104                rConfigFilename, &verify, err);
105       
106        if(pconfig.get() == 0 || !err.empty())
107        {
108                BOX_ERROR("RaidFile configuration file errors: " << err);
109                THROW_EXCEPTION(RaidFileException, BadConfigFile)
110        }
111
112        // Allow reinitializing the controller by remove any existing
113        // disc sets. Used by Boxi unit tests.
114        mSetList.clear();
115       
116        // Use the values
117        int expectedSetNum = 0;
118        std::vector<std::string> confdiscs(pconfig->GetSubConfigurationNames());
119        for(std::vector<std::string>::const_iterator i(confdiscs.begin()); i != confdiscs.end(); ++i)
120        {
121                const Configuration &disc(pconfig->GetSubConfiguration((*i).c_str()));
122               
123                int setNum = disc.GetKeyValueInt("SetNumber");
124                if(setNum != expectedSetNum)
125                {
126                        THROW_EXCEPTION(RaidFileException, BadConfigFile)                       
127                }
128                RaidFileDiscSet set(setNum, (unsigned int)disc.GetKeyValueInt("BlockSize"));
129                // Get the values of the directory keys
130                std::string d0(disc.GetKeyValue("Dir0"));
131                std::string d1(disc.GetKeyValue("Dir1"));
132                std::string d2(disc.GetKeyValue("Dir2"));
133                // Are they all different (using RAID) or all the same (not using RAID)
134                if(d0 != d1 && d1 != d2 && d0 != d2)
135                {
136                        set.push_back(d0);
137                        set.push_back(d1);
138                        set.push_back(d2);
139                }
140                else if(d0 == d1 && d0 == d2)
141                {
142                        // Just push the first one, which is the non-RAID place to store files
143                        set.push_back(d0);
144                }
145                else
146                {
147                        // One must be the same as another! Which is bad.
148                        THROW_EXCEPTION(RaidFileException, BadConfigFile)                       
149                }
150                mSetList.push_back(set);
151                expectedSetNum++;
152        }
153}
154
155// --------------------------------------------------------------------------
156//
157// Function
158//              Name:    RaidFileController::GetDiscSet(int)
159//              Purpose: Returns the numbered disc set
160//              Created: 2003/07/08
161//
162// --------------------------------------------------------------------------
163RaidFileDiscSet &RaidFileController::GetDiscSet(unsigned int DiscSetNum)
164{
165        if(DiscSetNum < 0 || DiscSetNum >= mSetList.size())
166        {
167                THROW_EXCEPTION(RaidFileException, NoSuchDiscSet)
168        }
169
170        return mSetList[DiscSetNum];
171}
172
173
174
175// --------------------------------------------------------------------------
176//
177// Function
178//              Name:    RaidFileDiscSet::GetSetNumForWriteFiles(const std::string &)
179//              Purpose: Returns the set number the 'temporary' written files should
180//                               be stored on, given a filename.
181//              Created: 2003/07/10
182//
183// --------------------------------------------------------------------------
184int RaidFileDiscSet::GetSetNumForWriteFiles(const std::string &rFilename) const
185{
186        // Simple hash function, add up the ASCII values of all the characters,
187        // and get modulo number of partitions in the set.
188        std::string::const_iterator i(rFilename.begin());
189        int h = 0;
190        for(; i != rFilename.end(); ++i)
191        {
192                h += (*i);
193        }
194        return h % size();
195}
196
197
198// --------------------------------------------------------------------------
199//
200// Function
201//              Name:    RaidFileController::DiscSetPathToFileSystemPath(unsigned int, const std::string &, int)
202//              Purpose: Given a Raid File style file name, return a filename for the physical filing system.
203//                               DiscOffset is effectively the disc number (but remember files are rotated around the
204//                               discs in a disc set)
205//              Created: 19/1/04
206//
207// --------------------------------------------------------------------------
208std::string RaidFileController::DiscSetPathToFileSystemPath(unsigned int DiscSetNum, const std::string &rFilename, int DiscOffset)
209{
210        if(DiscSetNum < 0 || DiscSetNum >= mController.mSetList.size())
211        {
212                THROW_EXCEPTION(RaidFileException, NoSuchDiscSet)
213        }
214
215        // Work out which disc it's to be on
216        int disc = (mController.mSetList[DiscSetNum].GetSetNumForWriteFiles(rFilename) + DiscOffset)
217                                                % mController.mSetList[DiscSetNum].size();
218       
219        // Make the string
220        std::string r((mController.mSetList[DiscSetNum])[disc]);
221        r += DIRECTORY_SEPARATOR_ASCHAR;
222        r += rFilename;
223        return r;
224}
225
226
227
Note: See TracBrowser for help on using the repository browser.