figure_set 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +14 -0
- data/README.rdoc +61 -0
- data/Rakefile +28 -0
- data/ext/and.c +118 -0
- data/ext/array.c +98 -0
- data/ext/extconf.rb +2 -0
- data/ext/figure_set.h +145 -0
- data/ext/index.c +118 -0
- data/ext/init.c +167 -0
- data/ext/methods.c +245 -0
- data/ext/or.c +105 -0
- data/ext/sample.c +89 -0
- data/lib/figure_set.rb +11 -0
- metadata +116 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
= FigureSet
|
2
|
+
|
3
|
+
= Description
|
4
|
+
FigureSet is the library which treats set operation.
|
5
|
+
FigureSet is able to treat the set of 32bit integer.(0 .. 2 ** 32 -1)
|
6
|
+
|
7
|
+
= How to
|
8
|
+
|
9
|
+
== Initialize
|
10
|
+
=== an empty set.
|
11
|
+
empty_set = FigureSet.new
|
12
|
+
|
13
|
+
=== give array.
|
14
|
+
set = FigureSet.new([0,3,6,7])
|
15
|
+
|
16
|
+
== Element operation
|
17
|
+
=== add to set.
|
18
|
+
set = FigureSet.new
|
19
|
+
set.add 10
|
20
|
+
set << 100
|
21
|
+
set.to_a #=> [10, 100]
|
22
|
+
|
23
|
+
=== remove from set.
|
24
|
+
set = FigureSet.new([1,4,5])
|
25
|
+
set.delete(4)
|
26
|
+
set.to_a #=> [1, 5]
|
27
|
+
|
28
|
+
== Set operation
|
29
|
+
=== and
|
30
|
+
set1 = FigureSet.new([1,2,3,5])
|
31
|
+
set2 = FigureSet.new([2,4,6])
|
32
|
+
set_and = set1 & set2
|
33
|
+
set_and.to_a #=> [2]
|
34
|
+
|
35
|
+
=== or
|
36
|
+
set1 = FigureSet.new([1,2,3,5])
|
37
|
+
set2 = FigureSet.new([2,4,6])
|
38
|
+
set_or = set1 | set2
|
39
|
+
set_or.to_a #=> [1,2,3,4,5,6]
|
40
|
+
|
41
|
+
== Other
|
42
|
+
=== size
|
43
|
+
set = FigureSet.new([1,2,3])
|
44
|
+
set.size #=> 3
|
45
|
+
|
46
|
+
=== empty?
|
47
|
+
set = FigureSet.new
|
48
|
+
set.empty? #=> true
|
49
|
+
|
50
|
+
=== clear
|
51
|
+
set = FigureSet.new([1,2,3])
|
52
|
+
set.clear
|
53
|
+
set.to_a #=> []
|
54
|
+
|
55
|
+
= INSTALL:
|
56
|
+
|
57
|
+
sudo gem install figure_set
|
58
|
+
|
59
|
+
= LICENSE:
|
60
|
+
|
61
|
+
FigureSet is released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
|
+
require File.dirname(__FILE__) + '/lib/figure_set'
|
3
|
+
|
4
|
+
# Generate all the Rake tasks
|
5
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
+
$hoe = Hoe.new('figure_set', FigureSet.version) do |p|
|
7
|
+
p.developer('Tsukasa OISHI', 'tsukasa.oishi@gmail.com')
|
8
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
|
+
p.rubyforge_name = p.name # TODO this is default value
|
10
|
+
p.extra_dev_deps = [
|
11
|
+
['newgem', ">= #{::Newgem::VERSION}"]
|
12
|
+
]
|
13
|
+
|
14
|
+
pec_extras = {
|
15
|
+
:extensions => ['ext/extconf.rb'],
|
16
|
+
}
|
17
|
+
|
18
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
19
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
20
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
21
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
25
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
26
|
+
|
27
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
28
|
+
# task :default => [:spec, :features]
|
data/ext/and.c
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
//************************************
|
2
|
+
// and.c
|
3
|
+
//************************************
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <ruby.h>
|
9
|
+
#include "figure_set.h"
|
10
|
+
|
11
|
+
//
|
12
|
+
// intersection
|
13
|
+
//
|
14
|
+
void intersection(root_node result_set, root_node set0, root_node set1)
|
15
|
+
{
|
16
|
+
unsigned int i, count;
|
17
|
+
root_node base, other;
|
18
|
+
branch_node branch;
|
19
|
+
|
20
|
+
if (set0->size == 0 || set1->size == 0) {
|
21
|
+
return;
|
22
|
+
} else if (set0->size > set1->size) {
|
23
|
+
base = set1;
|
24
|
+
other = set0;
|
25
|
+
} else {
|
26
|
+
base = set0;
|
27
|
+
other = set1;
|
28
|
+
}
|
29
|
+
|
30
|
+
for (i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE || count < base->children_size; i++) {
|
31
|
+
if (base->index[i]) {
|
32
|
+
count++;
|
33
|
+
if (other->index[i]) {
|
34
|
+
branch = (branch_node)init_and_intersection_branch_node(result_set, (branch_node)base->index[i], (branch_node)other->index[i]);
|
35
|
+
if (branch) {
|
36
|
+
result_set->index[i] = (void*)branch;
|
37
|
+
result_set->children_size++;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
void *init_and_intersection_branch_node(root_node result_set, branch_node base, branch_node other)
|
45
|
+
{
|
46
|
+
branch_node branch;
|
47
|
+
|
48
|
+
branch = (branch_node)init_branch_node();
|
49
|
+
|
50
|
+
if (base->children_type == CT_LEAF) {
|
51
|
+
last_intersection_branch_node(result_set, branch, base, other);
|
52
|
+
} else {
|
53
|
+
middel_intersection_branch_node(result_set, branch, base, other);
|
54
|
+
}
|
55
|
+
|
56
|
+
if (branch->children_size) {
|
57
|
+
branch->children_type = base->children_type;
|
58
|
+
return (void*)branch;
|
59
|
+
} else {
|
60
|
+
destroy_branch(branch);
|
61
|
+
return (void*)NULL;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
void middel_intersection_branch_node(root_node result_set, branch_node branch, branch_node base, branch_node other)
|
66
|
+
{
|
67
|
+
unsigned int i, count;
|
68
|
+
branch_node middle_branch;
|
69
|
+
|
70
|
+
for (i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < base->children_size; i++) {
|
71
|
+
if (base->index[i]) {
|
72
|
+
count++;
|
73
|
+
if (other->index[i]) {
|
74
|
+
middle_branch = (branch_node)init_and_intersection_branch_node(result_set, (branch_node)base->index[i], (branch_node)other->index[i]);
|
75
|
+
if (middle_branch) {
|
76
|
+
branch->index[i] = (void*)middle_branch;
|
77
|
+
branch->children_size++;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
void last_intersection_branch_node(root_node result_set, branch_node branch, branch_node base, branch_node other)
|
85
|
+
{
|
86
|
+
unsigned int i, count;
|
87
|
+
leaf_node leaf;
|
88
|
+
|
89
|
+
for (i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < base->children_size; i++) {
|
90
|
+
if (base->index[i]) {
|
91
|
+
count++;
|
92
|
+
if (other->index[i]) {
|
93
|
+
leaf = (leaf_node)init_and_intersection_leaf_node(result_set, (leaf_node)base->index[i], (leaf_node)other->index[i]);
|
94
|
+
if (leaf) {
|
95
|
+
branch->index[i] = (void*)leaf;
|
96
|
+
branch->children_size++;
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
|
104
|
+
void *init_and_intersection_leaf_node(root_node result_set, leaf_node base, leaf_node other)
|
105
|
+
{
|
106
|
+
unsigned long data;
|
107
|
+
leaf_node leaf;
|
108
|
+
|
109
|
+
data = base->data & other->data;
|
110
|
+
|
111
|
+
if (!data) return (void*)NULL;
|
112
|
+
|
113
|
+
leaf = (leaf_node)init_leaf_node(base->offset);
|
114
|
+
leaf->data = data;
|
115
|
+
result_set->size += BIT_COUNT(leaf->data);
|
116
|
+
|
117
|
+
return (void*)leaf;
|
118
|
+
}
|
data/ext/array.c
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
//************************************
|
2
|
+
// array.c
|
3
|
+
//************************************
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <ruby.h>
|
9
|
+
#include "figure_set.h"
|
10
|
+
|
11
|
+
//
|
12
|
+
// output Array object from internal set
|
13
|
+
//
|
14
|
+
void to_array(root_node root, VALUE array)
|
15
|
+
{
|
16
|
+
unsigned int i, count;
|
17
|
+
|
18
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE || count < root->children_size; i++) {
|
19
|
+
if (root->index[i]) {
|
20
|
+
search_and_get_array((branch_node)root->index[i], array);
|
21
|
+
count++;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
void search_and_get_array(branch_node branch, VALUE array)
|
27
|
+
{
|
28
|
+
unsigned int i, count;
|
29
|
+
|
30
|
+
if (branch->children_type == CT_LEAF) {
|
31
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < branch->children_size; i++) {
|
32
|
+
if (branch->index[i]) {
|
33
|
+
search_and_get_array_at_leaf((leaf_node)branch->index[i], array);
|
34
|
+
count++;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
} else {
|
38
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < branch->children_size; i++) {
|
39
|
+
if (branch->index[i]) {
|
40
|
+
search_and_get_array((branch_node)branch->index[i], array);
|
41
|
+
count++;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
void search_and_get_array_at_leaf(leaf_node leaf, VALUE array)
|
48
|
+
{
|
49
|
+
unsigned long i = 0;
|
50
|
+
unsigned long x;
|
51
|
+
|
52
|
+
x = leaf->data;
|
53
|
+
|
54
|
+
while(x) {
|
55
|
+
i = BIT_COUNT((x & (-x))-1);
|
56
|
+
rb_ary_push(array, ULONG2NUM(leaf->offset + i));
|
57
|
+
x = x ^ (1UL << i);
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
/*
|
62
|
+
while(x) {
|
63
|
+
if (x & 1UL) {
|
64
|
+
rb_ary_push(array, ULONG2NUM(leaf->offset + i));
|
65
|
+
}
|
66
|
+
x = x >> 1UL;
|
67
|
+
i++;
|
68
|
+
}
|
69
|
+
*/
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
//
|
74
|
+
// bit count
|
75
|
+
//
|
76
|
+
|
77
|
+
// 32 bit
|
78
|
+
unsigned long bit32_count(unsigned long x)
|
79
|
+
{
|
80
|
+
x = x - ((x >> 1UL) & 0x55555555UL);
|
81
|
+
x = (x & 0x33333333UL) + ((x >> 2UL) & 0x33333333UL);
|
82
|
+
x = (x + (x >> 4UL)) & 0x0f0f0f0fUL;
|
83
|
+
x = x + (x >> 8UL);
|
84
|
+
x = x + (x >> 16UL);
|
85
|
+
return x & 0x0000003FUL;
|
86
|
+
}
|
87
|
+
|
88
|
+
// 64 bit
|
89
|
+
unsigned long bit64_count(unsigned long x)
|
90
|
+
{
|
91
|
+
x = x - ((x >> 1UL) & 0x5555555555555555UL);
|
92
|
+
x = (x & 0x3333333333333333UL) + ((x >> 2UL) & 0x3333333333333333UL);
|
93
|
+
x = (x & 0x0f0f0f0f0f0f0f0fUL) + ((x >> 4UL) & 0x0f0f0f0f0f0f0f0fUL);
|
94
|
+
x = (x + (x >> 8UL)) & 0x00ff00ff00ff00ffUL;
|
95
|
+
x = x + (x >> 16UL);
|
96
|
+
x = x + (x >> 32UL);
|
97
|
+
return x & 0x000000000000007FUL;
|
98
|
+
}
|
data/ext/extconf.rb
ADDED
data/ext/figure_set.h
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
//************************************
|
2
|
+
// figure_set.h
|
3
|
+
//
|
4
|
+
// Tsukasa OISHI
|
5
|
+
// http://www.kaeruspoon.net
|
6
|
+
//************************************
|
7
|
+
|
8
|
+
#include <math.h>
|
9
|
+
|
10
|
+
#ifndef RUBY_19
|
11
|
+
#ifndef RFLOAT_VALUE
|
12
|
+
#define RFLOAT_VALUE(v) (RFLOAT(v)->value)
|
13
|
+
#endif
|
14
|
+
#ifndef RARRAY_LEN
|
15
|
+
#define RARRAY_LEN(v) (RARRAY(v)->len)
|
16
|
+
#endif
|
17
|
+
#ifndef RARRAY_PTR
|
18
|
+
#define RARRAY_PTR(v) (RARRAY(v)->ptr)
|
19
|
+
#endif
|
20
|
+
#endif
|
21
|
+
|
22
|
+
// max children size of branch
|
23
|
+
#define MAX_CHILDREN_SIZE_OF_BRANCH (unsigned long)16
|
24
|
+
#define LAST_BRANCH_LEVEL (unsigned long)6
|
25
|
+
|
26
|
+
#if ULLONG_MAX == 0xffffffffffffffff
|
27
|
+
#define ULONG_BIT_COUNT (unsigned long)64
|
28
|
+
#define MAX_CHILDREN_SIZE_OF_ROOT_NODE (unsigned long)4
|
29
|
+
#define BIT_COUNT(x) bit64_count(x)
|
30
|
+
static unsigned long OFFSET_SCALE[] = {0x40000000, 0x4000000, 0x400000, 0x40000, 0x4000, 0x400, 0x40};
|
31
|
+
#else
|
32
|
+
#define ULONG_BIT_COUNT (unsigned long)32
|
33
|
+
#define MAX_CHILDREN_SIZE_OF_ROOT_NODE (unsigned long)8
|
34
|
+
#define BIT_COUNT(x) bit32_count(x)
|
35
|
+
static unsigned long OFFSET_SCALE[] = {0x20000000, 0x2000000, 0x200000, 0x20000, 0x2000, 0x200, 0x20};
|
36
|
+
#endif
|
37
|
+
|
38
|
+
// branch node children type
|
39
|
+
#define CT_BRANCH 0
|
40
|
+
#define CT_LEAF 1
|
41
|
+
|
42
|
+
// valid valie range
|
43
|
+
#define VALID_MIN_VALUE UINT2NUM(0)
|
44
|
+
#define VALID_MAX_VALUE UINT2NUM(0xffffffff)
|
45
|
+
|
46
|
+
// FigureSet class object
|
47
|
+
static VALUE rb_cFigureSet;
|
48
|
+
|
49
|
+
// leaf node
|
50
|
+
// example:
|
51
|
+
// data = 5 # (bit is 0...0101) exist bit numbers is (2, 0)
|
52
|
+
// offset = 640
|
53
|
+
//
|
54
|
+
// set is
|
55
|
+
// [offset + 2, offset + 0]
|
56
|
+
// = [642, 640]
|
57
|
+
//
|
58
|
+
typedef struct _leaf_node {
|
59
|
+
unsigned long offset; // offset number
|
60
|
+
unsigned long data; // each bit is exist flag(1:exist 0:none) of member
|
61
|
+
} *leaf_node;
|
62
|
+
|
63
|
+
// branch node
|
64
|
+
typedef struct _branch_node {
|
65
|
+
unsigned char children_type; // children type
|
66
|
+
unsigned char children_size;
|
67
|
+
void *index[MAX_CHILDREN_SIZE_OF_BRANCH]; // children pointer
|
68
|
+
} *branch_node;
|
69
|
+
|
70
|
+
typedef struct _root_node {
|
71
|
+
unsigned char children_size;
|
72
|
+
unsigned long size; // number of elements in set
|
73
|
+
void *index[MAX_CHILDREN_SIZE_OF_ROOT_NODE]; // children pointer
|
74
|
+
} *root_node;
|
75
|
+
|
76
|
+
// initialize
|
77
|
+
void init_root_node(root_node);
|
78
|
+
void *init_branch_node();
|
79
|
+
void *init_leaf_node(unsigned long);
|
80
|
+
|
81
|
+
// init_copy
|
82
|
+
void copy_root_node(root_node, root_node);
|
83
|
+
void copy_branch_node(root_node, branch_node, branch_node);
|
84
|
+
void *init_and_copy_brance_node(root_node, branch_node);
|
85
|
+
void *init_and_copy_leaf_node(root_node, leaf_node);
|
86
|
+
|
87
|
+
// insert element into set
|
88
|
+
void add_num(root_node, unsigned long);
|
89
|
+
unsigned int search_and_insert(branch_node, unsigned long, unsigned long, unsigned long);
|
90
|
+
unsigned int search_and_insert_at_leaf(leaf_node, unsigned long);
|
91
|
+
|
92
|
+
// remove element from set
|
93
|
+
void delete_num(root_node, unsigned long);
|
94
|
+
unsigned int search_and_remove(branch_node, unsigned long, unsigned long, unsigned long);
|
95
|
+
unsigned int search_and_remove_at_leaf(leaf_node, unsigned long);
|
96
|
+
|
97
|
+
// output Array object from internal set
|
98
|
+
void to_array(root_node, VALUE);
|
99
|
+
void search_and_get_array(branch_node, VALUE);
|
100
|
+
void search_and_get_array_at_leaf(leaf_node, VALUE);
|
101
|
+
|
102
|
+
// join
|
103
|
+
void join(root_node, root_node, root_node);
|
104
|
+
void middle_join_branch_node(root_node, branch_node, branch_node, branch_node);
|
105
|
+
void last_join_branch_node(root_node, branch_node, branch_node, branch_node);
|
106
|
+
void *init_and_join_brance_node(root_node, branch_node, branch_node);
|
107
|
+
void *init_and_join_leaf_node(root_node, leaf_node, leaf_node);
|
108
|
+
|
109
|
+
// intersection
|
110
|
+
void intersection(root_node, root_node, root_node);
|
111
|
+
void middel_intersection_branch_node(root_node, branch_node, branch_node, branch_node);
|
112
|
+
void last_intersection_branch_node(root_node, branch_node, branch_node, branch_node);
|
113
|
+
void *init_and_intersection_leaf_node(root_node, leaf_node, leaf_node);
|
114
|
+
void *init_and_intersection_branch_node(root_node, branch_node, branch_node);
|
115
|
+
unsigned long bit32_count(unsigned long);
|
116
|
+
unsigned long bit64_count(unsigned long);
|
117
|
+
|
118
|
+
// sample
|
119
|
+
void sample(root_node, VALUE, unsigned long);
|
120
|
+
void search_and_sample_array(branch_node, VALUE);
|
121
|
+
void search_and_sample_array_at_leaf(leaf_node, VALUE);
|
122
|
+
|
123
|
+
// memory free
|
124
|
+
void destroy_all(root_node);
|
125
|
+
void destroy_all_branches(root_node);
|
126
|
+
void destroy_branch(branch_node);
|
127
|
+
|
128
|
+
//-----------------------------------------------------------
|
129
|
+
// Ruby Methods
|
130
|
+
// ----------------------------------------------------------
|
131
|
+
|
132
|
+
static VALUE t_allocate(VALUE);
|
133
|
+
static VALUE t_initialize(int, VALUE *, VALUE);
|
134
|
+
static VALUE t_initialize_copy(VALUE, VALUE);
|
135
|
+
static VALUE t_add(VALUE, VALUE);
|
136
|
+
static VALUE t_delete(VALUE, VALUE);
|
137
|
+
static VALUE t_intersection(VALUE, VALUE);
|
138
|
+
static VALUE t_union(VALUE, VALUE);
|
139
|
+
static VALUE t_to_a(VALUE);
|
140
|
+
static VALUE t_sample(int, VALUE *, VALUE);
|
141
|
+
static VALUE t_size(VALUE);
|
142
|
+
static VALUE t_empty(VALUE);
|
143
|
+
static VALUE t_clear(VALUE);
|
144
|
+
void Init_figure_set(void);
|
145
|
+
|
data/ext/index.c
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
//************************************
|
2
|
+
// index.c
|
3
|
+
//************************************
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <ruby.h>
|
9
|
+
#include "figure_set.h"
|
10
|
+
|
11
|
+
//
|
12
|
+
// insert element into set
|
13
|
+
//
|
14
|
+
void add_num(root_node root, unsigned long value)
|
15
|
+
{
|
16
|
+
unsigned long quotient, remainder;
|
17
|
+
|
18
|
+
quotient = value / OFFSET_SCALE[0];
|
19
|
+
remainder = value % OFFSET_SCALE[0];
|
20
|
+
|
21
|
+
if(!(root->index[quotient])) {
|
22
|
+
root->index[quotient] = init_branch_node();
|
23
|
+
root->children_size++;
|
24
|
+
}
|
25
|
+
|
26
|
+
if (search_and_insert((branch_node)root->index[quotient], 1, remainder, value)) {
|
27
|
+
root->size++;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
unsigned int search_and_insert(branch_node branch, unsigned long level, unsigned long value, unsigned long original)
|
32
|
+
{
|
33
|
+
unsigned long quotient, remainder;
|
34
|
+
|
35
|
+
quotient = value / OFFSET_SCALE[level];
|
36
|
+
remainder = value % OFFSET_SCALE[level];
|
37
|
+
|
38
|
+
if(!(branch->index[quotient])) {
|
39
|
+
if(branch->children_type == CT_LEAF) {
|
40
|
+
branch->index[quotient] = init_leaf_node((unsigned long)(original / ULONG_BIT_COUNT) * ULONG_BIT_COUNT);
|
41
|
+
} else {
|
42
|
+
branch->index[quotient] = init_branch_node();
|
43
|
+
if ((level + 1) == LAST_BRANCH_LEVEL) {
|
44
|
+
((branch_node)(branch->index[quotient]))->children_type = CT_LEAF;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
branch->children_size++;
|
48
|
+
}
|
49
|
+
|
50
|
+
if (branch->children_type == CT_LEAF) {
|
51
|
+
return search_and_insert_at_leaf((leaf_node)branch->index[quotient], remainder);
|
52
|
+
} else {
|
53
|
+
return search_and_insert((branch_node)branch->index[quotient], level + 1, remainder, original);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
unsigned int search_and_insert_at_leaf(leaf_node leaf, unsigned long value)
|
58
|
+
{
|
59
|
+
unsigned int exist_flag = 0;
|
60
|
+
unsigned long target_bit;
|
61
|
+
|
62
|
+
target_bit = 1UL << value;
|
63
|
+
|
64
|
+
if (!(leaf->data & target_bit)) {
|
65
|
+
leaf->data |= target_bit;
|
66
|
+
exist_flag = 1;
|
67
|
+
}
|
68
|
+
|
69
|
+
return exist_flag;
|
70
|
+
}
|
71
|
+
|
72
|
+
//
|
73
|
+
// remove element from set
|
74
|
+
//
|
75
|
+
void delete_num(root_node root, unsigned long value)
|
76
|
+
{
|
77
|
+
unsigned long quotient, remainder;
|
78
|
+
|
79
|
+
quotient = value / OFFSET_SCALE[0];
|
80
|
+
remainder = value % OFFSET_SCALE[0];
|
81
|
+
|
82
|
+
if (!(root->index[quotient])) return;
|
83
|
+
|
84
|
+
if (search_and_remove((branch_node)root->index[quotient], 1, remainder, value)) {
|
85
|
+
root->size--;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
unsigned int search_and_remove(branch_node branch, unsigned long level, unsigned long value, unsigned long original)
|
90
|
+
{
|
91
|
+
unsigned long quotient, remainder;
|
92
|
+
|
93
|
+
quotient = value / OFFSET_SCALE[level];
|
94
|
+
remainder = value % OFFSET_SCALE[level];
|
95
|
+
|
96
|
+
if (!(branch->index[quotient])) return 0;
|
97
|
+
|
98
|
+
if (branch->children_type == CT_LEAF) {
|
99
|
+
return search_and_remove_at_leaf((leaf_node)branch->index[quotient], remainder);
|
100
|
+
} else {
|
101
|
+
return search_and_remove((branch_node)branch->index[quotient], level + 1, remainder, original);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
unsigned int search_and_remove_at_leaf(leaf_node leaf, unsigned long value)
|
106
|
+
{
|
107
|
+
unsigned int exist_flag = 0;
|
108
|
+
unsigned long target_bit;
|
109
|
+
|
110
|
+
target_bit = 1UL << value;
|
111
|
+
|
112
|
+
if ((leaf->data & target_bit)) {
|
113
|
+
leaf->data ^= target_bit;
|
114
|
+
exist_flag = 1;
|
115
|
+
}
|
116
|
+
|
117
|
+
return exist_flag;
|
118
|
+
}
|
data/ext/init.c
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
//************************************
|
2
|
+
// init.c
|
3
|
+
//************************************
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <ruby.h>
|
9
|
+
#include "figure_set.h"
|
10
|
+
|
11
|
+
//
|
12
|
+
// initialize
|
13
|
+
//
|
14
|
+
void init_root_node(root_node root)
|
15
|
+
{
|
16
|
+
unsigned int i;
|
17
|
+
|
18
|
+
for(i = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE; i++) {
|
19
|
+
root->index[i] = (void*)NULL;
|
20
|
+
}
|
21
|
+
root->size = 0;
|
22
|
+
root->children_size = 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
void *init_branch_node()
|
26
|
+
{
|
27
|
+
unsigned int i;
|
28
|
+
branch_node branch;
|
29
|
+
|
30
|
+
if (!(branch = (branch_node)malloc(sizeof(struct _branch_node)))) {
|
31
|
+
rb_raise(rb_eStandardError, "memory is not enough");
|
32
|
+
}
|
33
|
+
|
34
|
+
for(i = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH; i++) {
|
35
|
+
branch->index[i] = (void*)NULL;
|
36
|
+
}
|
37
|
+
|
38
|
+
branch->children_size = 0;
|
39
|
+
branch->children_type = CT_BRANCH;
|
40
|
+
|
41
|
+
return (void*)branch;
|
42
|
+
}
|
43
|
+
|
44
|
+
void *init_leaf_node(unsigned long offset)
|
45
|
+
{
|
46
|
+
leaf_node leaf;
|
47
|
+
|
48
|
+
if(!(leaf = (leaf_node)malloc(sizeof(struct _leaf_node)))) {
|
49
|
+
rb_raise(rb_eStandardError, "memory is not enough");
|
50
|
+
}
|
51
|
+
|
52
|
+
leaf->offset = offset;
|
53
|
+
leaf->data = 0;
|
54
|
+
|
55
|
+
return (void*)leaf;
|
56
|
+
}
|
57
|
+
|
58
|
+
//
|
59
|
+
// initialize copy
|
60
|
+
//
|
61
|
+
void copy_root_node(root_node root, root_node orig)
|
62
|
+
{
|
63
|
+
unsigned int i, count;
|
64
|
+
|
65
|
+
root->children_size = orig->children_size;
|
66
|
+
|
67
|
+
for (i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE || count < orig->children_size; i++) {
|
68
|
+
if (orig->index[i]) {
|
69
|
+
root->index[i] = init_and_copy_brance_node(root, (branch_node)orig->index[i]);
|
70
|
+
count++;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
void copy_branch_node(root_node root, branch_node branch, branch_node orig)
|
76
|
+
{
|
77
|
+
unsigned int i, count;
|
78
|
+
|
79
|
+
branch->children_type = orig->children_type;
|
80
|
+
branch->children_size = orig->children_size;
|
81
|
+
|
82
|
+
if (orig->children_type == CT_LEAF) {
|
83
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < orig->children_size; i++) {
|
84
|
+
if (orig->index[i]) {
|
85
|
+
branch->index[i] = init_and_copy_leaf_node(root, (leaf_node)orig->index[i]);
|
86
|
+
count++;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
} else {
|
90
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < orig->children_size; i++) {
|
91
|
+
if (orig->index[i]) {
|
92
|
+
branch->index[i] = init_and_copy_brance_node(root, (branch_node)orig->index[i]);
|
93
|
+
count++;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
void *init_and_copy_brance_node(root_node root, branch_node orig)
|
100
|
+
{
|
101
|
+
branch_node branch;
|
102
|
+
|
103
|
+
branch = (branch_node)init_branch_node();
|
104
|
+
copy_branch_node(root, branch, orig);
|
105
|
+
|
106
|
+
return (void*)branch;
|
107
|
+
}
|
108
|
+
|
109
|
+
void *init_and_copy_leaf_node(root_node root, leaf_node orig)
|
110
|
+
{
|
111
|
+
leaf_node leaf;
|
112
|
+
|
113
|
+
leaf = (leaf_node)init_leaf_node(orig->offset);
|
114
|
+
leaf->data = orig->data;
|
115
|
+
root->size += BIT_COUNT(leaf->data);
|
116
|
+
|
117
|
+
return (void*)leaf;
|
118
|
+
}
|
119
|
+
|
120
|
+
//
|
121
|
+
// memory free
|
122
|
+
//
|
123
|
+
void destroy_all(root_node root)
|
124
|
+
{
|
125
|
+
destroy_all_branches(root);
|
126
|
+
free(root);
|
127
|
+
}
|
128
|
+
|
129
|
+
void destroy_all_branches(root_node root)
|
130
|
+
{
|
131
|
+
unsigned int i, count;
|
132
|
+
|
133
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE || count < root->children_size; i++) {
|
134
|
+
if (root->index[i]) {
|
135
|
+
destroy_branch((branch_node)root->index[i]);
|
136
|
+
root->index[i] = (void*)NULL;
|
137
|
+
count++;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
root->size = 0;
|
142
|
+
root->children_size = 0;
|
143
|
+
}
|
144
|
+
|
145
|
+
void destroy_branch(branch_node branch)
|
146
|
+
{
|
147
|
+
unsigned int i, count;
|
148
|
+
|
149
|
+
if (branch->children_type == CT_LEAF) {
|
150
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < branch->children_size; i++) {
|
151
|
+
if (branch->index[i]) {
|
152
|
+
free((leaf_node)branch->index[i]);
|
153
|
+
branch->index[i] = (void*)NULL;
|
154
|
+
count++;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
} else {
|
158
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < branch->children_size; i++) {
|
159
|
+
if (branch->index[i]) {
|
160
|
+
destroy_branch((branch_node)branch->index[i]);
|
161
|
+
branch->index[i] = (void*)NULL;
|
162
|
+
count++;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
}
|
166
|
+
free(branch);
|
167
|
+
}
|
data/ext/methods.c
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
//************************************
|
2
|
+
// method.c
|
3
|
+
//************************************
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <ruby.h>
|
9
|
+
#include "figure_set.h"
|
10
|
+
|
11
|
+
//-----------------------------------------------------------
|
12
|
+
// Ruby Methods
|
13
|
+
// ----------------------------------------------------------
|
14
|
+
|
15
|
+
/**
|
16
|
+
* allocate
|
17
|
+
**/
|
18
|
+
static VALUE t_allocate(VALUE klass)
|
19
|
+
{
|
20
|
+
VALUE obj;
|
21
|
+
root_node root;
|
22
|
+
|
23
|
+
obj = Data_Make_Struct(klass, struct _root_node, NULL, destroy_all, root);
|
24
|
+
init_root_node(root);
|
25
|
+
|
26
|
+
return obj;
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* initialize
|
31
|
+
**/
|
32
|
+
static VALUE t_initialize(int argc, VALUE *argv, VALUE self)
|
33
|
+
{
|
34
|
+
VALUE num, ary_element;
|
35
|
+
root_node root;
|
36
|
+
unsigned long i, len;
|
37
|
+
|
38
|
+
Data_Get_Struct(self, struct _root_node, root);
|
39
|
+
|
40
|
+
if (argc == 1 && TYPE(argv[0]) == T_ARRAY) {
|
41
|
+
len = RARRAY_LEN(argv[0]);
|
42
|
+
for(i = 0; i < len; i++) {
|
43
|
+
ary_element = rb_ary_entry(argv[0], i);
|
44
|
+
if ((TYPE(ary_element) == T_FIXNUM) && VALID_MIN_VALUE <= ary_element && VALID_MAX_VALUE >= ary_element) {
|
45
|
+
add_num(root, NUM2ULONG(ary_element));
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
return self;
|
51
|
+
}
|
52
|
+
|
53
|
+
/**
|
54
|
+
* initialize_copy
|
55
|
+
**/
|
56
|
+
static VALUE t_initialize_copy(VALUE self, VALUE orig)
|
57
|
+
{
|
58
|
+
root_node root, orig_set;
|
59
|
+
|
60
|
+
Data_Get_Struct(self, struct _root_node, root);
|
61
|
+
Data_Get_Struct(orig, struct _root_node, orig_set);
|
62
|
+
copy_root_node(root, orig_set);
|
63
|
+
|
64
|
+
return self;
|
65
|
+
}
|
66
|
+
|
67
|
+
/**
|
68
|
+
* add
|
69
|
+
**/
|
70
|
+
static VALUE t_add(VALUE self, VALUE value)
|
71
|
+
{
|
72
|
+
root_node root;
|
73
|
+
|
74
|
+
if (TYPE(value) != T_FIXNUM) return;
|
75
|
+
if (VALID_MIN_VALUE > value || VALID_MAX_VALUE < value) return;
|
76
|
+
|
77
|
+
Data_Get_Struct(self, struct _root_node, root);
|
78
|
+
add_num(root, NUM2ULONG(value));
|
79
|
+
|
80
|
+
return self;
|
81
|
+
}
|
82
|
+
|
83
|
+
/**
|
84
|
+
* delete
|
85
|
+
**/
|
86
|
+
static VALUE t_delete(VALUE self, VALUE value)
|
87
|
+
{
|
88
|
+
root_node root;
|
89
|
+
|
90
|
+
if (TYPE(value) != T_FIXNUM) return;
|
91
|
+
if (VALID_MIN_VALUE > value || VALID_MAX_VALUE < value) return;
|
92
|
+
|
93
|
+
Data_Get_Struct(self, struct _root_node, root);
|
94
|
+
delete_num(root, NUM2ULONG(value));
|
95
|
+
|
96
|
+
return self;
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* intersection
|
101
|
+
**/
|
102
|
+
static VALUE t_intersection(VALUE self, VALUE other)
|
103
|
+
{
|
104
|
+
VALUE obj;
|
105
|
+
root_node result_set, set0, set1;
|
106
|
+
|
107
|
+
obj = Data_Make_Struct(rb_cFigureSet, struct _root_node, NULL, destroy_all, result_set);
|
108
|
+
init_root_node(result_set);
|
109
|
+
|
110
|
+
Data_Get_Struct(self, struct _root_node, set0);
|
111
|
+
Data_Get_Struct(other, struct _root_node, set1);
|
112
|
+
|
113
|
+
intersection(result_set, set0, set1);
|
114
|
+
|
115
|
+
return obj;
|
116
|
+
}
|
117
|
+
|
118
|
+
/**
|
119
|
+
* union
|
120
|
+
**/
|
121
|
+
static VALUE t_union(VALUE self, VALUE other)
|
122
|
+
{
|
123
|
+
VALUE obj;
|
124
|
+
root_node result_set, set0, set1;
|
125
|
+
|
126
|
+
obj = Data_Make_Struct(rb_cFigureSet, struct _root_node, NULL, destroy_all, result_set);
|
127
|
+
init_root_node(result_set);
|
128
|
+
|
129
|
+
Data_Get_Struct(self, struct _root_node, set0);
|
130
|
+
Data_Get_Struct(other, struct _root_node, set1);
|
131
|
+
|
132
|
+
join(result_set, set0, set1);
|
133
|
+
|
134
|
+
return obj;
|
135
|
+
}
|
136
|
+
|
137
|
+
/**
|
138
|
+
* to_a
|
139
|
+
**/
|
140
|
+
static VALUE t_to_a(VALUE self)
|
141
|
+
{
|
142
|
+
root_node root;
|
143
|
+
VALUE array;
|
144
|
+
|
145
|
+
Data_Get_Struct(self, struct _root_node, root);
|
146
|
+
array = rb_ary_new2(root->size);
|
147
|
+
|
148
|
+
to_array(root, array);
|
149
|
+
|
150
|
+
return array;
|
151
|
+
}
|
152
|
+
|
153
|
+
/**
|
154
|
+
* sample
|
155
|
+
**/
|
156
|
+
static VALUE t_sample(int argc, VALUE *argv, VALUE self)
|
157
|
+
{
|
158
|
+
root_node root;
|
159
|
+
VALUE array;
|
160
|
+
unsigned long sample_count = 1UL;
|
161
|
+
|
162
|
+
Data_Get_Struct(self, struct _root_node, root);
|
163
|
+
|
164
|
+
if (argc == 1 && TYPE(argv[0]) == T_FIXNUM) {
|
165
|
+
sample_count = NUM2ULONG(argv[0]);
|
166
|
+
if (sample_count < 1UL || sample_count > root->size) sample_count = 1UL;
|
167
|
+
}
|
168
|
+
|
169
|
+
array = rb_ary_new2(sample_count);
|
170
|
+
if (sample_count == root->size) {
|
171
|
+
to_array(root, array);
|
172
|
+
} else {
|
173
|
+
sample(root, array, sample_count);
|
174
|
+
}
|
175
|
+
|
176
|
+
return array;
|
177
|
+
}
|
178
|
+
|
179
|
+
/**
|
180
|
+
* size
|
181
|
+
**/
|
182
|
+
static VALUE t_size(VALUE self)
|
183
|
+
{
|
184
|
+
root_node root;
|
185
|
+
|
186
|
+
Data_Get_Struct(self, struct _root_node, root);
|
187
|
+
|
188
|
+
return ULONG2NUM(root->size);
|
189
|
+
}
|
190
|
+
|
191
|
+
/**
|
192
|
+
* empty?
|
193
|
+
**/
|
194
|
+
static VALUE t_empty(VALUE self)
|
195
|
+
{
|
196
|
+
root_node root;
|
197
|
+
|
198
|
+
Data_Get_Struct(self, struct _root_node, root);
|
199
|
+
|
200
|
+
if (root->size == 0) {
|
201
|
+
return Qtrue;
|
202
|
+
} else {
|
203
|
+
return Qfalse;
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
207
|
+
/**
|
208
|
+
* cler
|
209
|
+
**/
|
210
|
+
static VALUE t_clear(VALUE self)
|
211
|
+
{
|
212
|
+
root_node root;
|
213
|
+
|
214
|
+
Data_Get_Struct(self, struct _root_node, root);
|
215
|
+
|
216
|
+
if (root->size) {
|
217
|
+
destroy_all_branches(root);
|
218
|
+
}
|
219
|
+
|
220
|
+
return self;
|
221
|
+
}
|
222
|
+
|
223
|
+
|
224
|
+
/**
|
225
|
+
* define class
|
226
|
+
**/
|
227
|
+
void Init_figure_set(void) {
|
228
|
+
rb_cFigureSet = rb_define_class("FigureSet", rb_cObject);
|
229
|
+
rb_define_alloc_func(rb_cFigureSet, t_allocate);
|
230
|
+
rb_define_private_method(rb_cFigureSet, "initialize", t_initialize, -1);
|
231
|
+
rb_define_method(rb_cFigureSet, "initialize_copy", t_initialize_copy, 1);
|
232
|
+
rb_define_method(rb_cFigureSet, "add", t_add, 1);
|
233
|
+
rb_define_method(rb_cFigureSet, "delete", t_delete, 1);
|
234
|
+
rb_define_method(rb_cFigureSet, "intersection", t_intersection, 1);
|
235
|
+
rb_define_method(rb_cFigureSet, "union", t_union, 1);
|
236
|
+
rb_define_method(rb_cFigureSet, "to_a", t_to_a, 0);
|
237
|
+
rb_define_method(rb_cFigureSet, "sample", t_sample, -1);
|
238
|
+
rb_define_method(rb_cFigureSet, "size", t_size, 0);
|
239
|
+
rb_define_method(rb_cFigureSet, "empty?", t_empty, 0);
|
240
|
+
rb_define_method(rb_cFigureSet, "clear", t_clear, 0);
|
241
|
+
rb_define_alias(rb_cFigureSet, "<<", "add");
|
242
|
+
rb_define_alias(rb_cFigureSet, "&", "intersection");
|
243
|
+
rb_define_alias(rb_cFigureSet, "|", "union");
|
244
|
+
rb_define_alias(rb_cFigureSet, "length", "size");
|
245
|
+
}
|
data/ext/or.c
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
//************************************
|
2
|
+
// or.c
|
3
|
+
//************************************
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <ruby.h>
|
9
|
+
#include "figure_set.h"
|
10
|
+
|
11
|
+
//
|
12
|
+
// join
|
13
|
+
//
|
14
|
+
void join(root_node result_set, root_node set0, root_node set1)
|
15
|
+
{
|
16
|
+
unsigned int i;
|
17
|
+
|
18
|
+
if (set0->size == 0 && set1->size == 0) {
|
19
|
+
return;
|
20
|
+
} else if (set0->size == 0) {
|
21
|
+
copy_root_node(result_set, set1);
|
22
|
+
return;
|
23
|
+
} else if (set1->size == 0) {
|
24
|
+
copy_root_node(result_set, set0);
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
|
28
|
+
for (i = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE; i++) {
|
29
|
+
if (set0->index[i] && set1->index[i]) {
|
30
|
+
result_set->index[i] = init_and_join_brance_node(result_set, (branch_node)set0->index[i], (branch_node)set1->index[i]);
|
31
|
+
result_set->children_size++;
|
32
|
+
} else if(set0->index[i]) {
|
33
|
+
result_set->index[i] = init_and_copy_brance_node(result_set, (branch_node)set0->index[i]);
|
34
|
+
result_set->children_size++;
|
35
|
+
} else if (set1->index[i]) {
|
36
|
+
result_set->index[i] = init_and_copy_brance_node(result_set, (branch_node)set1->index[i]);
|
37
|
+
result_set->children_size++;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
|
43
|
+
void *init_and_join_brance_node(root_node result_set, branch_node set0, branch_node set1)
|
44
|
+
{
|
45
|
+
branch_node branch;
|
46
|
+
|
47
|
+
branch = (branch_node)init_branch_node();
|
48
|
+
|
49
|
+
if (set0->children_type == CT_LEAF) {
|
50
|
+
branch->children_type = CT_LEAF;
|
51
|
+
last_join_branch_node(result_set, branch, set0, set1);
|
52
|
+
} else {
|
53
|
+
middle_join_branch_node(result_set, branch, set0, set1);
|
54
|
+
}
|
55
|
+
|
56
|
+
return (void*)branch;
|
57
|
+
}
|
58
|
+
|
59
|
+
void middle_join_branch_node(root_node result_set, branch_node branch, branch_node set0, branch_node set1)
|
60
|
+
{
|
61
|
+
unsigned int i;
|
62
|
+
|
63
|
+
for (i = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH; i++) {
|
64
|
+
if (set0->index[i] && set1->index[i]) {
|
65
|
+
branch->index[i] = init_and_join_brance_node(result_set, (branch_node)set0->index[i], (branch_node)set1->index[i]);
|
66
|
+
branch->children_size++;
|
67
|
+
} else if (set0->index[i]) {
|
68
|
+
branch->index[i] = init_and_copy_brance_node(result_set, (branch_node)set0->index[i]);
|
69
|
+
branch->children_size++;
|
70
|
+
} else if (set1->index[i]) {
|
71
|
+
branch->index[i] = init_and_copy_brance_node(result_set, (branch_node)set1->index[i]);
|
72
|
+
branch->children_size++;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
void last_join_branch_node(root_node result_set, branch_node branch, branch_node set0, branch_node set1)
|
78
|
+
{
|
79
|
+
unsigned int i;
|
80
|
+
|
81
|
+
for (i = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH; i++) {
|
82
|
+
if (set0->index[i] && set1->index[i]) {
|
83
|
+
branch->index[i] = init_and_join_leaf_node(result_set, (leaf_node)set0->index[i], (leaf_node)set1->index[i]);
|
84
|
+
branch->children_size++;
|
85
|
+
} else if (set0->index[i]) {
|
86
|
+
branch->index[i] = init_and_copy_leaf_node(result_set, (leaf_node)set0->index[i]);
|
87
|
+
branch->children_size++;
|
88
|
+
} else if (set1->index[i]) {
|
89
|
+
branch->index[i] = init_and_copy_leaf_node(result_set, (leaf_node)set1->index[i]);
|
90
|
+
branch->children_size++;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
void *init_and_join_leaf_node(root_node result_set, leaf_node set0, leaf_node set1)
|
96
|
+
{
|
97
|
+
leaf_node leaf;
|
98
|
+
|
99
|
+
leaf = (leaf_node)init_leaf_node(set0->offset);
|
100
|
+
|
101
|
+
leaf->data = set0->data | set1->data;
|
102
|
+
result_set->size += BIT_COUNT(leaf->data);
|
103
|
+
|
104
|
+
return (void*)leaf;
|
105
|
+
}
|
data/ext/sample.c
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
//************************************
|
2
|
+
// sample.c
|
3
|
+
//************************************
|
4
|
+
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <time.h>
|
9
|
+
#include <ruby.h>
|
10
|
+
#include "figure_set.h"
|
11
|
+
|
12
|
+
//
|
13
|
+
// output Array object from sample set
|
14
|
+
//
|
15
|
+
void sample(root_node root, VALUE array, unsigned long sample_count)
|
16
|
+
{
|
17
|
+
unsigned int start_sample, sample_now, i, count, target_point;
|
18
|
+
|
19
|
+
srand((unsigned) time(NULL));
|
20
|
+
|
21
|
+
start_sample = RARRAY_LEN(array);
|
22
|
+
|
23
|
+
for(sample_now = start_sample; sample_now < sample_count; sample_now++) {
|
24
|
+
target_point = rand() % root->children_size;
|
25
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_ROOT_NODE || count < root->children_size; i++) {
|
26
|
+
if (root->index[i]) {
|
27
|
+
if (count == target_point) {
|
28
|
+
search_and_sample_array((branch_node)root->index[i], array);
|
29
|
+
}
|
30
|
+
count++;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
if (RARRAY_LEN(array) < sample_count) {
|
36
|
+
sample(root, array, sample_count);
|
37
|
+
}
|
38
|
+
|
39
|
+
rb_funcall(array, rb_intern("uniq!"), 0);
|
40
|
+
if (RARRAY_LEN(array) < sample_count) {
|
41
|
+
sample(root, array, sample_count);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
void search_and_sample_array(branch_node branch, VALUE array)
|
46
|
+
{
|
47
|
+
unsigned int i, count, target_point;
|
48
|
+
|
49
|
+
if (!branch->children_size) return;
|
50
|
+
|
51
|
+
target_point = rand() % branch->children_size;
|
52
|
+
|
53
|
+
for(i = 0, count = 0; i < MAX_CHILDREN_SIZE_OF_BRANCH || count < branch->children_size; i++) {
|
54
|
+
if (branch->index[i]) {
|
55
|
+
if (count == target_point) {
|
56
|
+
if (branch->children_type == CT_LEAF) {
|
57
|
+
search_and_sample_array_at_leaf((leaf_node)branch->index[i], array);
|
58
|
+
} else {
|
59
|
+
search_and_sample_array((branch_node)branch->index[i], array);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
count++;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
void search_and_sample_array_at_leaf(leaf_node leaf, VALUE array)
|
68
|
+
{
|
69
|
+
unsigned long i = 0, hit_count = 0;
|
70
|
+
unsigned long bit_count, target_point;
|
71
|
+
unsigned long x;
|
72
|
+
|
73
|
+
x = leaf->data;
|
74
|
+
bit_count = BIT_COUNT(leaf->data);
|
75
|
+
if (!bit_count) return;
|
76
|
+
|
77
|
+
target_point = rand() % bit_count;
|
78
|
+
|
79
|
+
while(x) {
|
80
|
+
if (x & 1UL) {
|
81
|
+
if (hit_count == target_point) {
|
82
|
+
rb_ary_push(array, ULONG2NUM(leaf->offset + i));
|
83
|
+
}
|
84
|
+
hit_count++;
|
85
|
+
}
|
86
|
+
x = x >> 1UL;
|
87
|
+
i++;
|
88
|
+
}
|
89
|
+
}
|
data/lib/figure_set.rb
ADDED
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: figure_set
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Tsukasa OISHI
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-11-26 00:00:00 +09:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: newgem
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 25
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 2
|
33
|
+
- 3
|
34
|
+
version: 1.2.3
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: hoe
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 55
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 8
|
49
|
+
- 0
|
50
|
+
version: 1.8.0
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
description: FigureSet.
|
54
|
+
email:
|
55
|
+
- tsukasa.oishi@gmail.com
|
56
|
+
executables: []
|
57
|
+
|
58
|
+
extensions:
|
59
|
+
- ext/extconf.rb
|
60
|
+
extra_rdoc_files:
|
61
|
+
- History.txt
|
62
|
+
- Manifest.txt
|
63
|
+
- README.rdoc
|
64
|
+
files:
|
65
|
+
- History.txt
|
66
|
+
- Manifest.txt
|
67
|
+
- README.rdoc
|
68
|
+
- Rakefile
|
69
|
+
- lib/figure_set.rb
|
70
|
+
- ext/extconf.rb
|
71
|
+
- ext/figure_set.h
|
72
|
+
- ext/methods.c
|
73
|
+
- ext/init.c
|
74
|
+
- ext/index.c
|
75
|
+
- ext/and.c
|
76
|
+
- ext/or.c
|
77
|
+
- ext/array.c
|
78
|
+
- ext/sample.c
|
79
|
+
has_rdoc: true
|
80
|
+
homepage: http://www.kaeruspoon.net/
|
81
|
+
licenses: []
|
82
|
+
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options:
|
85
|
+
- --main
|
86
|
+
- README.rdoc
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
- ext
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
hash: 3
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
requirements: []
|
109
|
+
|
110
|
+
rubyforge_project: figure_set
|
111
|
+
rubygems_version: 1.6.2
|
112
|
+
signing_key:
|
113
|
+
specification_version: 2
|
114
|
+
summary: FigureSet.
|
115
|
+
test_files: []
|
116
|
+
|