Skip to content

Commit ed284a9

Browse files
feat: Add LRU hash (#970)
1 parent 58ca7f7 commit ed284a9

7 files changed

Lines changed: 171 additions & 3 deletions

File tree

.github/workflows/ci-common.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ on:
77
branches:
88
- main
99
workflow_dispatch:
10+
11+
env:
12+
MT_COMPAT: true
13+
1014
jobs:
1115
CI:
1216
if: ${{ github.repository == 'googleapis/gapic-generator-ruby' }}

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ on:
99
- main
1010
workflow_dispatch:
1111

12+
env:
13+
MT_COMPAT: true
14+
15+
1216
jobs:
1317
tests:
1418
if: ${{ github.repository == 'googleapis/gapic-generator-ruby' }}

gapic-common/lib/gapic/generic_lro/operation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def initialize operation, client:, polling_method_name:, operation_status_field:
9090
#
9191
def results
9292
return error if error?
93-
return response if response?
93+
response if response?
9494
end
9595

9696
##

gapic-common/lib/gapic/lru_hash.rb

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module Gapic
16+
##
17+
# @private
18+
#
19+
# Linked list based hash maintaining the order of
20+
# access/creation of the keys.
21+
#
22+
class LruHash
23+
def initialize size = 1
24+
raise ArgumentError, "The size of LRU hash can't be < 1" unless size > 1
25+
@start = nil
26+
@end = nil
27+
@size = size
28+
@cache = {}
29+
end
30+
31+
def get key
32+
return nil unless @cache.key? key
33+
node = @cache[key]
34+
move_to_top node
35+
node.value
36+
end
37+
38+
def put key, value
39+
if @cache.key? key
40+
node = @cache[key]
41+
node.value = value
42+
move_to_top node
43+
else
44+
remove_tail if @cache.size >= @size
45+
new_node = Node.new key, value
46+
insert_at_top new_node
47+
@cache[key] = new_node
48+
end
49+
end
50+
51+
private
52+
53+
def move_to_top node
54+
return if node.equal? @start
55+
56+
if node.equal? @end
57+
@end = node.prev
58+
@end.next = nil
59+
else
60+
node.prev.next = node.next
61+
node.next.prev = node.prev
62+
end
63+
64+
node.prev = nil
65+
node.next = @start
66+
@start.prev = node
67+
@start = node
68+
end
69+
70+
def remove_tail
71+
@cache.delete @end.key
72+
@end = @end.prev
73+
@end.next = nil if @end
74+
end
75+
76+
def insert_at_top node
77+
if @start.nil?
78+
@start = node
79+
@end = node
80+
else
81+
node.next = @start
82+
@start.prev = node
83+
@start = node
84+
end
85+
end
86+
87+
##
88+
# @private
89+
#
90+
# Node class for linked list.
91+
#
92+
class Node
93+
attr_accessor :key
94+
attr_accessor :value
95+
attr_accessor :prev
96+
attr_accessor :next
97+
98+
def initialize key, value
99+
@key = key
100+
@value = value
101+
@prev = nil
102+
@next = nil
103+
end
104+
end
105+
end
106+
end

gapic-common/lib/gapic/operation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def initialize grpc_op, client, result_type: nil, metadata_type: nil, options: {
102102
# `Google::Rpc::Status` will be returned.
103103
def results
104104
return error if error?
105-
return response if response?
105+
response if response?
106106
end
107107

108108
##

gapic-common/lib/gapic/rest/grpc_transcoder.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def extract_scalar_value! request_hash, field_path, regex
218218

219219
# Covers the case where in `foo.bar.baz`, `baz` is still a submessage or an array.
220220
return nil if value.is_a?(::Hash) || value.is_a?(::Array)
221-
return value.to_s if value.to_s =~ regex
221+
value.to_s if value.to_s =~ regex
222222
end
223223

224224
# Finds a value in the hash by path.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require "test_helper"
16+
require "gapic/lru_hash"
17+
18+
##
19+
# Tests LRU hash class
20+
#
21+
class LruHashTest < Minitest::Test
22+
def test_hash_size_exceed
23+
lru_cache = Gapic::LruHash.new 3
24+
lru_cache.put 1, "one"
25+
lru_cache.put 2, "two"
26+
lru_cache.put 3, "three"
27+
lru_cache.put 4, "four"
28+
assert lru_cache.get(1).nil?
29+
assert_equal "four", lru_cache.get(4)
30+
end
31+
32+
def test_hash_size_value
33+
assert_raises ArgumentError do
34+
Gapic::LruHash.new 0
35+
end
36+
assert_raises ArgumentError do
37+
Gapic::LruHash.new(-1)
38+
end
39+
end
40+
41+
def test_hash_removes_lru_value
42+
lru_cache = Gapic::LruHash.new 3
43+
lru_cache.put 1, "one"
44+
lru_cache.put 2, "two"
45+
lru_cache.put 3, "three"
46+
lru_cache.get 3
47+
lru_cache.get 2
48+
lru_cache.get 1
49+
50+
lru_cache.put 4, "four"
51+
assert lru_cache.get(3).nil?
52+
assert_equal "four", lru_cache.get(4)
53+
end
54+
end

0 commit comments

Comments
 (0)