rrlist 0.0.1

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,112 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <title>
7
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.8.6.1
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ hasFrames = window.top.frames.main ? true : false;
19
+ relpath = '';
20
+ framesUrl = "frames.html#!" + escape(window.location.href);
21
+ </script>
22
+
23
+
24
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
25
+
26
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
27
+
28
+
29
+ </head>
30
+ <body>
31
+ <div id="header">
32
+ <div id="menu">
33
+
34
+ <a href="_index.html">Index</a> &raquo;
35
+
36
+
37
+ <span class="title">Top Level Namespace</span>
38
+
39
+
40
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
41
+ </div>
42
+
43
+ <div id="search">
44
+
45
+ <a class="full_list_link" id="class_list_link"
46
+ href="class_list.html">
47
+ Class List
48
+ </a>
49
+
50
+ <a class="full_list_link" id="method_list_link"
51
+ href="method_list.html">
52
+ Method List
53
+ </a>
54
+
55
+ <a class="full_list_link" id="file_list_link"
56
+ href="file_list.html">
57
+ File List
58
+ </a>
59
+
60
+ </div>
61
+ <div class="clear"></div>
62
+ </div>
63
+
64
+ <iframe id="search_frame"></iframe>
65
+
66
+ <div id="content"><h1>Top Level Namespace
67
+
68
+
69
+
70
+ </h1>
71
+
72
+ <dl class="box">
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+ </dl>
82
+ <div class="clear"></div>
83
+
84
+ <h2>Defined Under Namespace</h2>
85
+ <p class="children">
86
+
87
+
88
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="RRList.html" title="RRList (module)">RRList</a></span>
89
+
90
+
91
+
92
+
93
+ </p>
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+ </div>
104
+
105
+ <div id="footer">
106
+ Generated on Fri May 31 08:53:01 2013 by
107
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
108
+ 0.8.6.1 (ruby-1.9.2).
109
+ </div>
110
+
111
+ </body>
112
+ </html>
@@ -0,0 +1,3 @@
1
+ require File.expand_path('../rrlist/version', __FILE__)
2
+ require File.expand_path('../rrlist/functions', __FILE__)
3
+ require File.expand_path('../rrlist/list', __FILE__)
@@ -0,0 +1,80 @@
1
+ module RRList
2
+
3
+ # @author Federico Dayan
4
+ # A helper module that provides some Proc object to be use with RRList::List
5
+ # @example
6
+ # RRList::List.new :size => 10, :range => 5, &RRList::Functions.max
7
+ # RRList::List.new :size => 10, :range => 5, &RRList::Functions.incr
8
+ module Functions
9
+
10
+ # @return [Proc] A proc to be used in a RRList::List that calculates the average of the values inserted at and index
11
+ def self.avg
12
+ Proc.new do |index, old_value, new_value|
13
+ case new_value
14
+ when Hash
15
+ if old_value
16
+ {
17
+ value: RRList::Functions.calc_average(old_value[:size],old_value[:value],new_value[:value],new_value[:size]),
18
+ size: old_value[:size] + new_value[:size]
19
+ }
20
+ else
21
+ {
22
+ value: new_value[:value],
23
+ size: new_value[:size],
24
+ }
25
+ end
26
+ else
27
+ if old_value
28
+ {
29
+ value: RRList::Functions.calc_average(old_value[:size],old_value[:value],new_value),
30
+ size: old_value[:size] + 1
31
+ }
32
+ else
33
+ {
34
+ value: new_value,
35
+ size: 1,
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ # @return [Proc] A proc to be used in a RRList::List that calculates the max of the values inserted at and index
43
+ def self.max
44
+ Proc.new do |index, old_value, new_value|
45
+ old_value.nil? || (new_value > old_value) ? new_value : old_value
46
+ end
47
+ end
48
+
49
+ # @return [Proc] A proc to be used in a RRList::List that calculates the min of the values inserted at and index
50
+ def self.min
51
+ Proc.new do |index, old_value, new_value|
52
+ old_value.nil? || (new_value < old_value) ? new_value : old_value
53
+ end
54
+ end
55
+
56
+ # @return [Proc] A proc to be used in a RRList::List increments the values inserted at and index
57
+ def self.incr
58
+ Proc.new do |index, old_value, new_value|
59
+ old_value ? (old_value + new_value) : new_value
60
+ end
61
+ end
62
+
63
+ # @return [Proc] A proc to be used in a RRList::List decrements the values inserted at and index
64
+ def self.decr
65
+ Proc.new do |index, old_value, new_value|
66
+ old_value ? (old_value - new_value) : new_value
67
+ end
68
+ end
69
+
70
+ private
71
+ def self.calc_average(numbers,previous_average,add_average,add_numbers=1)
72
+ numbers = numbers.to_f
73
+ previous_average = previous_average.to_f
74
+ add_average = add_average.to_f
75
+
76
+ (((numbers*previous_average )+ (add_average*add_numbers))/(numbers+add_numbers))
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,212 @@
1
+ require File.expand_path('../stores', __FILE__)
2
+
3
+ module RRList
4
+
5
+ # @author Federico Dayan
6
+ # Represents a Round Robin List.
7
+ # You set the max number of items and the size does not increse. While you add more items you lose the older items
8
+ class List
9
+
10
+ # Creates an object
11
+ # @param options [Hash]
12
+ # @option options [Integer] :size The size of the list. It does not add more elements than this.
13
+ # @option options [Integer] :range The range of the list. A range of 5 group 5 indexes into one position.
14
+ # @option options [Integer] :store Represents the where we save the data. It must follow a contract (see RRList:Stores:InMemoryArray)
15
+ # @yield [index, old_value, new_value]
16
+ def initialize(options={},&function_proc)
17
+ raise ":size is required" unless options[:size]
18
+ raise ":range should be greater thant 0" if options[:range] && options[:range] < 1
19
+
20
+ @store = options[:store] || RRList::Stores::InMemoryArray.new
21
+ @size = options[:size].to_i
22
+ @range = options[:range] || 1
23
+
24
+ reset
25
+
26
+ @function_proc = function_proc if block_given?
27
+ end
28
+
29
+ # Sets all values to nil, but it does not move the cursor
30
+ def clear
31
+ @store.fill(nil,0...@size)
32
+ end
33
+
34
+ # Reset this list, set all values to nil and move cursor to position 0
35
+ def reset
36
+ clear
37
+ @position = 0
38
+ @current_index = 0
39
+ end
40
+
41
+ # @return [Array<Integer>] The min_index and max_index as a list
42
+ def ranges
43
+ return [min_index,max_index]
44
+ end
45
+
46
+ # @param index [Integer] A number
47
+ # @return [True] if the given number is in the limits of the current max an min index of the list
48
+ def in_limits?(index)
49
+ ( !higher?(index) && !lower?(index))
50
+ end
51
+
52
+ # @param index [Integer] A number
53
+ # @return [True] if the given number is out of the range and all numbers will be lost if set
54
+ def out_of_range?(index) # refactor to out of limits?
55
+ if in_limits?(index)
56
+ return false
57
+ elsif higher?(index)
58
+ (index - max_index) >= (@size*@range)
59
+ elsif lower?(index)
60
+ (min_index - index) >= (@size*@range)
61
+ end
62
+ end
63
+
64
+ # @param index [Integer] A number
65
+ # @return [True] if the giving number is higher that the current max index.
66
+ def higher?(index)
67
+ index > (max_index + remaining_in_slot)
68
+ end
69
+
70
+ # @param index [Integer] A number
71
+ # @return [True] if the giving number is lower that the current min index.
72
+ def lower?(index)
73
+ index < min_index
74
+ end
75
+
76
+ # Iterates of over the values. Expects a block and passes the value
77
+ def each(&blk)
78
+ values.each(&blk)
79
+ end
80
+
81
+ # Iterates of over the values. Expects a block and passes the value and index
82
+ def each_with_index
83
+ ordered_values = values
84
+ ordered_values.each_with_index do |v,i|
85
+ yield ordered_values[i], min_index + (i*@range)
86
+ end
87
+ end
88
+
89
+ # @return [Object] the value for the specified index
90
+ def get(index)
91
+ return nil unless in_limits?(index)
92
+ pos = ((index/@range) % @size)
93
+ @store.get(pos)
94
+ end
95
+
96
+ # Adds a value to the next index position and moves the cursor forward
97
+ # @param value any object
98
+ def add(value)
99
+ @add_at_next = 0 unless @add_at_next
100
+ add_at @add_at_next, value
101
+ end
102
+
103
+ # Add an item to the specified postion and set the cursor to that position
104
+ # @param index must be higher than max_index
105
+ # @param value any object
106
+ def add_at(index,value)
107
+ raise "Index is lower that current index" if index < max_index
108
+
109
+ @add_at_next = index + 1
110
+ pos = position_for_index(index)
111
+
112
+ if out_of_range?(index)
113
+ @store.fill_with_nils
114
+ elsif higher?(index)
115
+ (pos-1).downto(@position) { |i| @store.put(i,nil) } if @current_index >= @size
116
+ @store.put(pos,nil) # We clean the value, if not it gets used by @before_add
117
+ end
118
+
119
+ set_value(pos,value)
120
+ @position = pos + 1
121
+ @current_index = index
122
+ self
123
+ end
124
+
125
+ # Set the specified value in the given index. The index must be in the range.
126
+ def set_at(index, value)
127
+ raise "The index #{index} is not in the range of the list" unless in_limits?(index)
128
+
129
+ pos = position_for_index(index)
130
+
131
+ set_value(pos,value)
132
+ end
133
+
134
+ # @return [Integer] if range is used, returns the remaining numbers in the current position.
135
+ def remaining_in_slot
136
+ (@range - (max_index % @range)) - 1
137
+ end
138
+
139
+ # @return [Integer] the index size of this list
140
+ def index_size
141
+ @size*@range
142
+ end
143
+
144
+ # @return [Integer] The min index of the current list
145
+ def min_index
146
+ if max_index <= index_size
147
+ 0
148
+ else
149
+ (max_index + 1) - index_size + remaining_in_slot
150
+ end
151
+ end
152
+
153
+ # @return [Integer] the max indes of current list
154
+ def max_index
155
+ @current_index
156
+ end
157
+
158
+ # @return [Array<Object>] The values of this list
159
+ def values
160
+ ret = if @current_index < (@size*@range)
161
+ @store.raw
162
+ else
163
+ @store.start_at(@position)
164
+ end
165
+
166
+ return ret
167
+ end
168
+
169
+ # Pretty print this object
170
+ def to_s
171
+ values.to_s
172
+ end
173
+
174
+ #########################
175
+ # Array API
176
+ #########################
177
+
178
+ # Returns the value for the given index
179
+ # @see #get
180
+ def [](index)
181
+ get(index)
182
+ end
183
+
184
+ # Sets a value to in the given index.
185
+ # @see #add_at
186
+ def []=(index,value)
187
+ add_at(index,value)
188
+ end
189
+
190
+ # Adds a value to the end of the list.
191
+ # @see #add
192
+ def << value
193
+ add(value)
194
+ end
195
+
196
+ private
197
+
198
+ def position_for_index(index)
199
+ ((index/@range) % @size)
200
+ end
201
+
202
+ def set_value(index,val,update_position=true)
203
+ if @function_proc
204
+ adding = @function_proc.call(index,@store.get(index),val)
205
+ @store.put(index, adding)
206
+ else
207
+ @store.put(index,val)
208
+ end
209
+ end
210
+
211
+ end
212
+ end
@@ -0,0 +1,45 @@
1
+ module RRList
2
+ module Stores
3
+
4
+ # @author Federico Dayan
5
+ # An implementation of a store that follows the contract
6
+ class InMemoryArray
7
+
8
+ def initialize
9
+ @values = []
10
+ end
11
+
12
+ def set_values(values)
13
+ @values = values
14
+ end
15
+
16
+ def put(index,value)
17
+ @values[index] = value
18
+ nil
19
+ end
20
+
21
+ def get(index)
22
+ @values[index]
23
+ end
24
+
25
+ def fill_with_nils
26
+ @values.fill(nil)
27
+ nil
28
+ end
29
+
30
+ def fill(value, range)
31
+ @values.fill(value,range)
32
+ nil
33
+ end
34
+
35
+ def raw
36
+ @values
37
+ end
38
+
39
+ def start_at(position)
40
+ @values[position..@values.size] + @values[0...position]
41
+ end
42
+
43
+ end
44
+ end
45
+ end