[libmath-prime-util-perl] 36/181: Convert segment_primes to segment start/next/end

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:51:04 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.36
in repository libmath-prime-util-perl.

commit 11685f624c416740c73368cf54785afaa5b6b52a
Author: Dana Jacobsen <dana at acm.org>
Date:   Mon Dec 23 00:23:30 2013 -0800

    Convert segment_primes to segment start/next/end
---
 XS.xs | 63 +++++++++++++--------------------------------------------------
 1 file changed, 13 insertions(+), 50 deletions(-)

diff --git a/XS.xs b/XS.xs
index 5f8697c..8d17681 100644
--- a/XS.xs
+++ b/XS.xs
@@ -262,15 +262,13 @@ sieve_primes(IN UV low, IN UV high)
 SV*
 trial_primes(IN UV low, IN UV high)
   PREINIT:
-    UV  curprime;
+    UV  p;
     AV* av = newAV();
   CODE:
     if (low <= high) {
       if (low >= 2) low--;   /* Make sure low gets included */
-      curprime = _XS_next_prime(low);
-      while (curprime <= high && curprime != 0) {
-        av_push(av,newSVuv(curprime));
-        curprime = _XS_next_prime(curprime);
+      for (p = _XS_next_prime(low); p <= high && p != 0; p = _XS_next_prime(p)) {
+        av_push(av,newSVuv(p));
       }
     }
     RETVAL = newRV_noinc( (SV*) av );
@@ -282,53 +280,20 @@ segment_primes(IN UV low, IN UV high);
   PREINIT:
     AV* av = newAV();
   CODE:
-    /* Could rewrite using {start/next/end}_segment_primes functions */
     if ((low <= 2) && (high >= 2)) { av_push(av, newSVuv( 2 )); }
     if ((low <= 3) && (high >= 3)) { av_push(av, newSVuv( 3 )); }
     if ((low <= 5) && (high >= 5)) { av_push(av, newSVuv( 5 )); }
     if (low < 7)  low = 7;
     if (low <= high) {
-      /* Call the segment siever one or more times */
-      UV low_d, high_d, segment_size;
-      unsigned char* sieve = get_prime_segment(&segment_size);
-      if (sieve == 0)
-        croak("Could not get segment cache");
-
-      /* To protect vs. overflow, work entirely with d. */
-      low_d  = low  / 30;
-      high_d = high / 30;
-
-      {  /* Avoid recalculations of this */
-        UV endp = (high_d >= (UV_MAX/30))  ?  UV_MAX-2  :  30*high_d+29;
-        prime_precalc(isqrt(endp) + 1 );
-      }
-
-      while ( low_d <= high_d ) {
-        UV seghigh_d = ((high_d - low_d) < segment_size)
-                       ? high_d
-                       : (low_d + segment_size-1);
-        UV range_d = seghigh_d - low_d + 1;
-        UV seghigh = (seghigh_d == high_d) ? high : (seghigh_d*30+29);
-        UV segbase = low_d * 30;
-        /* printf("  startd = %"UVuf"  endd = %"UVuf"\n", startd, endd); */
-
-        MPUassert( seghigh_d >= low_d, "segment_primes highd < lowd");
-        MPUassert( range_d <= segment_size, "segment_primes range > segment size");
-
-        /* Sieve from startd*30+1 to endd*30+29.  */
-        if (sieve_segment(sieve, low_d, seghigh_d) == 0) {
-          release_prime_segment(sieve);
-          croak("Could not segment sieve from %"UVuf" to %"UVuf, segbase+1, seghigh);
-        }
-
-        START_DO_FOR_EACH_SIEVE_PRIME( sieve, low - segbase, seghigh - segbase )
-          av_push(av,newSVuv( segbase + p ));
+      unsigned char* segment;
+      UV seg_base, seg_low, seg_high;
+      void* ctx = start_segment_primes(low, high, &segment);
+      while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
+        START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_low - seg_base, seg_high - seg_base )
+          av_push(av,newSVuv( seg_base + p ));
         END_DO_FOR_EACH_SIEVE_PRIME
-
-        low_d += range_d;
-        low = seghigh+2;
       }
-      release_prime_segment(sieve);
+      end_segment_primes(ctx);
     }
     RETVAL = newRV_noinc( (SV*) av );
   OUTPUT:
@@ -869,8 +834,8 @@ forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
      * exact limits will change based on the sieve vs. next_prime speed. */
     if (beg <= end && !CvISXSUB(cv) && (
 #if BITS_PER_WORD == 64
-          (beg >= UVCONST(10000000000000000000) && end-beg < 100000000) ||
-          (beg >= UVCONST( 1000000000000000000) && end-beg <  25000000) ||
+          (beg >= UVCONST(10000000000000000000) && end-beg <1000000000) ||
+          (beg >= UVCONST( 1000000000000000000) && end-beg <  95000000) ||
           (beg >= UVCONST(  100000000000000000) && end-beg <   8000000) ||
           (beg >= UVCONST(   10000000000000000) && end-beg <   1700000) ||
           (beg >= UVCONST(    1000000000000000) && end-beg <    400000) ||
@@ -882,12 +847,10 @@ forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
       dMULTICALL;
       I32 gimme = G_VOID;
       PUSH_MULTICALL(cv);
-      beg = _XS_next_prime(beg-1);
-      while (beg <= end && beg != 0) {
+      for (beg = _XS_next_prime(beg-1); beg <= end && beg != 0; beg = _XS_next_prime(beg)) {
         sv_setuv(svarg, beg);
         GvSV(PL_defgv) = svarg;
         MULTICALL;
-        beg = _XS_next_prime(beg);
       }
       FIX_MULTICALL_REFCOUNT;
       POP_MULTICALL;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git



More information about the Pkg-perl-cvs-commits mailing list