time_trap 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/timetrap.rb +20 -8
- data/spec/timetrap_spec.rb +64 -9
- data/time_trap.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2b8dc2516b7ae270ce33ab45bb0b872b50324c9
|
4
|
+
data.tar.gz: 01a073d6a79ff73dc07e5df36ec00bf1d30a3e89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f7a025cdfd2ad20c5c3fbd12ec3a76285fabd2fbf5c8167ced233f542756d08f15af3ee03254e4086c10690d787d973355b312c1eb314e1db20793b02430a34
|
7
|
+
data.tar.gz: b08617429e10da832b339eea6bb62e072d96f7164a187d825af5860205d3a118cd72764b9facd8a61822deccf3f24d4d99420a843bdb5b3b9c15d817e795c316
|
data/lib/timetrap.rb
CHANGED
@@ -18,9 +18,9 @@ class TimeTrap
|
|
18
18
|
end
|
19
19
|
|
20
20
|
# @param [Object] value key to retrieve.
|
21
|
-
# @return [
|
21
|
+
# @return [Hash] key = value, value = array of time entries. nil if missing
|
22
22
|
def get(value)
|
23
|
-
ret = @tt[value].nil? ? nil : @tt[value].queue
|
23
|
+
ret = @tt[value].nil? ? nil : {value => @tt[value].queue}
|
24
24
|
return ret
|
25
25
|
end
|
26
26
|
|
@@ -45,11 +45,16 @@ class TimeTrap
|
|
45
45
|
@tt.sort_by(&block)
|
46
46
|
end
|
47
47
|
|
48
|
-
# @param [Fixnum]
|
49
|
-
# @return [
|
48
|
+
# @param [Fixnum] number of entries to return
|
49
|
+
# @return [TimeTrap] TimeTrap consting of top values
|
50
50
|
def top(rank)
|
51
|
-
ret =
|
52
|
-
|
51
|
+
ret = TimeTrap.new
|
52
|
+
@tt.sort_by {|k,v| -v.count}.map{|k,v|
|
53
|
+
ret.set(k, v)
|
54
|
+
rank -= 1
|
55
|
+
break if rank <= 0
|
56
|
+
}
|
57
|
+
return ret
|
53
58
|
end
|
54
59
|
|
55
60
|
# @param [Fixnum] secs number of seconds before current time for window
|
@@ -75,10 +80,17 @@ class TimeTrap
|
|
75
80
|
# @param [FixNum] end_sec end of time frame
|
76
81
|
# @return [Hash] key = value added to TimeTrap, value = count of instances in the window
|
77
82
|
def window(start_sec, end_sec)
|
78
|
-
ret =
|
79
|
-
@tt.each {|k,v| ret
|
83
|
+
ret = TimeTrap.new
|
84
|
+
@tt.each {|k,v| ret.set(k, v.window(start_sec, end_sec)) if v.window(start_sec, end_sec).count > 0}
|
80
85
|
return ret
|
81
86
|
end
|
87
|
+
|
88
|
+
# allows direct set access to internal hash
|
89
|
+
# @param [Object] key value being tracked
|
90
|
+
#
|
91
|
+
def set(key, value)
|
92
|
+
@tt[key] = value
|
93
|
+
end
|
82
94
|
end
|
83
95
|
|
84
96
|
require 'timetrap/deque'
|
data/spec/timetrap_spec.rb
CHANGED
@@ -4,6 +4,12 @@ describe TimeTrap do
|
|
4
4
|
let(:ttrap) { TimeTrap.new }
|
5
5
|
|
6
6
|
context "#add" do
|
7
|
+
it "returns the time_added in seconds since epoch" do
|
8
|
+
t = Time.now.to_i
|
9
|
+
expect(ttrap.add("test_1")).to be_a(Fixnum)
|
10
|
+
expect(ttrap.add("test_1")).to eq(t)
|
11
|
+
end
|
12
|
+
|
7
13
|
it "allows values to be added" do
|
8
14
|
ttrap.add("test_1")
|
9
15
|
expect(ttrap.count).to eq(1)
|
@@ -12,32 +18,48 @@ describe TimeTrap do
|
|
12
18
|
it "allows values to be added with a timestamp" do
|
13
19
|
t = Time.now.to_i - 1000
|
14
20
|
ttrap.add("test_1", t)
|
15
|
-
expect(ttrap.get("test_1")).to match_array([t])
|
21
|
+
expect(ttrap.get("test_1")["test_1"]).to match_array([t])
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
19
25
|
context "#get" do
|
26
|
+
it "returns a hash" do
|
27
|
+
ttrap.add("test_1")
|
28
|
+
expect(ttrap.get("test_1")).to be_a(Hash)
|
29
|
+
end
|
30
|
+
|
20
31
|
it "allows retrieval of values" do
|
21
32
|
t = Time.now.to_i
|
22
33
|
ttrap.add("test_1", t)
|
23
|
-
expect(ttrap.get("test_1")).to match_array([t])
|
34
|
+
expect(ttrap.get("test_1")["test_1"]).to match_array([t])
|
24
35
|
end
|
25
|
-
|
36
|
+
|
26
37
|
it "returns nil for keys that haven't been added" do
|
27
38
|
expect(ttrap.get("test_1")).to be_nil
|
28
39
|
end
|
29
40
|
end
|
30
41
|
|
31
42
|
context "#count" do
|
43
|
+
it "returns a Fixnum" do
|
44
|
+
ttrap.add("test_1")
|
45
|
+
expect(ttrap.count).to be_a(Fixnum)
|
46
|
+
end
|
47
|
+
|
32
48
|
it "keeps count of objects added" do
|
33
49
|
time = ttrap.add("test_1")
|
34
50
|
expect(ttrap.count).to eq(1)
|
35
|
-
expect(ttrap.get("test_1").first).to eq(time)
|
36
|
-
expect(ttrap.get("test_1").last).to eq(time)
|
51
|
+
expect(ttrap.get("test_1")["test_1"].first).to eq(time)
|
52
|
+
expect(ttrap.get("test_1")["test_1"].last).to eq(time)
|
37
53
|
end
|
38
54
|
end
|
39
55
|
|
40
56
|
context "#has_key?" do
|
57
|
+
it "returns a bool" do
|
58
|
+
ttrap.add("test_1")
|
59
|
+
expect(ttrap.has_key?("test_1")).to be_a(TrueClass)
|
60
|
+
expect(ttrap.has_key?("test_2")).to be_a(FalseClass)
|
61
|
+
end
|
62
|
+
|
41
63
|
it "checks on added keys" do
|
42
64
|
ttrap.add("test_1")
|
43
65
|
expect(ttrap.has_key?("test_1")).to eq(true)
|
@@ -49,6 +71,11 @@ describe TimeTrap do
|
|
49
71
|
end
|
50
72
|
|
51
73
|
context "#keys" do
|
74
|
+
it "returns an array" do
|
75
|
+
ttrap.add("test_1")
|
76
|
+
expect(ttrap.keys).to be_an(Array)
|
77
|
+
end
|
78
|
+
|
52
79
|
it "returns array of added keys" do
|
53
80
|
ttrap.add("test_1")
|
54
81
|
ttrap.add("test_2")
|
@@ -57,6 +84,10 @@ describe TimeTrap do
|
|
57
84
|
end
|
58
85
|
|
59
86
|
context "#each" do
|
87
|
+
it "is an enumerator" do
|
88
|
+
expect(ttrap.each).to be_an(Enumerator)
|
89
|
+
end
|
90
|
+
|
60
91
|
it "allows block code to be run on each key" do
|
61
92
|
(1..3).each {|i| ttrap.add("test_#{i}")}
|
62
93
|
cnt = 0
|
@@ -66,6 +97,10 @@ describe TimeTrap do
|
|
66
97
|
end
|
67
98
|
|
68
99
|
context "#delete_if" do
|
100
|
+
it "is an enumerator" do
|
101
|
+
expect(ttrap.each).to be_an(Enumerator)
|
102
|
+
end
|
103
|
+
|
69
104
|
it "allows block code to be run on each key" do
|
70
105
|
(1..3).each {|i| ttrap.add("test_#{i}")}
|
71
106
|
ttrap.delete_if {|key, val| key == "test_1"}
|
@@ -74,6 +109,10 @@ describe TimeTrap do
|
|
74
109
|
end
|
75
110
|
|
76
111
|
context "#sort_by" do
|
112
|
+
it "is an enumerator" do
|
113
|
+
expect(ttrap.each).to be_an(Enumerator)
|
114
|
+
end
|
115
|
+
|
77
116
|
it "allows access to keys sorted by output of block code" do
|
78
117
|
(0..0).each {|i| ttrap.add("1")}
|
79
118
|
(0..1).each {|i| ttrap.add("2")}
|
@@ -86,30 +125,46 @@ describe TimeTrap do
|
|
86
125
|
end
|
87
126
|
|
88
127
|
context "#top" do
|
128
|
+
it "returns a TimeTrap" do
|
129
|
+
ttrap.add("test_1")
|
130
|
+
expect(ttrap.top(1)).to be_a(TimeTrap)
|
131
|
+
end
|
132
|
+
|
89
133
|
it "gives you the top values sorted by code block" do
|
90
134
|
(0..0).each {|i| ttrap.add("1")}
|
91
135
|
(0..1).each {|i| ttrap.add("2")}
|
92
136
|
(0..2).each {|i| ttrap.add("3")}
|
93
|
-
|
94
|
-
expect(
|
137
|
+
expect(ttrap.top(1).count).to eq(1)
|
138
|
+
expect(ttrap.top(1).get("3")["3"].count).to eq(3)
|
95
139
|
end
|
96
140
|
end
|
97
141
|
|
98
142
|
context "#window" do
|
143
|
+
it "returns a TimeTrap" do
|
144
|
+
t = Time.now.to_i
|
145
|
+
(0..9).each {|i| ttrap.add(i)}
|
146
|
+
expect(ttrap.window(t - 60, t)).to be_a(TimeTrap)
|
147
|
+
end
|
148
|
+
|
99
149
|
it "allows retrieves of key counts over a window of time" do
|
100
150
|
t = Time.now.to_i
|
101
151
|
(0..9).each {|i| ttrap.add(i)}
|
102
|
-
expect(ttrap.window(t - 60, t).
|
152
|
+
expect(ttrap.window(t - 60, t).count).to eq(10)
|
103
153
|
end
|
104
154
|
|
105
155
|
it "allows retrieves of key counts ignoring expired ones" do
|
106
156
|
t = Time.now.to_i
|
107
157
|
(0..9).each{|i| ttrap.add(i, t - 61)}
|
108
|
-
expect(ttrap.window(t - 60, t).
|
158
|
+
expect(ttrap.window(t - 60, t).count).to eq(0)
|
109
159
|
end
|
110
160
|
end
|
111
161
|
|
112
162
|
context "#last" do
|
163
|
+
it "returns a TimeTrap" do
|
164
|
+
ttrap.add("test_1")
|
165
|
+
expect(ttrap.last(60)).to be_a(TimeTrap)
|
166
|
+
end
|
167
|
+
|
113
168
|
it "gives last day's worth of data" do
|
114
169
|
t = Time.now.to_i
|
115
170
|
(0..9).each{|i| ttrap.add(i, t - 60*60*24 - 1)}
|
data/time_trap.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "time_trap"
|
7
|
-
spec.version = "0.
|
7
|
+
spec.version = "0.2.0"
|
8
8
|
spec.authors = ["Pat Farrell"]
|
9
9
|
spec.email = ["mr.patfarrell@gmail.com"]
|
10
10
|
spec.summary = %q{TimeTrap impelents a moving window data structure for keeping track of top-k things}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: time_trap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Farrell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|