00001 00006 #include "StaticRelations.H" 00007 00008 CRelation* StaticRelations::GLS[StaticFactorbaseSettings::MaxSize] = {NULL}; 00009 int StaticRelations::Filling_GLS = 0; 00010 00011 filebuf StaticRelations::FileBuffer; 00012 ostream StaticRelations::StaticRelations_to_file(&StaticRelations::FileBuffer); 00013 istream StaticRelations::StaticRelations_from_file(&StaticRelations::FileBuffer); 00014 00015 00016 void StaticRelations::Load() 00017 { 00018 // reading static relations from file 00019 #ifdef VERBOSE_NOTICE 00020 cout << "Reading static relations from file..." << endl; 00021 #endif 00022 StaticRelations_from_file.seekg(0,ios::beg); 00023 while (StaticRelations_from_file.peek()=='G' || StaticRelations_from_file.peek()=='U') 00024 { 00025 if (StaticRelations_from_file.peek()=='U') 00026 { 00027 #ifdef VERBOSE_WARN 00028 cerr << "skipping obsolete/invalid relation." << endl; 00029 #endif 00030 StaticRelations_from_file.ignore(1000000,'\n'); 00031 continue; 00032 } 00033 CRelation* GL = new CRelation(); 00034 GL->combine(StaticRelations_from_file); 00035 GL->optisize(); // Relation optimieren (dense<->sparse, etc.) 00036 GLS[GL->relevant_factor]=GL; ++Filling_GLS; // insert relation into linear system of equations 00037 StaticRelations_from_file.ignore(1,'\n'); 00038 } 00039 if (StaticRelations_from_file.peek()!=EOF) 00040 { 00041 cerr << "Static Relations: garbage detected. Giving up. Please validate." << endl; 00042 exit(1); 00043 } 00044 StaticRelations_from_file.clear(); 00045 #ifdef VERBOSE_NOTICE 00046 cout << "Recover: " << StaticRelations::Count() << " static relations read." << endl; 00047 #endif 00048 } 00049 00050 void StaticRelations::insert(CRelation *GL, const bool do_multi_combine_init /* =true */) 00051 { 00052 /* Any new relation is inserted into the linear system of equations. 00053 If the relation is redundant or if it leads to a factorization, 00054 this will be detected automatically. */ 00055 00056 #ifdef IS_CLIENT 00057 // the Client does not manage any system of equations (which is instead handled by the server!) 00058 // so: delete the relation, do stats and return 00059 if (GL->relevant_factor >= 0) ++Filling_GLS; 00060 delete GL; 00061 return; 00062 #else 00063 if (GL->relevant_factor==CRelation::dynamic_factor || GL->relevant_factor==CRelation::special_factor) 00064 { delete GL; return; } // save it to background storage and delete it in main memory 00065 00066 #ifdef IS_SERVER 00067 // if this function is called by multiple threads, it is a critical section! 00068 // therefore we have to protect it with a mutex... 00069 static CCriticalSection::Mutex my_read_mutex; 00070 static CCriticalSection::Mutex my_write_mutex; 00071 CCriticalSection CriticalSection_Read(my_read_mutex); // enter Critial Section 00072 CCriticalSection CriticalSection_Write(my_write_mutex,false); // do not enter Additional Critical Section yet 00073 #endif 00074 00075 if (do_multi_combine_init) 00076 { 00077 CRelation::SMulticombineData *pMD=new(CRelation::SMulticombineData); 00078 GL->set_MulticombineData(pMD); 00079 GL->multi_combine_init(); 00080 } 00081 00082 while (!GL->empty()) 00083 { 00084 if (GL->relevant_factor>=StaticFactorbase::Size()) 00085 { 00086 MARK; 00087 cerr << "value too big!" << endl; 00088 exit(1); 00089 } 00090 CRelation *pos = GLS[GL->relevant_factor]; 00091 if (pos!=NULL) 00092 { 00093 // an entry for this relation already exists -> we can combine it!! 00094 #if 1 /* toggle minimization of relations (1=on/0=off) */ 00095 if ( 00096 (GL->Relation_sparse) && (pos->Relation_sparse) // both are sparse 00097 && GL->SizeOfRelation()<=pos->SizeOfRelation() 00098 && GL->second_largest_factor_in_Relation()<=pos->second_largest_factor_in_Relation() 00099 ) 00100 { 00101 /* weniger Primzahlen in der Relation bedeuten schnelleres Abarbeiten. 00102 Da beide Relationen äquivalent sind, können sie problemlos so 00103 getauscht werden, dass die platzsparende im Gleichungssystem verbleibt. 00104 Andererseits bestimmt das Maximum der zweitgrößten Faktoren zweier 00105 Relationen die nächste Verknüpfung. Also ist auch dies zu minimieren. 00106 Beim Zielkonflikt wären beide Kriterien also abzuwägen. Dies geschieht 00107 hier nicht. Nur wenn beide Kriterien zugleich die Lage nicht 00108 verschlechtern, werden die Relationen getauscht. 00109 00110 Please note, that swapping the two relations does not change the the result of 00111 the combine operation. But it may help to speed-up later combinations and/or 00112 and/or reduces memory consumption. 00113 */ 00114 00115 #ifdef IS_SERVER 00116 // if we can retrieve the write lock immediately, then 00117 // we perform the optimization, otherwise we simply continue... 00118 if (!CriticalSection_Write.try_enter()) 00119 { 00120 #if defined(VERBOSE_INFO) || 1 00121 static unsigned int count = 0; 00122 ++count; 00123 if ((count&0x1f)==0) 00124 cout << "Elided optimizations due to write-locked Static Relations: " << count << endl; 00125 #endif 00126 } 00127 else 00128 { 00129 #if defined(VERBOSE_INFO) || 1 00130 static unsigned int count = 0; 00131 ++count; 00132 if ((count&0x1f)==0) 00133 cout << "Performed optimizations due to unlocked Static Relations: " << count << endl; 00134 #endif 00135 #endif 00136 GL->multi_combine_exit(); 00137 GLS[GL->relevant_factor]=GL; 00138 std::swap(pos,GL); // swap relations 00139 GL->use_MulticombineData_from(*pos); 00140 pos->invalidate_MulticombineData(); 00141 GL->multi_combine_init(); 00142 #ifdef IS_SERVER 00143 CriticalSection_Write.leave(); 00144 } 00145 #endif 00146 } 00147 #endif 00148 // biggest factor has to be eliminated 00149 GL->multi_combine_main(*pos); 00150 } 00151 else 00152 { 00153 GL->multi_combine_exit(); 00154 GL->dispose_MulticombineData(); 00155 00156 #ifdef IS_SERVER 00157 CriticalSection_Write.enter(); 00158 #endif 00159 00160 GLS[GL->relevant_factor]=GL; // insert relation into linear system of equations 00161 Filling_GLS++; // one more relation in the system of linear equations 00162 00163 #ifdef IS_SERVER 00164 CriticalSection_Read.leave(); 00165 #endif 00166 00167 GL->save(StaticRelations_to_file); 00168 // usleep(11000); // only for debugging: simulate slow filesystem 00169 StatusReport(); 00170 return; 00171 } 00172 } 00173 00174 GL->multi_combine_exit(); 00175 GL->dispose_MulticombineData(); 00176 00177 // the relation is redundant: 00178 // -> we cannot insert it into the static factorbase, 00179 // -> it can yield a factor instead! 00180 // -> compute quadratic congruency! 00181 const bool complete = GL->ComputeQuadraticCongruence(); 00182 delete GL; 00183 if (complete) 00184 { 00185 // Game over, we have won! 00186 // leave the program... 00187 ExitManager::StopFactorization(); // try to stop the program successfully... 00188 exit(0); // this line should not be reached! 00189 } 00190 #endif 00191 }