00001 #ifndef qsieve_header
00002 #define qsieve_header
00003
00009 #include "qsieve-fwd.H"
00010 #include "utils.H"
00011
00012 #ifdef CYGWIN_COMPAT
00013 extern "C"
00014 {
00015 #include <malloc.h>
00016 }
00017 #endif
00018
00019
00020
00021 #include "mpz_wrapper.H"
00022 using namespace my_mpz_wrapper;
00023
00024 #include "Tfactor.H"
00025 #include "TinyVector.H"
00026 typedef CTinyVector<StaticFactorbaseSettings::FBsizetype> CTinyFBsizetypeVector;
00027
00028 #include "myBitString.H"
00029
00030 using std::streampos;
00031
00032
00033 class CStreamEncoder
00034 {
00035 private:
00036 std::ostream &out;
00037 int prev_value;
00038 public:
00039 CStreamEncoder(std::ostream &out_) : out(out_), prev_value(0) { }
00040
00042 void PutValue(const int w);
00043 };
00044
00045 class CStreamDecoder
00046 {
00047 private:
00048 std::istream ∈
00049 int ahead_value;
00050 public:
00051 CStreamDecoder(std::istream &in_) : in(in_), ahead_value(0) { }
00052
00054 int GetValue();
00055 };
00056
00057 class CProvideHelperVariables : private ForbidAssignment, protected StaticFactorbaseSettings
00058 {
00059
00060
00061
00062 protected:
00063 mpz_t x,y;
00064 public:
00065 CProvideHelperVariables() { mpz_init(x); mpz_init(y); }
00066 ~CProvideHelperVariables() { mpz_clear(x); mpz_clear(y); }
00067 };
00068
00069 class CRelation : protected CProvideHelperVariables
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 {
00082 public:
00083 static const int no_factor = -1;
00084 static const int dynamic_factor = -2;
00085 static const int special_factor = -3;
00086 int relevant_factor;
00087
00088
00089
00090 private:
00091 CTinyFBsizetypeVector *Relation_sparse;
00092 myBitString *Relation_dense;
00093 mpz_t Delta;
00094 std::istream *pDynamicRelations_from_file;
00095
00096 public:
00098 static void (*seek_emergency_handler)(istream &, const streampos);
00099
00101 static void seek_emergency_default_handler(istream &, const streampos);
00102
00105 class ProvideDynamicRelationsStream
00106 {
00107 public:
00108 typedef istream *Pistream;
00109 private:
00110 Pistream &pistream;
00111 bool reuse;
00112 public:
00113
00114 ProvideDynamicRelationsStream(Pistream &pistream_);
00115
00116 ~ProvideDynamicRelationsStream();
00117 };
00118
00119 public:
00120 inline CRelation()
00121 : CProvideHelperVariables(), relevant_factor(no_factor),
00122 Relation_sparse(new CTinyFBsizetypeVector), Relation_dense(NULL),
00123 pDynamicRelations_from_file(NULL), pMulticombineData(NULL)
00124 {
00125 mpz_init_set_ui(Delta,1);
00126 }
00127
00128 inline ~CRelation()
00129 {
00130 #if 0
00131 if (Relation_sparse) { delete Relation_sparse; Relation_sparse=NULL; }
00132 if (Relation_dense) { delete Relation_dense; Relation_dense=NULL; }
00133 mpz_clear(Delta);
00134 relevant_factor=no_factor;
00135 #else
00136 delete Relation_sparse;
00137 delete Relation_dense;
00138 mpz_clear(Delta);
00139 #endif
00140 }
00141
00142 explicit CRelation(const signed int SievePos, short int HitCount=0);
00143
00144
00145
00146
00147
00148 public:
00149 int largest_factor_in_Relation() const
00150
00151 {
00152 if (Relation_sparse)
00153 if (Relation_sparse->empty()) return no_factor;
00154 else
00155 {
00156 return Relation_sparse->last();
00157 }
00158 else
00159 {
00160 return Relation_dense->last(1);
00161
00162
00163
00164
00165
00166 }
00167 }
00168
00169 int second_largest_factor_in_Relation() const
00170
00171 {
00172 if (Relation_sparse)
00173 if (Relation_sparse->size()>1)
00174 return (*Relation_sparse)[Relation_sparse->size()-2];
00175 else
00176 return no_factor;
00177 else
00178 {
00179 signed int vorletzter_Faktor=Relation_dense->last(1);
00180 if (vorletzter_Faktor>=0)
00181 return Relation_dense->prev(vorletzter_Faktor,1);
00182 else
00183 return no_factor;
00184 }
00185 }
00186
00187 inline unsigned int SizeOfRelation() const
00188 {
00189 if (Relation_sparse) return Relation_sparse->size();
00190 else return Relation_dense->count(1);
00191 }
00192
00197 inline void optisize(void)
00198 {
00199
00200
00201
00202
00203 const int size=SizeOfRelation();
00204 const int largest=largest_factor_in_Relation();
00205 const int quotient = size ? largest/size : 0;
00206
00207 if (Relation_sparse)
00208 {
00209 if (quotient<16-2) convert_Relation_to_dense();
00210 else Relation_sparse->optisize();
00211 }
00212 else
00213 {
00214 if (quotient>16+2) convert_Relation_to_sparse();
00215 else Relation_dense->optisize();
00216 }
00217 }
00218
00219 void convert_Relation_to_dense();
00220 void convert_Relation_to_sparse();
00221
00223 inline bool empty() const
00224 {
00225 return (relevant_factor==no_factor);
00226
00227
00228 }
00229
00230 void combine(const CRelation& GL2);
00232
00233
00234 public:
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 typedef unsigned short int TExponentArrayElement;
00247
00248 struct SMulticombineData
00249 {
00250 TExponentArrayElement ExponentArray[StaticFactorbaseSettings::MaxSize+64] __attribute__ ((aligned (16)));
00251
00252
00253
00254 unsigned long int multi_combine_Counter;
00255
00256 #if 1 && defined(ASM_SSE2)
00257 #ifdef DEBUG
00258 #warning "CRelation::SMulticombineData: using own new/delete to overcome alignment problems"
00259 #endif
00260
00261
00262
00263
00264 static void* operator new(size_t size)
00265 {
00266 void *p;
00267 #ifdef CYGWIN_COMPAT
00268 p = memalign(16,size);
00269 if ( p==NULL || (reinterpret_cast<int>(p)&0x0f) )
00270 {
00271 cout << "NULL or not aligned p: " << p << endl;
00272 throw std::bad_alloc();
00273 }
00274 #else
00275 if (posix_memalign(&p,16,size)) throw std::bad_alloc();
00276 #endif
00277 return p;
00278 }
00279 static void operator delete(void *p, size_t )
00280 {
00281 ::free(p);
00282 }
00283 #endif
00284
00285 SMulticombineData() : multi_combine_Counter(0)
00286 {
00287 #if defined(DEBUG) && (defined(ASM_SSE) || defined(ASM_SSE2))
00288 if (reinterpret_cast<unsigned int>(&ExponentArray[0]) &0x0fU)
00289 {
00290 MARK; cerr << "not 16-byte aligned!" << endl;
00291 cout << ExponentArray << endl;
00292 cout << this << endl;
00293 }
00294 #endif
00295 for (int i=0; i<StaticFactorbaseSettings::Size(); i++) ExponentArray[i]=0;
00296 }
00297 };
00298
00299 protected:
00300 SMulticombineData *pMulticombineData;
00301
00302
00303
00304 public:
00305 void set_MulticombineData(SMulticombineData *Data) { pMulticombineData=Data; }
00306 void invalidate_MulticombineData() { pMulticombineData=NULL; }
00307 void dispose_MulticombineData() { delete pMulticombineData; invalidate_MulticombineData(); }
00308 void use_MulticombineData_from(const CRelation &GL) { pMulticombineData=GL.pMulticombineData; }
00309 void multi_combine_init();
00310 void multi_combine_main(const CRelation& GL2);
00311 void multi_combine_exit();
00312
00313 protected:
00314 inline void adjust_multi_combine()
00315 {
00316
00317 if (++pMulticombineData->multi_combine_Counter>=std::numeric_limits<TExponentArrayElement>::max())
00318 {
00319 #ifdef VERBOSE
00320 cout << "intermediate multi_combine_exit() issued" << endl;
00321 #endif
00322 --pMulticombineData->multi_combine_Counter;
00323 multi_combine_exit();
00324 ++pMulticombineData->multi_combine_Counter;
00325 }
00326 }
00327
00328 public:
00329 bool ComputeQuadraticCongruence() const;
00330 bool is_valid() const;
00331 static bool is_valid(istream &in);
00332 inline void SanityCheck() const
00333 {
00334 if (!is_valid()) exit(1);
00335 }
00336 static void SanityCheck(istream &in)
00337 {
00338 if (!CRelation::is_valid(in)) exit(1);
00339 }
00340 static void SanityCheckRelationsFile(const std::string FileName);
00341
00342 private:
00343 inline void swap(CRelation &GL2)
00344 {
00345
00346
00347 std::swap(Relation_sparse,GL2.Relation_sparse);
00348 std::swap(Relation_dense,GL2.Relation_dense);
00349 std::swap(relevant_factor,GL2.relevant_factor);
00350 mpz_swap(Delta,GL2.Delta);
00351 }
00352 public:
00353 inline bool operator< (const CRelation &GL2) const
00354 {
00355 return relevant_factor < GL2.relevant_factor;
00356 }
00357 streampos save(ostream &out, const CmpqsFactor factor, const short int HitCount=0) const;
00358 inline streampos save(ostream &out, const int i=1, const short int HitCount=0) const
00359 {
00360 CmpqsFactor DLP;
00361 DLP=i;
00362 return save(out,DLP,HitCount);
00363 }
00364 CmpqsFactor combine(istream &in, const streampos pos);
00365 CmpqsFactor multi_combine_main(istream &in, const streampos pos);
00366 CmpqsFactor combine(istream &in);
00367 CmpqsFactor multi_combine_main(istream &in);
00368 friend ostream& operator<< (ostream& ostr, const CRelation& GL);
00369 friend class StaticRelations;
00370 friend class SpecialRelations;
00371 friend class Cprocess_clients;
00372 };
00373
00374
00376 ostream& operator<< (ostream& ostr, const CRelation& GL);
00377
00378
00379
00390 class TDynamicFactorRelation
00391 {
00392
00393
00394 private:
00395 static void append_DynamicFactor_for_sieving(const int DynFac);
00396 public:
00397 int factor;
00398 streampos fpos;
00399
00400 TDynamicFactorRelation() : factor(0), fpos(-1) { }
00401
00402 inline bool operator() (const TDynamicFactorRelation &t1, const TDynamicFactorRelation &t2) const
00403 {
00404
00405 return t1.factor<t2.factor;
00406 }
00407 inline int operator() (const TDynamicFactorRelation &t2) const
00408 {
00409
00410 return t2.factor;
00411 }
00412 inline bool operator== (const TDynamicFactorRelation &t2) const
00413 {
00414 return factor==t2.factor;
00415 }
00416 inline bool sieveable() const
00417 {
00418
00419 return factor<DynamicFactor_SievingThreshold;
00420 }
00421 inline void append_for_sieving() const
00422 {
00423 #ifndef IS_SERVER
00424
00425
00426 if (sieveable()) append_DynamicFactor_for_sieving(factor);
00427 #endif
00428 }
00429 };
00430
00431
00437 struct TSieve_Delta
00438 {
00439 int delta;
00440 int factor;
00441 inline bool operator< (const TSieve_Delta &v) const
00442 {
00443 #if defined (USE_FIBHEAP)
00444 return (delta < v.delta);
00445 #else
00446 return (delta > v.delta);
00447 #endif
00448
00449
00450 }
00451 };
00452
00453
00454 #endif