mincore 0.0.8 → 0.0.9.pre

Sign up to get free protection for your applications and to get access to all the features.
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