diff --git a/src/qsieve.h b/src/qsieve.h
index 5e4b76af12..4c88ceacc6 100644
--- a/src/qsieve.h
+++ b/src/qsieve.h
@@ -167,8 +167,10 @@ typedef struct
RELATION DATA
***************************************************************************/
- FLINT_FILE * siqs; /* pointer to file for storing relations */
- char * fname; /* name of file used for relations */
+ char * siqs; /* pointer to storage */
+ char * siqs_cur; /* pointer to current position in storage */
+ slong siqs_alloc; /* number of bytes allocated */
+ slong siqs_size; /* number of bytes used */
slong full_relation; /* number of full relations */
slong num_cycles; /* number of possible full relations from partials */
@@ -420,6 +422,100 @@ uint64_t * block_lanczos(flint_rand_t state, slong nrows,
void qsieve_square_root(fmpz_t X, fmpz_t Y, qs_t qs_inf,
uint64_t * nullrows, slong ncols, slong l, fmpz_t N);
+#define QS_SIQS_SIZE_LEFT(qs_inf) ((slong) ((qs_inf)->siqs + (qs_inf)->siqs_size - (qs_inf)->siqs_cur))
+#define QS_SIQS_ALLOC_LEFT(qs_inf) ((slong) ((qs_inf)->siqs + (qs_inf)->siqs_alloc - (qs_inf)->siqs_cur))
+
+#define QS_SIQS_INIT_ALLOC_SIZE (sizeof(char) * (WORD(1) << 25)) /* 32 MB */
+
+#define QS_SIQS_INIT(qs_inf) \
+do \
+{ \
+ (qs_inf)->siqs = flint_malloc(QS_SIQS_INIT_ALLOC_SIZE); \
+ /* Do not set (qs_inf)->siqs_cur */ \
+ (qs_inf)->siqs_alloc = QS_SIQS_INIT_ALLOC_SIZE; \
+ (qs_inf)->siqs_size = 0; \
+} while (0)
+#define QS_SIQS_REALLOC(qs_inf, size) \
+do \
+{ \
+ char * __tmp = flint_realloc((qs_inf)->siqs, size); \
+ (qs_inf)->siqs_cur = __tmp + ((qs_inf)->siqs_cur - (qs_inf)->siqs); \
+ (qs_inf)->siqs = __tmp; \
+ (qs_inf)->siqs_alloc = (size); \
+} while (0)
+#define QS_SIQS_CLEAR(qs_inf) \
+do \
+{ \
+ flint_free((qs_inf)->siqs); \
+ (qs_inf)->siqs = NULL; \
+ /* Do not clear (qs_inf)->siqs_cur */ \
+ (qs_inf)->siqs_alloc = 0; \
+ (qs_inf)->siqs_size = 0; \
+} while (0)
+
+#define QS_SIQS_FCLOSE(qs_inf) \
+do \
+{ \
+ (qs_inf)->siqs_cur = NULL; \
+} while (0)
+#define QS_SIQS_FOPEN_R(qs_inf) \
+do \
+{ \
+ (qs_inf)->siqs_cur = (qs_inf)->siqs; \
+} while (0)
+#define QS_SIQS_FOPEN_W(qs_inf) \
+do \
+{ \
+ (qs_inf)->siqs_cur = (qs_inf)->siqs; \
+ (qs_inf)->siqs_size = 0; \
+} while (0)
+#define QS_SIQS_FOPEN_A(qs_inf) \
+do \
+{ \
+ (qs_inf)->siqs_cur = (qs_inf)->siqs + (qs_inf)->siqs_size; \
+} while (0)
+
+#define QS_SIQS_FREAD(res, ptr, size, count, qs_inf) \
+do \
+{ \
+ slong _max_read \
+ = FLINT_MIN((slong) (size) * (slong) (count), \
+ QS_SIQS_SIZE_LEFT(qs_inf)); \
+ \
+ memcpy(ptr, (qs_inf)->siqs_cur, _max_read); \
+ (qs_inf)->siqs_cur += _max_read; \
+ (res) = _max_read; \
+} while (0)
+#define QS_SIQS_FREAD_NORES(ptr, size, count, qs_inf) \
+do \
+{ \
+ slong __useless; \
+ QS_SIQS_FREAD(__useless, ptr, size, count, qs_inf); \
+} while (0)
+#define QS_SIQS_FWRITE(ptr, size, count, qs_inf) \
+do \
+{ \
+ slong _write_size = (slong) (size) * (slong) (count); \
+ \
+ /* Here we assume that the relation size is always */ \
+ /* less than QS_SIQS_INIT_ALLOC_SIZE */ \
+ if (_write_size > QS_SIQS_ALLOC_LEFT(qs_inf)) \
+ QS_SIQS_REALLOC(qs_inf, 2 * (qs_inf)->siqs_alloc); \
+ \
+ memcpy((qs_inf)->siqs_cur, ptr, _write_size); \
+ (qs_inf)->siqs_cur += _write_size; \
+ (qs_inf)->siqs_size += _write_size; \
+} while (0)
+
+#define QS_SIQS_FSEEK_SEEK_CUR(qs_inf, offset) \
+do \
+{ \
+ slong _jump_size \
+ = FLINT_MIN((slong) (offset), QS_SIQS_SIZE_LEFT(qs_inf)); \
+ \
+ (qs_inf)->siqs_cur += _jump_size; \
+} while (0)
+
#ifdef __cplusplus
}
#endif
diff --git a/src/qsieve/clear.c b/src/qsieve/clear.c
index edfba23fbb..8b70af3ef7 100644
--- a/src/qsieve/clear.c
+++ b/src/qsieve/clear.c
@@ -23,6 +23,4 @@ void qsieve_clear(qs_t qs_inf)
qs_inf->factor_base = NULL;
qs_inf->sqrts = NULL;
-
- flint_free(qs_inf->fname);
}
diff --git a/src/qsieve/factor.c b/src/qsieve/factor.c
index c815a72862..36a5c74a5f 100644
--- a/src/qsieve/factor.c
+++ b/src/qsieve/factor.c
@@ -11,32 +11,14 @@
(at your option) any later version. See .
*/
-#define _STDC_FORMAT_MACROS
-
-#ifdef __GNUC__
-# define strcpy __builtin_strcpy
-#else
-# include
-#endif
-
-/* try to get fdopen, mkstemp declared */
-#if defined __STRICT_ANSI__
-#undef __STRICT_ANSI__
-#endif
-
-#include
#include
+#include
#include "thread_support.h"
#include "fmpz.h"
#include "fmpz_factor.h"
#include "fmpz_vec.h"
#include "qsieve.h"
-/* Use Windows API for temporary files under MSVC and MinGW */
-#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
-#include
-#endif
-
int compare_facs(const void * a, const void * b)
{
fmpz * x = (fmpz *) a;
@@ -63,11 +45,6 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
fmpz_t temp, temp2, X, Y;
slong num_facs;
fmpz * facs;
-#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
- char temp_path[MAX_PATH];
-#else
- int fd;
-#endif
if (fmpz_sgn(n) < 0)
{
@@ -214,41 +191,8 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
pthread_mutex_init(&qs_inf->mutex, NULL);
#endif
-#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
- if (GetTempPathA(MAX_PATH, temp_path) == 0)
- {
- flint_printf("Exception (qsieve_factor). GetTempPathA() failed.\n");
- flint_abort();
- }
- /* uUnique = 0 means the we *do* want a unique filename (obviously!). */
- if (GetTempFileNameA(temp_path, "siq", /*uUnique*/ 0, qs_inf->fname) == 0)
- {
- flint_printf("Exception (qsieve_factor). GetTempFileNameA() failed.\n");
- flint_abort();
- }
- qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "wb");
- if (qs_inf->siqs == NULL)
- flint_throw(FLINT_ERROR, "fopen failed\n");
-#else
- strcpy(qs_inf->fname, "/tmp/siqsXXXXXX"); /* must be shorter than fname_alloc_size in init.c */
- fd = mkstemp(qs_inf->fname);
- if (fd == -1)
- flint_throw(FLINT_ERROR, "mkstemp failed\n");
-
- qs_inf->siqs = (FLINT_FILE *) fdopen(fd, "wb");
- if (qs_inf->siqs == NULL)
- flint_throw(FLINT_ERROR, "fdopen failed\n");
-#endif
- /*
- * The code here and in large_prime_variant.c opens and closes the file
- * qs_inf->fname in several different places. On Windows all file handles
- * need to be closed before the file can be removed in cleanup at function
- * exit. The invariant that needs to be preserved at each open/close is
- * that either
- * qs_inf->siqs is NULL and there are no open handles to the file,
- * or
- * qs_inf->siqs is not NULL and is the *only* open handle to the file.
- */
+ QS_SIQS_INIT(qs_inf);
+ QS_SIQS_FOPEN_W(qs_inf);
for (j = qs_inf->small_primes; j < qs_inf->num_primes; j++)
{
@@ -290,9 +234,7 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
{
int ok;
- if (fclose((FILE *) qs_inf->siqs))
- flint_throw(FLINT_ERROR, "fclose fail\n");
- qs_inf->siqs = NULL;
+ QS_SIQS_FCLOSE(qs_inf);
ok = qsieve_process_relation(qs_inf);
@@ -406,9 +348,7 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
_fmpz_vec_clear(facs, 100);
- qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "wb");
- if (qs_inf->siqs == NULL)
- flint_throw(FLINT_ERROR, "fopen fail\n");
+ QS_SIQS_FOPEN_W(qs_inf);
qs_inf->num_primes = num_primes; /* linear algebra adjusts this */
goto more_primes; /* factoring failed, may need more primes */
}
@@ -486,11 +426,8 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
flint_give_back_threads(qs_inf->handles, qs_inf->num_handles);
flint_free(sieve);
- if (qs_inf->siqs != NULL && fclose((FILE *) qs_inf->siqs))
- flint_throw(FLINT_ERROR, "fclose fail\n");
- if (remove(qs_inf->fname)) {
- flint_throw(FLINT_ERROR, "remove fail\n");
- }
+ QS_SIQS_FCLOSE(qs_inf);
+ QS_SIQS_CLEAR(qs_inf);
qsieve_clear(qs_inf);
qsieve_linalg_clear(qs_inf);
qsieve_poly_clear(qs_inf);
diff --git a/src/qsieve/init.c b/src/qsieve/init.c
index 1c5b162a27..2efc6933f1 100644
--- a/src/qsieve/init.c
+++ b/src/qsieve/init.c
@@ -13,22 +13,10 @@
#include "fmpz.h"
#include "qsieve.h"
-#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
-#include
-#endif
-
void qsieve_init(qs_t qs_inf, const fmpz_t n)
{
- size_t fname_alloc_size;
slong i;
-#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
- fname_alloc_size = MAX_PATH;
-#else
- fname_alloc_size = 20;
-#endif
- qs_inf->fname = (char *) flint_malloc(fname_alloc_size); /* space for filename */
-
/* store n in struct */
fmpz_init_set(qs_inf->n, n);
diff --git a/src/qsieve/large_prime_variant.c b/src/qsieve/large_prime_variant.c
index 9c18c4f702..cd5ece4cb0 100644
--- a/src/qsieve/large_prime_variant.c
+++ b/src/qsieve/large_prime_variant.c
@@ -10,18 +10,12 @@
(at your option) any later version. See .
*/
-#include
#include
+#include
#include
#include "fmpz.h"
#include "qsieve.h"
-#ifdef __GNUC__
-# define memset __builtin_memset
-#else
-# include
-#endif
-
#define HASH_MULT (2654435761U) /* hash function, taken from 'msieve' */
#define HASH(a) ((ulong)((((unsigned int) a) * HASH_MULT) >> (12)))
@@ -131,26 +125,26 @@ void qsieve_write_to_file(qs_t qs_inf, mp_limb_t prime, const fmpz_t Y, const qs
+ sizeof(fac_t) * num_factors /* factors */
+ sizeof(slong) /* Y->_mp_size */
+ sizeof(mp_limb_t) * (Ysz != 0 ? FLINT_ABS(Ysz) : 1); /* Y->_mp_d */
- fwrite(&write_size, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(&write_size, sizeof(slong), 1, qs_inf);
/* Write large prime */
- fwrite(&prime, sizeof(mp_limb_t), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(&prime, sizeof(mp_limb_t), 1, qs_inf);
/* NOTE: We do not have to write small primes. */
/* Write number of small primes */
- fwrite(&qs_inf->small_primes, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(&qs_inf->small_primes, sizeof(slong), 1, qs_inf);
/* Write small primes */
- fwrite(small, sizeof(slong), qs_inf->small_primes, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(small, sizeof(slong), qs_inf->small_primes, qs_inf);
/* Write number of factors */
- fwrite(&num_factors, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(&num_factors, sizeof(slong), 1, qs_inf);
/* Write factors and exponents */
- fwrite(factor, sizeof(fac_t), num_factors, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(factor, sizeof(fac_t), num_factors, qs_inf);
/* Write Y->_mp_size (or mock it) */
- fwrite(&Ysz, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(&Ysz, sizeof(slong), 1, qs_inf);
/* Write Y->_mp_d (or mock it) */
if (!COEFF_IS_MPZ(*Y))
@@ -158,14 +152,14 @@ void qsieve_write_to_file(qs_t qs_inf, mp_limb_t prime, const fmpz_t Y, const qs
slong abslimb = FLINT_ABS(*Y);
/* Write mock Y->_mp_d */
- fwrite(&abslimb, sizeof(mp_limb_t), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(&abslimb, sizeof(mp_limb_t), 1, qs_inf);
}
else
{
mp_srcptr Yd = COEFF_TO_PTR(*Y)->_mp_d;
/* Write Y->_mp_d */
- fwrite(Yd, sizeof(mp_limb_t), FLINT_ABS(Ysz), (FILE *) qs_inf->siqs);
+ QS_SIQS_FWRITE(Yd, sizeof(mp_limb_t), FLINT_ABS(Ysz), qs_inf);
}
}
@@ -264,22 +258,22 @@ relation_t qsieve_parse_relation(qs_t qs_inf)
/* NOTE: We can use qs_inf->small_primes here instead of reading. */
/* Get number of small primes */
- fread(&rel.small_primes, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(&rel.small_primes, sizeof(slong), 1, qs_inf);
/* Get small primes */
rel.small = flint_malloc(rel.small_primes * sizeof(slong));
- fread(rel.small, sizeof(slong), rel.small_primes, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(rel.small, sizeof(slong), rel.small_primes, qs_inf);
/* Get number of factors */
- fread(&rel.num_factors, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(&rel.num_factors, sizeof(slong), 1, qs_inf);
/* Get factors */
rel.factor = flint_malloc(rel.num_factors * sizeof(fac_t));
- fread(rel.factor, sizeof(fac_t), rel.num_factors, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(rel.factor, sizeof(fac_t), rel.num_factors, qs_inf);
/* Get Ysz */
Ysz = 0;
- fread(&Ysz, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(&Ysz, sizeof(slong), 1, qs_inf);
/* Get Y */
fmpz_init(rel.Y);
@@ -287,7 +281,7 @@ relation_t qsieve_parse_relation(qs_t qs_inf)
{
mp_limb_t abslimb = 0;
- fread(&abslimb, sizeof(mp_limb_t), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(&abslimb, sizeof(mp_limb_t), 1, qs_inf);
#if COEFF_MAX != -COEFF_MIN
# error
@@ -305,7 +299,7 @@ relation_t qsieve_parse_relation(qs_t qs_inf)
if (mY->_mp_alloc < FLINT_ABS(Ysz))
_mpz_realloc(mY, FLINT_ABS(Ysz));
- fread(mY->_mp_d, sizeof(mp_limb_t), FLINT_ABS(Ysz), (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(mY->_mp_d, sizeof(mp_limb_t), FLINT_ABS(Ysz), qs_inf);
*rel.Y = PTR_TO_COEFF(mY);
}
@@ -557,11 +551,8 @@ int qsieve_process_relation(qs_t qs_inf)
relation_t * rlist;
int done = 0;
- if (qs_inf->siqs != NULL && fclose((FILE *) qs_inf->siqs))
- flint_throw(FLINT_ERROR, "fclose fail\n");
- qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "rb");
- if (qs_inf->siqs == NULL)
- flint_throw(FLINT_ERROR, "fopen fail\n");
+ QS_SIQS_FCLOSE(qs_inf);
+ QS_SIQS_FOPEN_R(qs_inf);
#if QS_DEBUG & 64
flint_printf("Getting relations\n");
@@ -569,15 +560,15 @@ int qsieve_process_relation(qs_t qs_inf)
while (1)
{
- int siqs_eof;
- slong write_size = 0;
+ int read_size;
+ slong relation_size = 0;
- siqs_eof = !fread(&write_size, sizeof(slong), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD(read_size, &relation_size, sizeof(slong), 1, qs_inf);
- if (siqs_eof)
+ if (read_size != sizeof(slong))
break;
- fread(&prime, sizeof(mp_limb_t), 1, (FILE *) qs_inf->siqs);
+ QS_SIQS_FREAD_NORES(&prime, sizeof(mp_limb_t), 1, qs_inf);
entry = qsieve_get_table_entry(qs_inf, prime);
if (num_relations == rel_size)
@@ -596,13 +587,11 @@ int qsieve_process_relation(qs_t qs_inf)
{
/* We have to get to the next relation in the file. We have already
* read write_size (is a slong) and large prime (is an mp_limb_t).*/
- fseek((FILE *) qs_inf->siqs, write_size - sizeof(slong) - sizeof(mp_limb_t), SEEK_CUR);
+ QS_SIQS_FSEEK_SEEK_CUR(qs_inf, relation_size - sizeof(slong) - sizeof(mp_limb_t));
}
}
- if(fclose((FILE *) qs_inf->siqs))
- flint_throw(FLINT_ERROR, "fclose fail\n");
- qs_inf->siqs = NULL;
+ QS_SIQS_FCLOSE(qs_inf);
#if QS_DEBUG & 64
flint_printf("Removing duplicates\n");
@@ -655,11 +644,8 @@ int qsieve_process_relation(qs_t qs_inf)
{
qs_inf->edges -= 100;
done = 0;
- if (qs_inf->siqs != NULL && fclose((FILE *) qs_inf->siqs))
- flint_throw(FLINT_ERROR, "fclose fail\n");
- qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "ab");
- if (qs_inf->siqs == NULL)
- flint_throw(FLINT_ERROR, "fopen fail\n");
+ QS_SIQS_FCLOSE(qs_inf);
+ QS_SIQS_FOPEN_A(qs_inf);
} else
{
done = 1;