00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ObjectManager_i.h"
00021 #include "DataStructures.h"
00022
00023 #include "../idl/Storage.hh"
00024 #include "../idl/Security.hh"
00025 #include "../Object/Properties.h"
00026 #include "../utils/URI.h"
00027 #include "../utils/NameServer.h"
00028 #include "../utils/Rand.h"
00029
00030 #include <values.h>
00031
00032 using namespace utils;
00033
00044 void fbfs::ObjectManager_i::validate() {
00045 TempRepository tr;
00046
00047
00048
00049
00050
00051
00052 for(Servers::iterator it = servers.begin(); it != servers.end(); it++) {
00053
00054
00055
00056 try {
00057 URI uri((*it).c_str());
00058 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri);
00059 fbfs::Storage_var server = fbfs::Storage::_narrow(obj);
00060 if(CORBA::is_nil(server))
00061 throw NotFound();
00062
00063 Obj_infoList *list = server->list(cert);
00064 for(int i=0; i<list->length(); i++) {
00065 Obj_info &info = (*list)[i];
00066 string name(info.id.name);
00067 InstanceInfo instance;
00068 instance.server = (*it);
00069 instance.prop = info.prop;
00070 instance.ts = info.ts;
00071 tr[name].push_front(instance);
00072 };
00073 } catch (...) {
00074
00075 servers.erase(it);
00076 };
00077 };
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 rep = Repository();
00089 for( TempRepository::iterator i = tr.begin(); i != tr.end(); i++ ) {
00090 Servers s = validate( (*i).first, (*i).second );
00091 if(s.size() != 0)
00092 rep[(*i).first] = s;
00093 };
00094 };
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 static void remove(const string &server, const string &objname, CORBA::ORB_ptr &orb, const fbfs::Security &cert) {
00124 try {
00125 URI uri(server.c_str());
00126 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri);
00127 fbfs::Storage_var server = fbfs::Storage::_narrow(obj);
00128 if(!CORBA::is_nil(server)) {
00129 fbfs::Obj_id id;
00130 id.name = CORBA::string_dup(objname.c_str());
00131 server->remove(cert, id);
00132 };
00133 } catch (...) {};
00134 };
00135
00136 fbfs::Servers fbfs::ObjectManager_i::validate(const string &objname, list<InstanceInfo> &infos) {
00137 int ts = MININT;
00138 list<InstanceInfo> newinfos = list<InstanceInfo>();
00139 list<InstanceInfo>::iterator it;
00140 for(it = infos.begin(); it != infos.end(); it++) {
00141 if((*it).ts.time == ts) {
00142
00143 newinfos.push_front(*it);
00144 } else if((*it).ts.time > ts) {
00145
00146
00147 for(list<InstanceInfo>::iterator i = newinfos.begin(); i != newinfos.end(); i++)
00148 ::remove((*i).server, objname, orb, cert);
00149 newinfos = list<InstanceInfo>();
00150 newinfos.push_front(*it);
00151 ts = (*it).ts.time;
00152 } else {
00153
00154 ::remove((*it).server, objname, orb, cert);
00155 };
00156 };
00157
00158
00159
00160
00161
00162 Obj_prop np;
00163 np.value_a = 0;
00164 np.value_b = 0;
00165
00166 for(it = newinfos.begin(); it != newinfos.end(); it++) {
00167 Obj_prop &props = (*it).prop;
00168 switch (props.type) {
00169 case Properties::REPLICATE_MIN_MAX :
00170 if(props.value_b > np.value_b)
00171 np.value_b = props.value_b;
00172 if(props.value_a > np.value_a)
00173 np.value_a = props.value_a;
00174 break;
00175 case Properties::REPLICATE_ALWAYS :
00176 if(props.value_a > np.value_b)
00177 np.value_b = props.value_a;
00178 case Properties::REPLICATE_ON_CREAT :
00179 if(props.value_a > np.value_a)
00180 np.value_a = props.value_a;
00181 case Properties::DONT_SAVE :
00182 ;
00183 };
00184 };
00185
00186 if(np.value_b == 0) {
00187 np.type = Properties::REPLICATE_ON_CREAT;
00188 if(np.value_a == 0)
00189 np.type = Properties::DONT_SAVE;
00190 } else if(np.value_a == np.value_b) {
00191 np.type = Properties::REPLICATE_ALWAYS;
00192 } else {
00193 np.type = Properties::REPLICATE_MIN_MAX;
00194 };
00195
00196
00197
00198
00199
00200
00201 Servers tempservers = servers;
00202 Servers newservers;
00203 for( it = newinfos.begin(); it != newinfos.end(); it++) {
00204 tempservers.remove( (*it).server );
00205 newservers.push_front( (*it).server );
00206 };
00207
00208 if(newinfos.size() >= np.value_b || newinfos.size() == servers.size() ) {
00209
00210 return newservers;
00211 };
00212
00213
00214
00215
00216 if(np.value_a > servers.size() )
00217 np.value_a = servers.size();
00218
00219
00220 int count = np.value_a - newinfos.size();
00221
00222 Servers::iterator vecchio = newservers.begin();
00223 Servers::iterator nuovo = tempservers.begin();
00224
00225 Servers finalservers = newservers;
00226
00227
00228
00229 for( int n = utils::rand(newservers.size()); n--; nuovo++);
00230
00231 for(int maxcycles=2*servers.size() ; count && maxcycles ; nuovo++, vecchio++, count--, maxcycles--) {
00232 if( vecchio == newservers.end() )
00233 vecchio = newservers.begin();
00234 if( nuovo == tempservers.end() )
00235 nuovo = tempservers.begin();
00236
00237
00238
00239 try {
00240 URI uri(*nuovo);
00241 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri);
00242 fbfs::Storage_var server = fbfs::Storage::_narrow(obj);
00243 if(!CORBA::is_nil(server)) {
00244 Obj_id id;
00245 id.name = CORBA::string_dup(objname.c_str());
00246 server->put_from_peer(cert, id, (*vecchio).c_str() );
00247 finalservers.push_front(*nuovo);
00248 };
00249 } catch (...) {
00250
00251 count++;
00252 };
00253 };
00254
00255 return finalservers;
00256 };