mincore 0.0.8 → 0.0.9.pre

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/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ writable_tmp_dir/
2
+ scratch
3
+ *.gem
4
+ Gemfile.lock
5
+ gems/
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+
3
+ before_script: ./bin/ci/before_build.sh
4
+
5
+ script: "bundle exec rake test"
6
+
7
+ rvm:
8
+ - 1.9.3
9
+ - 1.8.7
10
+ - 2.0.0-p0
11
+ - 2.0.0-p247
12
+
13
+ gemfile:
14
+ - Gemfile
15
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'RubyInline', '>= 3.10.1', :require => 'inline'
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ ruby-mincore
2
+ ============
3
+ [![Gem Version](https://badge.fury.io/rb/mincore.png)](http://badge.fury.io/rb/mincore)
4
+ [![Build Status](https://travis-ci.org/noushi/ruby-mincore.png?branch=master)](https://travis-ci.org/noushi/ruby-mincore)
5
+ [![Code Climate](https://codeclimate.com/github/noushi/ruby-mincore.png)](https://codeclimate.com/github/noushi/ruby-mincore)
6
+ [![Dependency Status](https://gemnasium.com/noushi/ruby-mincore.png)](https://gemnasium.com/noushi/ruby-mincore)
7
+
8
+ Ruby bindings for Linux cache manipulation.
9
+
10
+ This project is heavily inspired from [Feh/nocache](http://github.com/Feh/nocache).
11
+
12
+
13
+ Status & Limitations
14
+ ====================
15
+
16
+ Currently, the File class is extended as such:
17
+ - `mincore(filename)` is exported to Ruby in the form of an array of booleans corresponding to each page of the file.
18
+ - `cachedel(filename, count=1)` calls `posix_fadvise(2)` to purge all file pages from the cache
19
+ - `PAGESIZE` is a simple helper that returns the value of PAGESIZE (4KB on Intel)
20
+
21
+ The bindings are implemented using Ruby Inline, instead of the classic mkmf ext C.
22
+
23
+ There is a gem module generated, and the code is still beta.
24
+
25
+ Since `File.cachedel()` isn't guaranteed to work (no matter how many time you call it), the `test_cachedel_non_empty_file` most always succeeds without properly asserting that `posix_fadvise()` has worked.
26
+
27
+ Also, the tests use a `./writable_tmp_dir/` directory to store the temporary test files. `/tmp` can't be used since it's
28
+ usually a ramfs, and files will always be in cache, until they're deleted.
29
+
30
+
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'rake/testtask'
2
+ require 'rake/clean'
3
+
4
+ WORKDIR='writable_tmp_dir'
5
+
6
+ CLEAN.include("#{WORKDIR}/*")
7
+
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.libs << 'lib'
10
+ t.libs << 'test'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+
16
+
17
+
18
+ task :default => :test
19
+
data/TODO ADDED
@@ -0,0 +1,20 @@
1
+ - Integrate mincore functions fully in the File class : File.mincore
2
+ should be an instance method operating on the file instance
3
+ => use GetOpenFile macro from io.h and keep the class method form
4
+ as well:
5
+ https://github.com/ruby/ruby/blob/4c2304f0004e9f1784540f3d36976aad9eab1f68/ext/socket/init.c#L181
6
+ https://github.com/ruby/ruby/blob/4c2304f0004e9f1784540f3d36976aad9eab1f68/ext/socket/init.c#L204
7
+ https://github.com/ruby/ruby/blob/4c2304f0004e9f1784540f3d36976aad9eab1f68/ext/socket/init.c#L208
8
+
9
+ - Generate proper Ruby exceptions instead of perror/exit(1)
10
+ - Fix the documentation
11
+ - Find a better way to manage the gem: auto-increment version...
12
+ - Find a (more!) proper test case for cachedel
13
+
14
+ POSTPONED
15
+ =========
16
+ - fstat() on each mincore() call is most probably overkill: we don't
17
+ need to read file status just to know if it's empty or not a
18
+ regular file, but I need to know the pageinfo array size and if I
19
+ receive the file name from inotify, its metadata should already be
20
+ in RAM...
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+
3
+ gem install bundler
4
+
data/mincore.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'mincore'
3
+ s.version = '0.0.9.pre'
4
+ s.date = '2013-11-10'
5
+
6
+ s.homepage = 'http://github.com/noushi/ruby-mincore'
7
+ s.summary = "Ruby bindings for Linux cache manipulation"
8
+ s.description = <<-DESC
9
+ micore provides Ruby bindings for Linux cache manipulation,
10
+ including cache inspection and deletion for a specific file.
11
+ DESC
12
+ s.license = 'GPL-2'
13
+
14
+ s.authors = ["Reda NOUSHI"]
15
+ s.email = 'reda_noushi@yahoo.com'
16
+
17
+ s.files = `git ls-files`.split($/)
18
+ #s.files = ["lib/mincore.rb"]
19
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
20
+
21
+ s.add_runtime_dependency "RubyInline", [">= 3.10.1"]
22
+ s.add_development_dependency "RubyInline", [">= 3.10.1"]
23
+ end
@@ -0,0 +1,160 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ require 'fileutils'
4
+ require 'mincore'
5
+
6
+ class TestableFile
7
+ attr_reader :path, :size, :name
8
+
9
+ def initialize(size_kb=100, path='/tmp')
10
+ @path = path
11
+ FileUtils.mkdir_p(@path) unless File.directory?(@path)
12
+
13
+ @size_kb = size_kb
14
+
15
+ @name = "#{@path}/testable_file.#{rand(1000000)}"
16
+ FileUtils.touch(@name)
17
+ end
18
+
19
+ def numpages
20
+ File.open(@name).numpages
21
+ end
22
+
23
+ def cli_fill
24
+ @size_kb.times do
25
+ s = "s" * 1024
26
+ `echo -n #{s} >>#{@name}`
27
+ end
28
+ end
29
+
30
+ def ruby_fill
31
+ File.open(@name, "w") do |f|
32
+ # s = Random.new.bytes(1024)
33
+ s = "s" * 1024
34
+ @size_kb.times do
35
+ f.write s
36
+ end
37
+ end
38
+ end
39
+
40
+ alias_method :fill, :ruby_fill
41
+ # alias_method :fill, :cli_fill
42
+
43
+ def read(pages=@size_kb)
44
+ if pages == @size_kb
45
+ `cat #{@name} >/dev/null`
46
+ else
47
+ 4.times do
48
+ File.open(@name, "r").each do |line|
49
+ line
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def delete
56
+ File.delete(@name)
57
+ end
58
+
59
+ def describe
60
+ "file #{@name} of current size #{File.stat(@name).size}"
61
+ end
62
+
63
+ end
64
+
65
+ class MincoreTest < Test::Unit::TestCase
66
+ def test_pagesize
67
+ pagesize = `getconf PAGESIZE`.to_i
68
+ assert_equal pagesize, File.PAGESIZE
69
+ end
70
+
71
+ def test_numpages
72
+ size_kb = rand(1000)
73
+ f = TestableFile.new(size_kb, "./writable_tmp_dir")
74
+ pagesize = File.PAGESIZE
75
+
76
+ numpages = (File.open(f.name).stat.size*1024 + pagesize -1 ) / pagesize
77
+
78
+ assert_equal numpages, f.numpages
79
+
80
+ f.delete
81
+ end
82
+
83
+ def test_mincore_empty_file
84
+ _generic_mincore_test 0, [0,[]], :delete => true
85
+ end
86
+
87
+ def test_mincore_non_empty_file
88
+ _generic_mincore_test 40, :delete => true
89
+ end
90
+
91
+ def test_cachedel_empty_file
92
+ _generic_cachedel_test 0
93
+ end
94
+
95
+ def test_cachedel_non_empty_file
96
+ _generic_cachedel_test 400
97
+ end
98
+
99
+
100
+ def _generic_mincore_test(size_kb, result=nil, delete=true)
101
+ size = size_kb * 1024
102
+
103
+ f = TestableFile.new(size_kb, "./writable_tmp_dir")
104
+
105
+ retcode, pieces = File.mincore(f.name)
106
+
107
+ assert_equal [0, []], [retcode, pieces]
108
+
109
+ return f if size == 0
110
+
111
+ f.fill
112
+
113
+ retcode, pieces = File.mincore(f.name)
114
+
115
+ assert_equal retcode, 0, f.describe
116
+ assert_equal [[true, f.numpages]], pieces.tinify
117
+
118
+ f.delete if delete
119
+
120
+ return f
121
+ end
122
+
123
+ def _generic_cachedel_test(size_kb)
124
+ f=_generic_mincore_test(size_kb, nil, false)
125
+
126
+ f.read
127
+
128
+ retcode, pieces = File.mincore(f.name)
129
+
130
+ assert_equal retcode, 0, f.describe
131
+ assert_equal [true]*(f.numpages), pieces
132
+
133
+ ret = File.cachedel(f.name, 30)
134
+ assert_equal 0, ret, f.describe
135
+
136
+ #`cachedel #{f.name}`
137
+
138
+ retcode, pieces = File.mincore(f.name)
139
+
140
+ assert_equal retcode, 0, f.describe
141
+
142
+ if size_kb == 0
143
+ ret = []
144
+ assert_equal ret, pieces.tinify, f.describe
145
+ else
146
+ ret = [[true, f.numpages]]
147
+ if ret != pieces.tinify #The code/test is still valid even if the file is fully kept cached
148
+ assert_not_equal ret, pieces.tinify, f.describe
149
+ end
150
+ end
151
+
152
+ f.delete
153
+
154
+ end
155
+
156
+
157
+
158
+
159
+
160
+ end
@@ -0,0 +1,31 @@
1
+ Dir.chdir File.expand_path("../../", __FILE__)
2
+ $LOAD_PATH.unshift ".", "lib", "test"
3
+
4
+ require "test/unit"
5
+
6
+
7
+ class Array
8
+ def tinify
9
+ cur = nil
10
+ ret = []
11
+ self.each_index { |x|
12
+ if x == 0
13
+ cur = self[x]
14
+ ret << [self[x],1]
15
+ next
16
+ end
17
+
18
+ if cur == self[x]
19
+ # puts "<#{ret.last}>"
20
+ ret[-1][1] += 1
21
+ else
22
+ ret << [self[x],1]
23
+ end
24
+
25
+ cur = self[x]
26
+ }
27
+ ret
28
+ end
29
+ end
30
+
31
+
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ArrayTinifyTest < Test::Unit::TestCase
4
+ def test_true
5
+ a = [true]*10
6
+
7
+ # puts "#{a.tinify}"
8
+ assert_equal [[true, 10]], a.tinify
9
+ end
10
+
11
+ def test_true_false
12
+ a = [[true]*10, [false]*10].flatten
13
+
14
+ assert_equal [[true, 10], [false, 10]], a.tinify
15
+ end
16
+ end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mincore
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
5
- prerelease:
4
+ hash: -2045603333
5
+ prerelease: 6
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 8
10
- version: 0.0.8
9
+ - 9
10
+ - pre
11
+ version: 0.0.9.pre
11
12
  platform: ruby
12
13
  authors:
13
14
  - Reda NOUSHI
@@ -15,7 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2013-11-09 00:00:00 Z
19
+ date: 2013-11-10 00:00:00 Z
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: RubyInline
@@ -49,7 +50,7 @@ dependencies:
49
50
  version: 3.10.1
50
51
  type: :development
51
52
  version_requirements: *id002
52
- description: Provides cache inspection and deletion for a specific file.
53
+ description: " micore provides Ruby bindings for Linux cache manipulation, \n including cache inspection and deletion for a specific file.\n"
53
54
  email: reda_noushi@yahoo.com
54
55
  executables: []
55
56
 
@@ -58,10 +59,21 @@ extensions: []
58
59
  extra_rdoc_files: []
59
60
 
60
61
  files:
62
+ - .gitignore
63
+ - .travis.yml
64
+ - Gemfile
65
+ - README.md
66
+ - Rakefile
67
+ - TODO
68
+ - bin/ci/before_build.sh
61
69
  - lib/mincore.rb
70
+ - mincore.gemspec
71
+ - test/mincore_test.rb
72
+ - test/test_helper.rb
73
+ - test/tinify_test.rb
62
74
  homepage: http://github.com/noushi/ruby-mincore
63
75
  licenses:
64
- - GPLv2
76
+ - GPL-2
65
77
  post_install_message:
66
78
  rdoc_options: []
67
79
 
@@ -79,12 +91,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
91
  required_rubygems_version: !ruby/object:Gem::Requirement
80
92
  none: false
81
93
  requirements:
82
- - - ">="
94
+ - - ">"
83
95
  - !ruby/object:Gem::Version
84
- hash: 3
96
+ hash: 25
85
97
  segments:
86
- - 0
87
- version: "0"
98
+ - 1
99
+ - 3
100
+ - 1
101
+ version: 1.3.1
88
102
  requirements: []
89
103
 
90
104
  rubyforge_project:
@@ -92,5 +106,7 @@ rubygems_version: 1.8.15
92
106
  signing_key:
93
107
  specification_version: 3
94
108
  summary: Ruby bindings for Linux cache manipulation
95
- test_files: []
96
-
109
+ test_files:
110
+ - test/mincore_test.rb
111
+ - test/test_helper.rb
112
+ - test/tinify_test.rb