fincore 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 80ed7da7089920d4881cd9622d916ba0a88f9b9a
4
+ data.tar.gz: a9d324094e62d2ba0a00dcf6d7d097bca5c0b384
5
+ SHA512:
6
+ metadata.gz: 8823ac5dd5518759131bd8a8003492bdbb49e45efd0f560985ba8960fb35881b46da42f3b26c9e57fd2d6f2c79d8acaeab44444f21421a48b313c84c2d032a9e
7
+ data.tar.gz: dad1442bfe0fa347ac001c5f71fc2e79d26cd5de64821ff43fc00ee7c2ba91e2c37afcde83ccadfe0883a0cabce04e21e3cb0a4285027b26f7a87a945ccc18e8
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+ gem "rake-compiler"
@@ -0,0 +1,28 @@
1
+ # ruby-fincore
2
+ Ruby File class extension to determine pages of file contents being resident in memory(in core).
3
+
4
+ ### Installation
5
+
6
+ To install:
7
+
8
+ ```sh
9
+ $ gem install fincore
10
+ ```
11
+
12
+ ### Usage
13
+
14
+ ```ruby
15
+ require 'fincore'
16
+
17
+ File.open('some/file') do |f|
18
+ f.cached_pages # return number of pages that are cached
19
+ f.total_pages # return number of pages at total
20
+ end
21
+ ```
22
+
23
+ ### Instance methods for File class
24
+ * `cached_pages -> Integer`
25
+ * `total_pages -> Integer`
26
+
27
+ ### Requirements
28
+ Your platform must support mincore system call.
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/extensiontask'
3
+
4
+ Rake::ExtensionTask.new 'fincore' do |ext|
5
+ ext.name = 'fincore'
6
+ ext.lib_dir = 'lib/fincore'
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'mkmf'
2
+
3
+ HEADERS = %w(unistd.h sys/mman.h sys/types.h sys/stat.h errno.h fcntl.h)
4
+
5
+ HEADERS.each do |header|
6
+ have_header(header) || abort("#{header} is missing!")
7
+ end
8
+
9
+ create_makefile('fincore')
@@ -0,0 +1,124 @@
1
+ #include <unistd.h>
2
+ #include <errno.h>
3
+ #include <sys/mman.h>
4
+ #include <sys/types.h>
5
+ #include <sys/stat.h>
6
+ #include <ruby.h>
7
+
8
+ /*
9
+ * Document-method: total_pages
10
+ * call-seq:
11
+ * total_pages -> Integer
12
+ * ==== Return
13
+ * number of pages file allocated.
14
+ */
15
+ VALUE rb_total_pages(VALUE self)
16
+ {
17
+ int fd;
18
+ size_t page_size;
19
+ struct stat st;
20
+ VALUE rb_fd;
21
+ VALUE rb_error[2];
22
+
23
+ rb_fd = rb_funcall(self, rb_intern("fileno"), 0);
24
+ fd = NUM2INT(rb_fd);
25
+
26
+ // sysconf
27
+ page_size = sysconf(_SC_PAGESIZE);
28
+ if (-1 == page_size){
29
+ rb_error[0] = rb_str_new2("sysconf failed");
30
+ rb_error[1] = INT2FIX(errno);
31
+ rb_exc_raise(rb_class_new_instance(2, rb_error, rb_eSystemCallError));
32
+ }
33
+
34
+ // fstat
35
+ if (fstat(fd, &st)) {
36
+ rb_error[0] = rb_str_new2("fstat failed");
37
+ rb_error[1] = INT2FIX(errno);
38
+ rb_exc_raise(rb_class_new_instance(2, rb_error, rb_eSystemCallError));
39
+ }
40
+ return INT2NUM((st.st_size + page_size - 1) / page_size);
41
+ }
42
+
43
+ /*
44
+ * Document-method: cached_pages
45
+ * call-seq:
46
+ * pages that are cached
47
+ */
48
+ VALUE rb_cached_pages(VALUE self)
49
+ {
50
+ int fd;
51
+ size_t page_size, total_pages;
52
+ size_t index;
53
+ struct stat st;
54
+ void *mmap_p;
55
+ unsigned char *vec;
56
+ unsigned int cached_pages;
57
+
58
+ VALUE rb_fd;
59
+ VALUE rb_error[2];
60
+
61
+ rb_fd = rb_funcall(self, rb_intern("fileno"), 0);
62
+ fd = NUM2INT(rb_fd);
63
+
64
+
65
+ // sysconf
66
+ page_size = sysconf(_SC_PAGESIZE);
67
+ if (-1 == page_size){
68
+ rb_error[0] = rb_str_new2("sysconf failed");
69
+ rb_error[1] = INT2FIX(errno);
70
+ rb_exc_raise(rb_class_new_instance(2, rb_error, rb_eSystemCallError));
71
+ }
72
+
73
+
74
+ // fstat
75
+ if (fstat(fd, &st)) {
76
+ rb_error[0] = rb_str_new2("fstat failed");
77
+ rb_error[1] = INT2FIX(errno);
78
+ rb_exc_raise(rb_class_new_instance(2, rb_error, rb_eSystemCallError));
79
+ }
80
+
81
+ if (st.st_size == 0) return INT2FIX(0);
82
+
83
+ total_pages = (st.st_size + page_size - 1) / page_size;
84
+
85
+ // mmap
86
+ mmap_p = mmap(NULL, st.st_size, PROT_NONE, MAP_SHARED, fd, 0);
87
+
88
+ if (MAP_FAILED == mmap_p) {
89
+ rb_error[0] = rb_str_new2("mmap failed");
90
+ rb_error[1] = INT2FIX(errno);
91
+ rb_exc_raise(rb_class_new_instance(2, rb_error, rb_eSystemCallError));
92
+ }
93
+
94
+ vec = ALLOC_N(unsigned char, total_pages);
95
+
96
+ // mincore
97
+ if (mincore(mmap_p, st.st_size, vec)) {
98
+ xfree(vec);
99
+ rb_error[0] = rb_str_new2("mincore failed");
100
+ rb_error[1] = INT2FIX(errno);
101
+ rb_exc_raise(rb_class_new_instance(2, rb_error, rb_eSystemCallError));
102
+ }
103
+
104
+ // munmap
105
+ if (munmap(mmap_p, st.st_size)) {
106
+ xfree(vec);
107
+ rb_error[0] = rb_str_new2("munmap failed");
108
+ rb_error[1] = INT2FIX(errno);
109
+ rb_exc_raise(rb_class_new_instance(2, rb_error, rb_eSystemCallError));
110
+ }
111
+
112
+ cached_pages = 0;
113
+ for (index = 0; index < total_pages; ++index) {
114
+ if (vec[index] & 1) cached_pages++;
115
+ }
116
+ xfree(vec);
117
+ return INT2NUM(cached_pages);
118
+ }
119
+
120
+ void Init_fincore()
121
+ {
122
+ rb_define_method(rb_cFile, "cached_pages", RUBY_METHOD_FUNC(rb_cached_pages), 0);
123
+ rb_define_method(rb_cFile, "total_pages", RUBY_METHOD_FUNC(rb_total_pages), 0);
124
+ }
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
4
+
5
+ require 'fincore/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'fincore'
9
+ spec.version = Fincore::VERSION
10
+ spec.authors = ['kzcat@outlook.jp']
11
+ spec.email = ['kzcat@outlook.jp']
12
+ spec.summary = %q{fincore}
13
+ spec.description = %q{FIle class extention to determine pages of file contents being resident in memory(in core).}
14
+ spec.homepage = 'https://github.com/kzcat/ruby-fincore'
15
+ spec.license = 'MIT'
16
+ spec.extensions = %w[ext/fincore/extconf.rb]
17
+ spec.files = %w(ext/fincore/extconf.rb ext/fincore/fincore.c Rakefile fincore.gemspec Gemfile lib/fincore.rb lib/fincore/version.rb README.md)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,4 @@
1
+ # coding: utf-8
2
+
3
+ require 'fincore/version'
4
+ require 'fincore.so'
@@ -0,0 +1,3 @@
1
+ module Fincore
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fincore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - kzcat@outlook.jp
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: FIle class extention to determine pages of file contents being resident
14
+ in memory(in core).
15
+ email:
16
+ - kzcat@outlook.jp
17
+ executables: []
18
+ extensions:
19
+ - ext/fincore/extconf.rb
20
+ extra_rdoc_files: []
21
+ files:
22
+ - Gemfile
23
+ - README.md
24
+ - Rakefile
25
+ - ext/fincore/extconf.rb
26
+ - ext/fincore/fincore.c
27
+ - fincore.gemspec
28
+ - lib/fincore.rb
29
+ - lib/fincore/version.rb
30
+ homepage: https://github.com/kzcat/ruby-fincore
31
+ licenses:
32
+ - MIT
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 2.4.6
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: fincore
54
+ test_files: []