og 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,84 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2002-2003 Navel, all rights reserved.
5
+ # $Id: array.rb 165 2004-11-18 12:04:04Z gmosx $
6
+
7
+ require "sync"
8
+
9
+ module G
10
+
11
+ # == SafeArray
12
+ #
13
+ # A thread-safe array. We use a sync object instead of a mutex,
14
+ # because it is re-entrant.
15
+ # An exclusive lock is needed when writing, a shared lock IS NEEDED
16
+ # when reading
17
+ #
18
+ class SafeArray < Array
19
+
20
+ attr :sync
21
+
22
+ # gmosx: delegator is not used.
23
+ #
24
+ def initialize(delegator = nil)
25
+ @sync = ::Sync.new()
26
+ end
27
+
28
+ def << (value)
29
+ return @sync.synchronize(::Sync::SH) {
30
+ super
31
+ }
32
+ end
33
+
34
+ def delete_if(&block)
35
+ return @sync.synchronize(::Sync::SH) {
36
+ super
37
+ }
38
+ end
39
+
40
+ def [](key)
41
+ return @sync.synchronize(::Sync::SH) {
42
+ super
43
+ }
44
+ end
45
+
46
+ def []=(key, value)
47
+ return @sync.synchronize(::Sync::EX) {
48
+ super
49
+ }
50
+ end
51
+
52
+ def delete(key)
53
+ return @sync.synchronize(::Sync::EX) {
54
+ super
55
+ }
56
+ end
57
+
58
+ def clear
59
+ @sync.synchronize(::Sync::EX) {
60
+ super
61
+ }
62
+ end
63
+
64
+ def size
65
+ return @sync.synchronize(::Sync::SH) {
66
+ super
67
+ }
68
+ end
69
+
70
+ def shift
71
+ return @sync.synchronize(::Sync::EX) {
72
+ super
73
+ }
74
+ end
75
+
76
+ def unshift(el)
77
+ return @sync.synchronize(::Sync::EX) {
78
+ super
79
+ }
80
+ end
81
+
82
+ end
83
+
84
+ end # module
@@ -0,0 +1,140 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ # * Anastasios Koutoumanos <ak@navel.gr>
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id: cache.rb 167 2004-11-23 14:03:10Z gmosx $
7
+
8
+ module G;
9
+
10
+ # = LRUCache
11
+ #
12
+ # A cache utilizing a simple LRU (Least Recently Used) policy.
13
+ # The items managed by this cache must respond to the #key method.
14
+ # Attempts to optimize reads rather than inserts!
15
+ #
16
+ # LRU semantics are enforced by inserting the items in a queue.
17
+ # The lru item is always at the tail. Two special sentinels
18
+ # (head, tail) are used to simplify (?) the code.
19
+ #
20
+ class LRUCache < Hash
21
+
22
+ # Mix this in your class to make LRU-managable.
23
+ #
24
+ module Item
25
+ attr_accessor :lru_key, :lru_prev, :lru_next
26
+ end
27
+
28
+ # head-tail sentinels
29
+ #
30
+ class Sentinel; include Item; end
31
+
32
+ # the maximum number of items in the cache
33
+ attr_accessor :max_items
34
+
35
+ # the head sentinel
36
+ attr :head
37
+ # the tail sentinel, tail.prev points to the lru item.
38
+ attr :tail
39
+
40
+ #
41
+ #
42
+ def initialize(max_items)
43
+ @max_items = max_items
44
+ lru_clear()
45
+ end
46
+
47
+ # Lookup an item in the cache
48
+ #
49
+ def [](key)
50
+ if item = super
51
+ return lru_touch(item)
52
+ end
53
+ end
54
+
55
+ # The inserted item is considered mru!
56
+ #
57
+ def []=(key, item)
58
+ item = super
59
+ item.lru_key = key
60
+ lru_insert(item)
61
+ end
62
+
63
+ # Delete an item from the cache
64
+ #
65
+ def delete(key)
66
+ if item = super
67
+ lru_delete(item)
68
+ end
69
+ end
70
+
71
+ # Clear the cache
72
+ #
73
+ def clear
74
+ super
75
+ lru_clear()
76
+ end
77
+
78
+ # The first (mru) element in the cache
79
+ #
80
+ def first
81
+ @head.lru_next
82
+ end
83
+
84
+ # The last (lru) element in the cache
85
+ #
86
+ def last
87
+ @tail.lru_prev
88
+ end
89
+ alias_method :lru, :last
90
+
91
+ private
92
+
93
+ # Delete an item from the lru list.
94
+ #
95
+ def lru_delete(item)
96
+ lru_join(item.lru_prev, item.lru_next)
97
+ return item
98
+ end
99
+
100
+ # Join two items in the lru list
101
+ # Return y to allow for chaining
102
+ #
103
+ def lru_join(x, y)
104
+ x.lru_next = y
105
+ y.lru_prev = x
106
+ return y
107
+ end
108
+
109
+ # Append a child item to a parent item in the lru list
110
+ # (Re)inserts the child in the list.
111
+ #
112
+ def lru_append(parent, child)
113
+ lru_join(child, parent.lru_next)
114
+ lru_join(parent, child)
115
+ end
116
+
117
+ # Insert an item
118
+ #
119
+ def lru_insert(item)
120
+ delete(last.lru_key) if size() > @max_items
121
+ lru_append(@head, item)
122
+ end
123
+
124
+ # Touch an item, make mru!
125
+ # Returns the item
126
+ #
127
+ def lru_touch(item)
128
+ lru_append(@head, lru_delete(item))
129
+ end
130
+
131
+ # Clear the lru
132
+ #
133
+ def lru_clear
134
+ @head = Sentinel.new
135
+ @tail = Sentinel.new
136
+ lru_join(@head, @tail)
137
+ end
138
+ end
139
+
140
+ end # module
@@ -0,0 +1,143 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: hash.rb 167 2004-11-23 14:03:10Z gmosx $
6
+
7
+ require "sync"
8
+
9
+ module G;
10
+
11
+ # == SafeHash
12
+ #
13
+ # A thread-safe hash. We use a sync object instead of a mutex,
14
+ # because it is re-entrant.
15
+ # An exclusive lock is needed when writing, a shared lock IS NEEDED
16
+ # when reading
17
+ # uses the delegator pattern to allow for multiple
18
+ # implementations!
19
+ #
20
+ class SafeHash < Hash
21
+ attr :sync
22
+
23
+ # gmosx: delegator is not used.
24
+ #
25
+ def initialize(delegator = nil)
26
+ @sync = ::Sync.new
27
+ end
28
+
29
+ def [](key)
30
+ return @sync.synchronize(::Sync::SH) {
31
+ super
32
+ }
33
+ end
34
+
35
+ def []=(key, value)
36
+ return @sync.synchronize(::Sync::EX) {
37
+ super
38
+ }
39
+ end
40
+
41
+ def delete(key)
42
+ return @sync.synchronize(::Sync::EX) {
43
+ super
44
+ }
45
+ end
46
+
47
+ def clear
48
+ @sync.synchronize(::Sync::EX) {
49
+ super
50
+ }
51
+ end
52
+
53
+ def size
54
+ return @sync.synchronize(::Sync::SH) {
55
+ super
56
+ }
57
+ end
58
+
59
+ def values
60
+ return @sync.synchronize(::Sync::SH) {
61
+ super
62
+ }
63
+ end
64
+
65
+ def keys
66
+ return @sync.synchronize(::Sync::SH) {
67
+ super
68
+ }
69
+ end
70
+
71
+ end # SafeHash
72
+
73
+ # == SafeHashDelegator
74
+ #
75
+ # A thread-safe hash. We use a sync object instead of a mutex,
76
+ # because it is re-entrant.
77
+ # An exclusive lock is needed when writing, a shared lock IS NEEDED
78
+ # when reading
79
+ #
80
+ # Design:
81
+ # This class uses the delegator pattern. However we dont use rubys
82
+ # delegation facilities, they are more general and powerfull than we
83
+ # need here (and slower). Instead a custom (but simple) solution is
84
+ # used.
85
+ #
86
+ # Example:
87
+ #
88
+ # hash = SafeHashDelegator.new(Hash.new)
89
+ # hash = SafeHashDelegator.new(Hash.new)
90
+
91
+ class SafeHashDelegator < Hash
92
+ attr :delegate, :sync
93
+
94
+ def initialize(delegate)
95
+ @delegate = delegate
96
+ @sync = ::Sync.new
97
+ end
98
+
99
+ def [](key)
100
+ return @sync.synchronize(::Sync::SH) {
101
+ @delegate[key]
102
+ }
103
+ end
104
+
105
+ def []=(key, value)
106
+ return @sync.synchronize(::Sync::EX) {
107
+ @delegate[key] = value
108
+ }
109
+ end
110
+
111
+ def delete(key)
112
+ return @sync.synchronize(::Sync::EX) {
113
+ @delegate.delete(key)
114
+ }
115
+ end
116
+
117
+ def clear
118
+ @sync.synchronize(::Sync::EX) {
119
+ @delegate.clear
120
+ }
121
+ end
122
+
123
+ def size
124
+ return @sync.synchronize(::Sync::SH) {
125
+ @delegate.size()
126
+ }
127
+ end
128
+
129
+ def values
130
+ return @sync.synchronize(::Sync::SH) {
131
+ @delegate.values()
132
+ }
133
+ end
134
+
135
+ def keys
136
+ return @sync.synchronize(::Sync::SH) {
137
+ @delegate.keys()
138
+ }
139
+ end
140
+
141
+ end # SafeHashDelegator
142
+
143
+ end # module
@@ -0,0 +1,91 @@
1
+ # Code from RubyOnRailes (http://www.rubyonrails.com)
2
+ # Copyright (c) 2004 David Heinemeier Hansson.
3
+ #
4
+
5
+ module G
6
+
7
+ # The Inflector transforms words from singular to plural, class names to table names, modulized class names to ones without,
8
+ # and class names to foreign keys.
9
+ #
10
+ module Inflector
11
+ extend self
12
+
13
+ def pluralize(word)
14
+ result = word.dup
15
+ plural_rules.each do |(rule, replacement)|
16
+ break if result.gsub!(rule, replacement)
17
+ end
18
+ return result
19
+ end
20
+
21
+ def singularize(word)
22
+ result = word.dup
23
+ singular_rules.each do |(rule, replacement)|
24
+ break if result.gsub!(rule, replacement)
25
+ end
26
+ return result
27
+ end
28
+
29
+ def camelize(lower_case_and_underscored_word)
30
+ lower_case_and_underscored_word.gsub(/(^|_)(.)/){$2.upcase}
31
+ end
32
+
33
+ def underscore(camel_cased_word)
34
+ camel_cased_word.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
35
+ end
36
+
37
+ def demodulize(class_name_in_module)
38
+ class_name_in_module.gsub(/^.*::/, '')
39
+ end
40
+
41
+ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
42
+ Inflector.underscore(Inflector.demodulize(class_name)) +
43
+ (separate_class_name_and_id_with_underscore ? "_id" : "id")
44
+ end
45
+
46
+ # Convert a class to a name.
47
+ #
48
+ def name(klass)
49
+ Inflector.underscore(Inflector.demodulize(klass.to_s))
50
+ end
51
+
52
+ # Convert a class to a name in plural
53
+ #
54
+ def plural_name(klass)
55
+ Inflector.pluralize(Inflector.underscore(Inflector.demodulize(klass.to_s)))
56
+ end
57
+
58
+ private
59
+ def plural_rules #:doc:
60
+ [
61
+ [/(x|ch|ss)$/, '\1es'], # search, switch, fix, box, process, address
62
+ [/([^aeiouy]|qu)y$/, '\1ies'], # query, ability, agency
63
+ [/(?:([^f])fe|([lr])f)$/, '\1\2ves'], # half, safe, wife
64
+ [/sis$/, 'ses'], # basis, diagnosis
65
+ [/([ti])um$/, '\1a'], # datum, medium
66
+ [/person$/, 'people'], # person, salesperson
67
+ [/man$/, 'men'], # man, woman, spokesman
68
+ [/child$/, 'children'], # child
69
+ [/s$/, 's'], # no change (compatibility)
70
+ [/$/, 's']
71
+ ]
72
+ end
73
+
74
+ def singular_rules #:doc:
75
+ [
76
+ [/(x|ch|ss)es$/, '\1'],
77
+ [/([^aeiouy]|qu)ies$/, '\1y'],
78
+ [/([lr])ves$/, '\1f'],
79
+ [/([^f])ves$/, '\1fe'],
80
+ [/(analy|ba|diagno|parenthe|progno|synop|the)ses$/, '\1sis'],
81
+ [/([ti])a$/, '\1um'],
82
+ [/people$/, 'person'],
83
+ [/men$/, 'man'],
84
+ [/status$/, 'status'],
85
+ [/children$/, 'child'],
86
+ [/s$/, '']
87
+ ]
88
+ end
89
+ end
90
+
91
+ end # module