fsdb 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.txt +1 -1
- data/lib/fsdb/database.rb +1 -1
- data/rakefile +5 -3
- data/test/test-concurrency.rb +5 -3
- data/test/test-formats.rb +3 -1
- data/test/test-fsdb.rb +5 -3
- metadata +10 -148
- data/junk/OLDRakefile +0 -98
- data/junk/OLDRakefile2 +0 -55
- data/junk/check-cache.rb +0 -18
- data/junk/create-lock.rb +0 -25
- data/junk/doc/old-api/classes/FSDB.html +0 -139
- data/junk/doc/old-api/classes/FSDB/Database.html +0 -953
- data/junk/doc/old-api/classes/FSDB/Database.src/M000029.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000030.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000031.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000032.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000033.html +0 -33
- data/junk/doc/old-api/classes/FSDB/Database.src/M000034.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000035.html +0 -22
- data/junk/doc/old-api/classes/FSDB/Database.src/M000036.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000037.html +0 -22
- data/junk/doc/old-api/classes/FSDB/Database.src/M000038.html +0 -43
- data/junk/doc/old-api/classes/FSDB/Database.src/M000039.html +0 -25
- data/junk/doc/old-api/classes/FSDB/Database.src/M000040.html +0 -43
- data/junk/doc/old-api/classes/FSDB/Database.src/M000041.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Database.src/M000042.html +0 -22
- data/junk/doc/old-api/classes/FSDB/Database.src/M000043.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000044.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000045.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000046.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000047.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000048.html +0 -16
- data/junk/doc/old-api/classes/FSDB/Database.src/M000049.html +0 -71
- data/junk/doc/old-api/classes/FSDB/Database.src/M000050.html +0 -43
- data/junk/doc/old-api/classes/FSDB/Database.src/M000051.html +0 -53
- data/junk/doc/old-api/classes/FSDB/Database.src/M000052.html +0 -44
- data/junk/doc/old-api/classes/FSDB/Database.src/M000053.html +0 -39
- data/junk/doc/old-api/classes/FSDB/Database.src/M000054.html +0 -72
- data/junk/doc/old-api/classes/FSDB/Database.src/M000055.html +0 -39
- data/junk/doc/old-api/classes/FSDB/Database.src/M000056.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000057.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000058.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000059.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000060.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000061.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Database.src/M000062.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Database.src/M000063.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database.src/M000064.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Database/AbortedTransaction.html +0 -118
- data/junk/doc/old-api/classes/FSDB/Database/CreateFileError.html +0 -120
- data/junk/doc/old-api/classes/FSDB/Database/DirIsImmutableError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/DirNotEmptyError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/FormatError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/MissingFileError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/MissingObjectError.html +0 -117
- data/junk/doc/old-api/classes/FSDB/Database/NotDirError.html +0 -118
- data/junk/doc/old-api/classes/FSDB/Database/PathComponentError.html +0 -120
- data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.html +0 -148
- data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.src/M000005.html +0 -21
- data/junk/doc/old-api/classes/FSDB/DatabaseDebuggable.src/M000007.html +0 -21
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.html +0 -210
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000006.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000007.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000008.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000009.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000010.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000011.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000012.html +0 -22
- data/junk/doc/old-api/classes/FSDB/DirectoryIterators.src/M000013.html +0 -22
- data/junk/doc/old-api/classes/FSDB/ForkSafely.html +0 -126
- data/junk/doc/old-api/classes/FSDB/Modex.html +0 -237
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000024.html +0 -21
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000025.html +0 -30
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000026.html +0 -21
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000027.html +0 -30
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000028.html +0 -44
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000029.html +0 -26
- data/junk/doc/old-api/classes/FSDB/Modex.src/M000030.html +0 -48
- data/junk/doc/old-api/classes/FSDB/Modex/ForkSafely.html +0 -105
- data/junk/doc/old-api/classes/FSDB/Mutex.html +0 -244
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000018.html +0 -19
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000019.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000020.html +0 -19
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000021.html +0 -18
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000022.html +0 -23
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000023.html +0 -30
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000024.html +0 -26
- data/junk/doc/old-api/classes/FSDB/Mutex.src/M000025.html +0 -21
- data/junk/doc/old-api/classes/FSDB/Mutex/ForkSafely.html +0 -105
- data/junk/doc/old-api/classes/FSDB/PathUtilities.html +0 -257
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000012.html +0 -23
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000013.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000014.html +0 -23
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000015.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000016.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000017.html +0 -22
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000018.html +0 -23
- data/junk/doc/old-api/classes/FSDB/PathUtilities.src/M000019.html +0 -18
- data/junk/doc/old-api/classes/FSDB/PathUtilities/InvalidPathError.html +0 -111
- data/junk/doc/old-api/classes/File.html +0 -272
- data/junk/doc/old-api/classes/File.src/M000001.html +0 -17
- data/junk/doc/old-api/classes/File.src/M000002.html +0 -17
- data/junk/doc/old-api/classes/File.src/M000003.html +0 -20
- data/junk/doc/old-api/classes/File.src/M000004.html +0 -20
- data/junk/doc/old-api/classes/File.src/M000005.html +0 -32
- data/junk/doc/old-api/classes/File.src/M000006.html +0 -32
- data/junk/doc/old-api/created.rid +0 -1
- data/junk/doc/old-api/files/README.html +0 -112
- data/junk/doc/old-api/files/RELEASE-NOTES.html +0 -233
- data/junk/doc/old-api/files/fsdb_txt.html +0 -888
- data/junk/doc/old-api/files/lib/fsdb/database_rb.html +0 -115
- data/junk/doc/old-api/files/lib/fsdb/file-lock_rb.html +0 -109
- data/junk/doc/old-api/files/lib/fsdb/modex_rb.html +0 -121
- data/junk/doc/old-api/files/lib/fsdb/mutex_rb.html +0 -108
- data/junk/doc/old-api/files/lib/fsdb/util_rb.html +0 -108
- data/junk/doc/old-api/fr_class_index.html +0 -47
- data/junk/doc/old-api/fr_file_index.html +0 -34
- data/junk/doc/old-api/fr_method_index.html +0 -90
- data/junk/doc/old-api/index.html +0 -24
- data/junk/doc/old-api/rdoc-style.css +0 -208
- data/junk/file-lock-nb.rb +0 -15
- data/junk/fl.rb +0 -144
- data/junk/flock-test.rb +0 -39
- data/junk/fsdb.kateproject +0 -47
- data/junk/fsdb.prj +0 -196
- data/junk/fsdb.sf +0 -46
- data/junk/insert-dir.rb +0 -48
- data/junk/lock-test-bug.rb +0 -150
- data/junk/lock-test-too-simple.rb +0 -136
- data/junk/lock-test.rb +0 -151
- data/junk/mkrdoc +0 -7
- data/junk/restore-fsdb.rb +0 -37
- data/junk/rf.txt +0 -5
- data/junk/solaris-bug-fixed.rb +0 -184
- data/junk/solaris-bug.rb +0 -182
- data/junk/solaris-bug.txt +0 -43
- data/junk/sync.rb +0 -327
- data/junk/test-file-lock.html +0 -86
- data/junk/test-file-lock.rb +0 -84
- data/junk/test-processes.rb +0 -131
- data/junk/test-threads.rb +0 -113
- data/junk/wiki-mutex.rb +0 -108
- data/misc/fsdb-blorubu.txt +0 -47
- data/misc/mtime-and-file-id.txt +0 -23
- data/misc/posixlock.txt +0 -148
data/junk/test-processes.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
require './test.rb'
|
2
|
-
|
3
|
-
## should also test nested transactions, replace, insert, delete, etc...
|
4
|
-
module TestStressProcesses
|
5
|
-
|
6
|
-
class ProcessTester
|
7
|
-
attr_accessor :x
|
8
|
-
def initialize
|
9
|
-
@x = 0
|
10
|
-
end
|
11
|
-
def inspect
|
12
|
-
"<ProcessTester:@x=#{@x}>"
|
13
|
-
end
|
14
|
-
def to_s
|
15
|
-
inspect
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.go
|
20
|
-
|
21
|
-
db = $db
|
22
|
-
|
23
|
-
object_count = 5
|
24
|
-
process_count = 10
|
25
|
-
rep_count = 1000
|
26
|
-
max_sleep = 0.01
|
27
|
-
|
28
|
-
paths = (0...object_count).map {|i| "thread-test/t#{i}"}
|
29
|
-
|
30
|
-
paths.each do |path|
|
31
|
-
db[path] = ProcessTester.new
|
32
|
-
end
|
33
|
-
|
34
|
-
processes = (0...process_count).map do
|
35
|
-
fork do
|
36
|
-
srand(Process.pid)
|
37
|
-
|
38
|
-
rep_count.times do |iter|
|
39
|
-
path = paths[rand(paths.size)]
|
40
|
-
|
41
|
-
case rand(100)
|
42
|
-
|
43
|
-
when 0..49
|
44
|
-
db.browse path do |tester|
|
45
|
-
__x__ = tester.x
|
46
|
-
|
47
|
-
data = File.read(File.join(db.dir, path))
|
48
|
-
uncached_x = Marshal.load(data).x
|
49
|
-
unless uncached_x == __x__
|
50
|
-
fail "browse test: cache is stale:\n" +
|
51
|
-
" #{uncached_x} on disk, #{__x__} in cache"
|
52
|
-
end
|
53
|
-
|
54
|
-
sleep(rand*max_sleep)
|
55
|
-
|
56
|
-
unless __x__ == tester.x
|
57
|
-
fail "browse test: x == #{__x__} but tester.x == #{tester.x}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
when 50..69
|
62
|
-
db.edit path do |tester|
|
63
|
-
__x__ = tester.x
|
64
|
-
|
65
|
-
data = File.read(File.join(db.dir, path))
|
66
|
-
uncached_x = Marshal.load(data).x
|
67
|
-
unless uncached_x == __x__
|
68
|
-
fail "edit test: cache is stale:\n" +
|
69
|
-
" #{uncached_x} on disk, #{__x__} in cache"
|
70
|
-
end
|
71
|
-
|
72
|
-
tester.x += 1
|
73
|
-
__x__ = tester.x
|
74
|
-
|
75
|
-
sleep(rand*max_sleep)
|
76
|
-
|
77
|
-
unless __x__ == tester.x
|
78
|
-
fail "edit test: x == #{__x__} but tester.x == #{tester.x}"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
when 70..90
|
83
|
-
db.replace path do |tester|
|
84
|
-
__x__ = tester.x
|
85
|
-
|
86
|
-
data = File.read(File.join(db.dir, path))
|
87
|
-
uncached_x = Marshal.load(data).x
|
88
|
-
unless uncached_x == __x__
|
89
|
-
fail "replace test: cache is stale:\n" +
|
90
|
-
" #{uncached_x} on disk, #{__x__} in cache"
|
91
|
-
end
|
92
|
-
|
93
|
-
tester.x += 1
|
94
|
-
__x__ = tester.x
|
95
|
-
|
96
|
-
sleep(rand*max_sleep)
|
97
|
-
|
98
|
-
unless __x__ == tester.x
|
99
|
-
fail "replace test: x == #{__x__} but tester.x == #{tester.x}"
|
100
|
-
end
|
101
|
-
|
102
|
-
tester
|
103
|
-
end
|
104
|
-
|
105
|
-
else
|
106
|
-
sleep(rand*max_sleep)
|
107
|
-
db.clear_cache
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
thread = Thread.new do
|
116
|
-
i = 0
|
117
|
-
loop do
|
118
|
-
puts i
|
119
|
-
sleep 1
|
120
|
-
i += 1
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
process_count.times {Process.wait}
|
125
|
-
thread.kill
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
TestStressProcesses.go if __FILE__ == $0
|
data/junk/test-threads.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
require './test.rb'
|
2
|
-
|
3
|
-
## should also test nested transactions, replace, insert, delete, etc...
|
4
|
-
module TestStressThreads
|
5
|
-
|
6
|
-
class ThreadTester
|
7
|
-
attr_accessor :x
|
8
|
-
def initialize
|
9
|
-
@x = 0
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.go
|
14
|
-
|
15
|
-
db = $db
|
16
|
-
|
17
|
-
srand(3765)
|
18
|
-
|
19
|
-
object_count = 100
|
20
|
-
thread_count = 100
|
21
|
-
rep_count = 1000
|
22
|
-
max_sleep = nil
|
23
|
-
|
24
|
-
paths = (0...object_count).map {|i| "thread-test/t#{i}"}
|
25
|
-
|
26
|
-
paths.each do |path|
|
27
|
-
db[path] = ThreadTester.new
|
28
|
-
end
|
29
|
-
|
30
|
-
threads = (0...thread_count).map do |thread_index|
|
31
|
-
Thread.new(thread_index) do |ti|
|
32
|
-
Thread.current[:number] = ti
|
33
|
-
Thread.current[:transactions] = 0
|
34
|
-
rep_count.times do |iter|
|
35
|
-
Thread.current[:iter] = iter
|
36
|
-
path = paths[rand(paths.size)]
|
37
|
-
|
38
|
-
case rand(3)
|
39
|
-
|
40
|
-
when 0
|
41
|
-
db.browse path do |tester|
|
42
|
-
__x__ = tester.x
|
43
|
-
sleep(rand*max_sleep) if max_sleep
|
44
|
-
unless __x__ == tester.x
|
45
|
-
fail "browse: x == #{__x__} but tester.x == #{tester.x}"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
Thread.current[:transactions] += 1
|
49
|
-
|
50
|
-
when 1
|
51
|
-
db.edit path do |tester|
|
52
|
-
tester.x += 1
|
53
|
-
__x__ = tester.x
|
54
|
-
sleep(rand*max_sleep) if max_sleep
|
55
|
-
unless __x__ == tester.x
|
56
|
-
fail "edit: x == #{__x__} but tester.x == #{tester.x}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
Thread.current[:transactions] += 1
|
60
|
-
|
61
|
-
else
|
62
|
-
sleep(rand*max_sleep) if max_sleep
|
63
|
-
if rand(20) == 0
|
64
|
-
db.clear_cache
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
start_time = Process.times
|
74
|
-
|
75
|
-
# threads.each{|t|printf "%6d", t[:number]}
|
76
|
-
# puts
|
77
|
-
# puts "-----|" * threads.size
|
78
|
-
sleep 1
|
79
|
-
|
80
|
-
# stats = old_stats = nil
|
81
|
-
loop do
|
82
|
-
# old_stats = stats
|
83
|
-
# stats = threads.map{|t|t[:iter]}
|
84
|
-
# stats.each{|s|printf "%6d", s}
|
85
|
-
puts "."
|
86
|
-
break unless threads.any?{|t|t.alive?}
|
87
|
-
# if old_stats == stats
|
88
|
-
# fail "Deadlock!"
|
89
|
-
# end
|
90
|
-
sleep 1
|
91
|
-
end
|
92
|
-
|
93
|
-
end_time = Process.times
|
94
|
-
|
95
|
-
utime = end_time.utime - start_time.utime
|
96
|
-
stime = end_time.stime - start_time.stime
|
97
|
-
rate = threads.inject(0) {|sum, t| sum += t[:transactions]} /
|
98
|
-
(utime + stime)
|
99
|
-
|
100
|
-
puts "All db worker threads dead."
|
101
|
-
puts "time: %12s%12s" % %w{user system}
|
102
|
-
puts " %12.2f%12.2f" % [utime, stime]
|
103
|
-
puts "\nExecuted %d transactions per second" % rate
|
104
|
-
|
105
|
-
threads.each do |thread|
|
106
|
-
thread.join
|
107
|
-
end
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
TestStressThreads.go
|
data/junk/wiki-mutex.rb
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'thread'
|
4
|
-
|
5
|
-
# Mutex class based on standard thread.rb Mutex, which has some problems:
|
6
|
-
# - waiters are not a strict queue (try_lock can jump the queue, after
|
7
|
-
# which the queue gets *rotated*). Race condition.
|
8
|
-
# - doesn't use Thread.exclusive in enough places
|
9
|
-
# - no way to make dead threads give up the mutex, which is crucial in a fork
|
10
|
-
class ForkableMutex
|
11
|
-
def initialize
|
12
|
-
@waiting = [] # queue of waiting threads
|
13
|
-
@locked = nil; # the thread that has the lock
|
14
|
-
@waiting.taint # enable tainted comunication
|
15
|
-
self.taint
|
16
|
-
end
|
17
|
-
|
18
|
-
def locked?
|
19
|
-
@locked
|
20
|
-
end
|
21
|
-
|
22
|
-
def try_lock
|
23
|
-
Thread.exclusive do
|
24
|
-
if not @locked and @waiting.empty?
|
25
|
-
@locked = Thread.current
|
26
|
-
true
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def lock
|
32
|
-
thread = Thread.current
|
33
|
-
Thread.exclusive do
|
34
|
-
if @locked
|
35
|
-
@waiting.push thread
|
36
|
-
Thread.stop
|
37
|
-
unless @locked == thread
|
38
|
-
raise ThreadError, "queue was jumped"
|
39
|
-
end
|
40
|
-
else
|
41
|
-
@locked = thread
|
42
|
-
end
|
43
|
-
self
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def unlock
|
48
|
-
return unless @locked
|
49
|
-
|
50
|
-
t = Thread.exclusive { wake_next_waiter }
|
51
|
-
|
52
|
-
begin
|
53
|
-
t.run if t
|
54
|
-
rescue ThreadError
|
55
|
-
end
|
56
|
-
self
|
57
|
-
end
|
58
|
-
|
59
|
-
def synchronize
|
60
|
-
lock
|
61
|
-
yield
|
62
|
-
ensure
|
63
|
-
unlock
|
64
|
-
end
|
65
|
-
|
66
|
-
def remove_dead
|
67
|
-
Thread.exclusive do
|
68
|
-
@waiting = @waiting.select {|t| t.alive?}
|
69
|
-
wake_next_waiter if @locked and not @locked.alive?
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
def wake_next_waiter
|
75
|
-
t = @waiting.shift
|
76
|
-
t.wakeup if t
|
77
|
-
@locked = t
|
78
|
-
rescue ThreadError
|
79
|
-
retry
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
module ForkSafely
|
84
|
-
def fork
|
85
|
-
super do
|
86
|
-
ObjectSpace.each_object(ForkableMutex) { |m| m.remove_dead }
|
87
|
-
yield
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
include ForkSafely
|
92
|
-
|
93
|
-
|
94
|
-
if __FILE__ == $0
|
95
|
-
include ForkSafely
|
96
|
-
|
97
|
-
m = ForkableMutex.new
|
98
|
-
|
99
|
-
Thread.new { m.synchronize { sleep 2 } }
|
100
|
-
|
101
|
-
fork do
|
102
|
-
m.synchronize { puts "Didn't get here if you used standard mutex or fork." }
|
103
|
-
end
|
104
|
-
|
105
|
-
m.synchronize { puts "Got here." }
|
106
|
-
|
107
|
-
Process.wait
|
108
|
-
end
|
data/misc/fsdb-blorubu.txt
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
Like pstore, fsdb is:
|
2
|
-
|
3
|
-
- pure ruby, cross-platform
|
4
|
-
|
5
|
-
- ruby license
|
6
|
-
|
7
|
-
- simple API
|
8
|
-
|
9
|
-
- simple implementation (though less so)
|
10
|
-
|
11
|
-
- transaction based, with abort capability
|
12
|
-
|
13
|
-
However, pstore has some drawbacks:
|
14
|
-
|
15
|
-
- not thread-safe (though it is process-safe)
|
16
|
-
|
17
|
-
- coarse granularity (transaction applies to whole pstore), does not scale well
|
18
|
-
|
19
|
-
- uses marshalling, even if your data is is some other format that doesn't require the overhead of marshalling (e.g., strings, binary data)
|
20
|
-
|
21
|
-
Other advantages of fsdb:
|
22
|
-
|
23
|
-
- can use YAML (or other formats) where you want to (e.g., in user settings, but perhaps not for large ruby objects or binary data). It's easy to specify a mapping from path patterns to data formats.
|
24
|
-
|
25
|
-
- thread-safe, so you can easily wire it up to a multithreaded server, like drb (see examples/server.rb)
|
26
|
-
|
27
|
-
- objects in the database are just files, and so can be manipulated with standard command line tools (including rsync, versioning tools, etc.).
|
28
|
-
|
29
|
-
- granularity is up to you: you can have lots of little objects, if you want, (there are tradeoffs, of course)
|
30
|
-
|
31
|
-
- scales as well as the fs does
|
32
|
-
|
33
|
-
- thoroughly stress-tested, partially unit-tested. (But still not quite stable on Windows.)
|
34
|
-
|
35
|
-
- Can select fcntl-based locking (if platform supports it), which should allow safe use with NFS mounts on linux
|
36
|
-
|
37
|
-
Disadvantages of fsdb:
|
38
|
-
|
39
|
-
- If you want indexes, you need to implement them on top of fsdb. You could do:
|
40
|
-
|
41
|
-
db['name-index'] = RBTree.new
|
42
|
-
|
43
|
-
and define your own methods for adding/removing objects that also updates the name-index. The name-index maps names (or other keys) to paths in the db.
|
44
|
-
|
45
|
-
- Likewise, no SQL, out of the box.
|
46
|
-
|
47
|
-
- Efficiency and reliability depends on the fs. (My benchmarks get on the order of 1000 transactions per sec on a 3 yr old linux box.)
|
data/misc/mtime-and-file-id.txt
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
mtime granularity on win?
|
2
|
-
|
3
|
-
see:
|
4
|
-
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/by_handle_file_information_str.asp
|
5
|
-
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/file_times.asp
|
6
|
-
|
7
|
-
http://www.google.com/search?hl=en&ie=ISO-8859-1&q=unique+file+id+on+windows&btnG=Google+Search
|
8
|
-
|
9
|
-
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=42340
|
10
|
-
|
11
|
-
Windows can give a unique file indentifier using the function GetFileInformationByHandle() (See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/getfileinformationbyhandle.asp)
|
12
|
-
|
13
|
-
Example: (hFile is a handle to a file)
|
14
|
-
|
15
|
-
BY_HANDLE_FILE_INFORMATION FileInfo;
|
16
|
-
|
17
|
-
GetFileInformationByHandle(hFile, &FileInfo);
|
18
|
-
inode= FileInfo.nFileIndexLow | (FileInfo.nFileIndexHigh << 32);
|
19
|
-
volume=FileInfo.dwVolumeSerialNumber;
|
20
|
-
|
21
|
-
According to Micorsoft : "The identifier (low and high parts) and the volume serial number uniquely identify a file on a single computer. To determine whether two open handles represent the same file, combine this identifier and the volume serial number for each file and compare them."
|
22
|
-
|
23
|
-
|
data/misc/posixlock.txt
DELETED
@@ -1,148 +0,0 @@
|
|
1
|
-
Subject:
|
2
|
-
[ANN] posixlock
|
3
|
-
From:
|
4
|
-
"Ara.T.Howard" <ahoward@ngdc.noaa.gov>
|
5
|
-
Date:
|
6
|
-
Sat, 6 Dec 2003 05:22:07 +0900
|
7
|
-
To:
|
8
|
-
ruby-talk@ruby-lang.org (ruby-talk ML)
|
9
|
-
Newsgroups:
|
10
|
-
comp.lang.ruby
|
11
|
-
|
12
|
-
|
13
|
-
SYNOPSIS:
|
14
|
-
posixlock
|
15
|
-
use fcntl (vs. flock) based locking for File#flock
|
16
|
-
|
17
|
-
USAGE
|
18
|
-
require 'posixlock' # replaces File#flock!
|
19
|
-
|
20
|
-
|
21
|
-
i currently do not have a place to post software - so here's a little
|
22
|
-
extension that replaces flock with an fcntl based impl for posix compliant
|
23
|
-
locking (safe on nfs) - posted to c.l.r for posterity:
|
24
|
-
|
25
|
-
extconf.rb
|
26
|
-
================
|
27
|
-
require 'mkmf'
|
28
|
-
create_makefile 'posixlock'
|
29
|
-
================
|
30
|
-
|
31
|
-
posixlock.c
|
32
|
-
================
|
33
|
-
#ifdef _WIN32
|
34
|
-
#include "missing/file.h"
|
35
|
-
#endif
|
36
|
-
|
37
|
-
#include "ruby.h"
|
38
|
-
#include "rubyio.h"
|
39
|
-
#include "rubysig.h"
|
40
|
-
|
41
|
-
#ifdef HAVE_UNISTD_H
|
42
|
-
#include <unistd.h>
|
43
|
-
#endif
|
44
|
-
|
45
|
-
#ifdef HAVE_FCNTL_H
|
46
|
-
#include <fcntl.h>
|
47
|
-
#endif
|
48
|
-
|
49
|
-
#include <errno.h>
|
50
|
-
|
51
|
-
extern VALUE rb_cFile;
|
52
|
-
|
53
|
-
# ifndef LOCK_SH
|
54
|
-
# define LOCK_SH 1
|
55
|
-
# endif
|
56
|
-
# ifndef LOCK_EX
|
57
|
-
# define LOCK_EX 2
|
58
|
-
# endif
|
59
|
-
# ifndef LOCK_NB
|
60
|
-
# define LOCK_NB 4
|
61
|
-
# endif
|
62
|
-
# ifndef LOCK_UN
|
63
|
-
# define LOCK_UN 8
|
64
|
-
# endif
|
65
|
-
|
66
|
-
static int
|
67
|
-
posixlock (fd, operation)
|
68
|
-
int fd;
|
69
|
-
int operation;
|
70
|
-
{
|
71
|
-
struct flock lock;
|
72
|
-
|
73
|
-
switch (operation & ~LOCK_NB)
|
74
|
-
{
|
75
|
-
case LOCK_SH:
|
76
|
-
lock.l_type = F_RDLCK;
|
77
|
-
break;
|
78
|
-
case LOCK_EX:
|
79
|
-
lock.l_type = F_WRLCK;
|
80
|
-
break;
|
81
|
-
case LOCK_UN:
|
82
|
-
lock.l_type = F_UNLCK;
|
83
|
-
break;
|
84
|
-
default:
|
85
|
-
errno = EINVAL;
|
86
|
-
return -1;
|
87
|
-
}
|
88
|
-
lock.l_whence = SEEK_SET;
|
89
|
-
lock.l_start = lock.l_len = 0L;
|
90
|
-
return fcntl (fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
|
91
|
-
}
|
92
|
-
|
93
|
-
|
94
|
-
static VALUE
|
95
|
-
rb_file_posixlock (obj, operation)
|
96
|
-
VALUE obj;
|
97
|
-
VALUE operation;
|
98
|
-
{
|
99
|
-
#ifndef __CHECKER__
|
100
|
-
OpenFile *fptr;
|
101
|
-
int ret;
|
102
|
-
|
103
|
-
rb_secure (2);
|
104
|
-
GetOpenFile (obj, fptr);
|
105
|
-
|
106
|
-
if (fptr->mode & FMODE_WRITABLE)
|
107
|
-
{
|
108
|
-
fflush (GetWriteFile (fptr));
|
109
|
-
}
|
110
|
-
retry:
|
111
|
-
TRAP_BEG;
|
112
|
-
ret = posixlock (fileno (fptr->f), NUM2INT (operation));
|
113
|
-
TRAP_END;
|
114
|
-
if (ret < 0)
|
115
|
-
{
|
116
|
-
switch (errno)
|
117
|
-
{
|
118
|
-
case EAGAIN:
|
119
|
-
case EACCES:
|
120
|
-
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
121
|
-
case EWOULDBLOCK:
|
122
|
-
#endif
|
123
|
-
return Qfalse;
|
124
|
-
case EINTR:
|
125
|
-
#if defined(ERESTART)
|
126
|
-
case ERESTART:
|
127
|
-
#endif
|
128
|
-
goto retry;
|
129
|
-
}
|
130
|
-
rb_sys_fail (fptr->path);
|
131
|
-
}
|
132
|
-
#endif
|
133
|
-
|
134
|
-
return INT2FIX (0);
|
135
|
-
}
|
136
|
-
|
137
|
-
|
138
|
-
void
|
139
|
-
Init_posixlock()
|
140
|
-
{
|
141
|
-
rb_define_method(rb_cFile, "flock", rb_file_posixlock, 1);
|
142
|
-
}
|
143
|
-
================
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
-a
|
148
|
-
-- ATTN: please update your address books with address below! =============================================================================== | EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov | PHONE :: 303.497.6469 | ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328 | STP :: http://www.ngdc.noaa.gov/stp/ | NGDC :: http://www.ngdc.noaa.gov/ | NESDIS :: http://www.nesdis.noaa.gov/ | NOAA :: http://www.noaa.gov/ | US DOC :: http://www.commerce.gov/ | | The difference between art and science is that science is what we | understand well enough to explain to a computer. | Art is everything else. | -- Donald Knuth, "Discover" | | /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done' ===============================================================================
|