figure_set 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|