[libmath-prime-util-perl] 04/11: Fix memory leak in forprimes. Document it.

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


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

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

commit c803cae002eebaf51d8720d25963d6a6960f6267
Author: Dana Jacobsen <dana at acm.org>
Date:   Tue May 21 00:19:05 2013 -0700

    Fix memory leak in forprimes.  Document it.
---
 TODO                   |  6 +++++-
 XS.xs                  |  9 +++++++--
 lib/Math/Prime/Util.pm | 16 ++++++++++++++++
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/TODO b/TODO
index 4b10d09..f716733 100644
--- a/TODO
+++ b/TODO
@@ -42,6 +42,10 @@
    - QS factoring
 
 - forprimes { say } 1000,2000
-  - Documentation
   - Tests
   - Examples
+
+- Make forprimes use a segment sieve
+
+- Figure out a way to make the internal FOR_EACH_PRIME macros use a segmented
+  sieve.
diff --git a/XS.xs b/XS.xs
index b708e36..491b6f3 100644
--- a/XS.xs
+++ b/XS.xs
@@ -648,6 +648,7 @@ forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
     GV *gv;
     HV *stash;
     CV *cv;
+    SV* svarg;
 
     if (!_validate_int(svbeg, 0) || (items >= 3 && !_validate_int(svend,0))) {
       dSP;
@@ -672,12 +673,14 @@ forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
     if (cv == Nullcv)
       croak("Not a subroutine reference");
     SAVESPTR(GvSV(PL_defgv));
+    svarg = newSVuv(0);
     if (!CvISXSUB(cv)) {
       dMULTICALL;
       I32 gimme = G_VOID;
       PUSH_MULTICALL(cv);
       START_DO_FOR_EACH_PRIME(beg, end) {
-        GvSV(PL_defgv) = newSVuv(p);
+        sv_setuv(svarg, p);
+        GvSV(PL_defgv) = svarg;
         MULTICALL;
       } END_DO_FOR_EACH_PRIME
 #ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
@@ -688,11 +691,13 @@ forprimes (SV* block, IN SV* svbeg, IN SV* svend = 0)
     } else {
       START_DO_FOR_EACH_PRIME(beg, end) {
         dSP;
-        GvSV(PL_defgv) = newSVuv(p);
+        sv_setuv(svarg, p);
+        GvSV(PL_defgv) = svarg;
         PUSHMARK(SP);
         call_sv((SV*)cv, G_VOID|G_DISCARD);
       } END_DO_FOR_EACH_PRIME
     }
+    SvREFCNT_dec(svarg);
 #endif
     XSRETURN_UNDEF;
   }
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 6cb62fd..0dac169 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -2385,6 +2385,8 @@ Version 0.27
   # If you want them in an array instead
   my @primes = @{primes( 500 )};
 
+  # You can do something for every prime in a range.  Twin primes to 10k:
+  forprimes { say if is_prime($_+2) } 10000;
 
   # For non-bigints, is_prime and is_prob_prime will always be 0 or 2.
   # They return return 0 (composite), 2 (prime), or 1 (probably prime)
@@ -2663,6 +2665,20 @@ Returns the prime smaller than the input number.  0 is returned if the
 input is C<2> or lower.
 
 
+=head2 forprimes
+
+  forprimes { say } 100,200;                  # print primes from 100-200
+
+  $sum=0;  forprimes { $sum += $_ } 100000;   # sum primes to 100k
+
+  forprimes { say if is_prime($_+2) } 10000;  # print twin primes to 10k
+
+Given a block and either an end count or a start and end pair, calls the
+block for each prime in the range.  Compared to getting a big array of primes
+and iterating through it, this is more memory efficient and perhaps more
+convenient.
+
+
 =head2 prime_count
 
   my $primepi = prime_count( 1_000 );

-- 
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