sieve 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -8,5 +8,6 @@ coverage/*
8
8
  rerun.txt
9
9
  pkg/*
10
10
  *.gem
11
+ Gemfile.lock
11
12
 
12
13
  !.keep
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010 Josh Clayton
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -81,3 +81,7 @@ The benchmarks were run on a 2.8GHz Intel Core 2 Duo MacBook Pro with 8 GB memor
81
81
  ## Author
82
82
 
83
83
  Written by Josh Clayton
84
+
85
+ ## License
86
+
87
+ See the LICENSE
data/Rakefile CHANGED
@@ -2,9 +2,6 @@ require "rubygems"
2
2
  require "rake"
3
3
  require "benchmark"
4
4
 
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
6
- require "sieve"
7
-
8
5
  require "rake/extensiontask"
9
6
  Rake::ExtensionTask.new("sieve") do |extension|
10
7
  extension.lib_dir = "lib/sieve"
@@ -13,16 +10,17 @@ end
13
10
  task :build => [:clean, :compile]
14
11
 
15
12
  require "cucumber/rake/task"
16
- Cucumber::Rake::Task.new(:cucumber => :build) do |t|
17
- t.rcov = true
18
- end
13
+ Cucumber::Rake::Task.new(:cucumber => :build)
19
14
 
20
15
  task :default => :cucumber
21
16
 
22
17
  desc "Benchmark C implementation against pure Ruby implementation of the Sieve"
23
18
  task(:benchmark => :build) do
19
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
20
+ require "sieve"
21
+
24
22
  def sieve(n)
25
- numbers = (0..n).map {|i| i }
23
+ numbers = (0..n).to_a
26
24
  numbers[0] = numbers[1] = nil
27
25
  numbers.each do |num|
28
26
  next unless num
@@ -1,2 +1,3 @@
1
1
  require "mkmf"
2
+ $CFLAGS = "--std=c99 -O"
2
3
  create_makefile("sieve/sieve")
@@ -10,41 +10,73 @@ void Init_sieve() {
10
10
  }
11
11
 
12
12
  static VALUE sieve(const VALUE self) {
13
- if(NUM2LONG(self) < 2) { return Qnil; }
14
- long number = NUM2LONG(self) + 1;
13
+ if(NUM2LONG(self) < 2) { return rb_ary_new(); }
15
14
 
16
- char* results = malloc((long)(number/8));
15
+ sieve_data* data = initialize_sieve_data(self);
17
16
 
18
- if(results == NULL) {
19
- rb_raise(rb_eNoMemError, "Can't allocate enough memory.");
20
- }
17
+ default_sieve_data(data);
18
+ remove_non_primes(data);
19
+ VALUE primes_array = primes_array_from_sieve_data(data);
21
20
 
22
- CLEARBIT(results, 0);
23
- CLEARBIT(results, 1);
24
- long i;
25
- for(i = 2; i < number; i++) { SETBIT(results, i); }
21
+ destroy_sieve_data(data);
22
+
23
+ return primes_array;
24
+ }
25
+
26
+ static sieve_data* initialize_sieve_data(const VALUE self) {
27
+ sieve_data* data = (sieve_data*)malloc(sizeof(sieve_data));
26
28
 
27
- long current_square;
28
- for(i = 0; i < number; i++) {
29
- if(BITNOTSET(results, i)) { continue; }
29
+ data->number = NUM2LONG(self) + 1;
30
+ data->results = malloc((long)(data->number/8));
31
+
32
+ ensure_memory_allocated(data->results);
33
+
34
+ return data;
35
+ }
36
+
37
+ static void remove_non_primes(sieve_data* data) {
38
+ long current_square, i, n;
39
+
40
+ for(i = 0; i < data->number; i++) {
41
+ if(BITNOTSET(data->results, i)) { continue; }
30
42
 
31
43
  current_square = powl(i, 2);
32
- if(current_square > number) { break; }
44
+ if(current_square > data->number) { break; }
33
45
 
34
- long n;
35
- for(n = current_square; n < number; n += i) {
36
- CLEARBIT(results, n);
37
- }
46
+ for(n = current_square; n < data->number; n += i) { CLEARBIT(data->results, n); }
38
47
  }
39
48
 
49
+ return;
50
+ }
51
+
52
+ static void default_sieve_data(sieve_data* data) {
53
+ CLEARBIT(data->results, 0);
54
+ CLEARBIT(data->results, 1);
55
+
56
+ long i;
57
+ for(i = 2; i < data->number; i++) { SETBIT(data->results, i); }
58
+ return;
59
+ }
60
+
61
+ static VALUE primes_array_from_sieve_data(sieve_data* data) {
40
62
  VALUE primes_array = rb_ary_new();
41
- for(i = 0; i < number; i++) {
42
- if(BITSET(results, i)) {
43
- rb_ary_push(primes_array, LONG2FIX(i));
44
- }
45
- }
46
63
 
47
- free(results);
64
+ long i;
65
+ for(i = 0; i < data->number; i++) {
66
+ if(BITSET(data->results, i)) { rb_ary_push(primes_array, LONG2FIX(i)); }
67
+ }
48
68
 
49
69
  return primes_array;
50
70
  }
71
+
72
+ static void ensure_memory_allocated(void* data) {
73
+ if(NULL == data) {
74
+ rb_raise(rb_eNoMemError, "Can't allocate enough memory.");
75
+ }
76
+ }
77
+
78
+ static void destroy_sieve_data(sieve_data* data) {
79
+ free(data->results);
80
+ free(data);
81
+ return;
82
+ }
@@ -6,5 +6,19 @@
6
6
  #define SETBIT(x,i) ((x)[(i)>>3] |= (1<<((i)&7)))
7
7
  #define CLEARBIT(x,i) ((x)[(i)>>3] &= (1<<((i)&7))^0xFF)
8
8
 
9
+ typedef struct {
10
+ char* results;
11
+ long number;
12
+ } sieve_data;
13
+
9
14
  static VALUE sieve(VALUE);
15
+
16
+ static sieve_data* initialize_sieve_data(const VALUE);
17
+ static void destroy_sieve_data(sieve_data*);
18
+ static void default_sieve_data(sieve_data*);
19
+ static void initialize_results(sieve_data*);
20
+ static void remove_non_primes(sieve_data*);
21
+ static VALUE primes_array_from_sieve_data(sieve_data*);
22
+ static void ensure_memory_allocated(void*);
23
+
10
24
  #endif
@@ -8,11 +8,11 @@ Feature: Sieve of Eratosthenes
8
8
  Then I should have the primes <primes>
9
9
  Examples:
10
10
  | number | primes |
11
- | -12345 | nil |
12
- | -5 | nil |
13
- | -1 | nil |
14
- | 0 | nil |
15
- | 1 | nil |
11
+ | -12345 | |
12
+ | -5 | |
13
+ | -1 | |
14
+ | 0 | |
15
+ | 1 | |
16
16
  | 2 | 2 |
17
17
  | 3 | 2,3 |
18
18
  | 4 | 2,3 |
@@ -7,8 +7,8 @@ end
7
7
 
8
8
  Then /^I should have the primes (.*)$/ do |primes|
9
9
  case primes
10
- when "nil"
11
- @result.should be_nil
10
+ when ""
11
+ @result.should == []
12
12
  else
13
13
  @primes = primes.split(",").map {|prime| prime.to_i }
14
14
  @result.should == @primes
@@ -1,3 +1,2 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
1
+ Bundler.require
2
2
  require "sieve"
3
- require "spec/expectations"
@@ -1,5 +1,5 @@
1
- require "sieve/sieve"
2
-
3
1
  module Sieve
4
- VERSION = "0.1.2"
2
+ autoload :Version, "sieve/version"
5
3
  end
4
+
5
+ require "sieve/sieve"
@@ -0,0 +1,3 @@
1
+ module Sieve
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path("../lib/", __FILE__)
3
+ $:.unshift(lib) unless $:.include?(lib)
4
+
5
+ require "sieve/version"
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = %q{sieve}
9
+ s.summary = %q{Sieve of Eratosthenes}
10
+ s.description = %q{Ruby C Extension for the Sieve of Eratosthenes}
11
+ s.homepage = %q{http://github.com/joshuaclayton/sieve}
12
+ s.version = Sieve::VERSION
13
+ s.authors = ["Josh Clayton"]
14
+ s.email = %q{joshua.clayton@gmail.com}
15
+
16
+ s.rubygems_version = %q{1.3.7}
17
+ s.date = %q{2010-09-12}
18
+
19
+ s.require_paths = ["lib"]
20
+ s.extensions = ["ext/sieve/extconf.rb"]
21
+ s.files = %x{git ls-files}.split("\n").reject {|file| file =~ /^(features|cucumber)/ }
22
+ s.test_files = %x{git ls-files}.split("\n").select {|file| file =~ /^(features|cucumber)/ }
23
+
24
+ s.add_dependency "rake-compiler", "0.7.9"
25
+ s.add_development_dependency "rspec", "2.7.0"
26
+ s.add_development_dependency "cucumber", "1.1.0"
27
+ end
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sieve
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 2
9
- version: 0.1.2
4
+ prerelease:
5
+ version: 1.0.0
10
6
  platform: ruby
11
7
  authors:
12
8
  - Josh Clayton
@@ -16,8 +12,40 @@ cert_chain: []
16
12
 
17
13
  date: 2010-09-12 00:00:00 -04:00
18
14
  default_executable:
19
- dependencies: []
20
-
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rake-compiler
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - "="
23
+ - !ruby/object:Gem::Version
24
+ version: 0.7.9
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - "="
34
+ - !ruby/object:Gem::Version
35
+ version: 2.7.0
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: cucumber
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - "="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.1.0
47
+ type: :development
48
+ version_requirements: *id003
21
49
  description: Ruby C Extension for the Sieve of Eratosthenes
22
50
  email: joshua.clayton@gmail.com
23
51
  executables: []
@@ -28,6 +56,8 @@ extra_rdoc_files: []
28
56
 
29
57
  files:
30
58
  - .gitignore
59
+ - Gemfile
60
+ - LICENSE
31
61
  - MIT-LICENSE
32
62
  - README.markdown
33
63
  - Rakefile
@@ -35,6 +65,8 @@ files:
35
65
  - ext/sieve/sieve.c
36
66
  - ext/sieve/sieve.h
37
67
  - lib/sieve.rb
68
+ - lib/sieve/version.rb
69
+ - sieve.gemspec
38
70
  - cucumber.yml
39
71
  - features/sieve.feature
40
72
  - features/step_definitions/sieve_steps.rb
@@ -54,21 +86,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
86
  requirements:
55
87
  - - ">="
56
88
  - !ruby/object:Gem::Version
57
- segments:
58
- - 0
59
89
  version: "0"
60
90
  required_rubygems_version: !ruby/object:Gem::Requirement
61
91
  none: false
62
92
  requirements:
63
93
  - - ">="
64
94
  - !ruby/object:Gem::Version
65
- segments:
66
- - 0
67
95
  version: "0"
68
96
  requirements: []
69
97
 
70
98
  rubyforge_project:
71
- rubygems_version: 1.3.7
99
+ rubygems_version: 1.6.2
72
100
  signing_key:
73
101
  specification_version: 3
74
102
  summary: Sieve of Eratosthenes