Skip to content

Commit b9223b3

Browse files
author
Kylo Ginsberg
committed
Merge pull request #191 from hlindberg/HI-239-cherry-pick-speedup-from-master
(HI-239) Cherry pick speedup from master (from #22142)
2 parents 72d7961 + 37bb93b commit b9223b3

File tree

3 files changed

+49
-68
lines changed

3 files changed

+49
-68
lines changed

lib/hiera/backend.rb

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,19 @@ def datadir(backend, scope)
3434
#
3535
# If the file is not found nil is returned
3636
def datafile(backend, scope, source, extension)
37-
file = File.join([datadir(backend, scope), "#{source}.#{extension}"])
37+
datafile_in(datadir(backend, scope), source, extension)
38+
end
3839

39-
unless File.exist?(file)
40-
Hiera.debug("Cannot find datafile #{file}, skipping")
40+
# @api private
41+
def datafile_in(datadir, source, extension)
42+
file = File.join(datadir, "#{source}.#{extension}")
4143

42-
return nil
44+
if File.exist?(file)
45+
file
46+
else
47+
Hiera.debug("Cannot find datafile #{file}, skipping")
48+
nil
4349
end
44-
45-
return file
4650
end
4751

4852
# Constructs a list of data sources to search
@@ -73,6 +77,35 @@ def datasources(scope, override=nil, hierarchy=nil)
7377
end
7478
end
7579

80+
# Constructs a list of data files to search
81+
#
82+
# If you give it a specific hierarchy it will just use that
83+
# else it will use the global configured one, failing that
84+
# it will just look in the 'common' data source.
85+
#
86+
# An override can be supplied that will be pre-pended to the
87+
# hierarchy.
88+
#
89+
# The source names will be subject to variable expansion based
90+
# on scope
91+
#
92+
# Only files that exist will be returned. If the file is missing, then
93+
# the block will not receive the file.
94+
#
95+
# @yield [String, String] the source string and the name of the resulting file
96+
# @api public
97+
def datasourcefiles(backend, scope, extension, override=nil, hierarchy=nil)
98+
datadir = Backend.datadir(backend, scope)
99+
Backend.datasources(scope, override, hierarchy) do |source|
100+
Hiera.debug("Looking for data source #{source}")
101+
file = datafile_in(datadir, source, extension)
102+
103+
if file
104+
yield source, file
105+
end
106+
end
107+
end
108+
76109
# Parse a string like <code>'%{foo}'</code> against a supplied
77110
# scope and additional scope. If either scope or
78111
# extra_scope includes the variable 'foo', then it will

lib/hiera/backend/yaml_backend.rb

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,7 @@ def lookup(key, scope, order_override, resolution_type)
1313

1414
Hiera.debug("Looking up #{key} in YAML backend")
1515

16-
Backend.datasources(scope, order_override) do |source|
17-
Hiera.debug("Looking for data source #{source}")
18-
yamlfile = Backend.datafile(:yaml, scope, source, "yaml") || next
19-
20-
next unless file_exists?(yamlfile)
21-
16+
Backend.datasourcefiles(:yaml, scope, "yaml", order_override) do |source, yamlfile|
2217
data = @cache.read_file(yamlfile, Hash) do |data|
2318
YAML.load(data) || {}
2419
end

spec/unit/backend/yaml_backend_spec.rb

Lines changed: 9 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -37,38 +37,16 @@ def read_file(path, expected_type, &block)
3737
end
3838

3939
describe "#lookup" do
40-
it "should look for data in all sources" do
41-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
42-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns(nil)
43-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns(nil)
44-
45-
@backend.lookup("key", {}, nil, :priority)
46-
end
47-
4840
it "should pick data earliest source that has it for priority searches" do
49-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
50-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
51-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns(nil).never
52-
53-
@backend.stubs(:file_exists?).with("/nonexisting/one.yaml").returns(true)
41+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).yields(["one", "/nonexisting/one.yaml"])
5442
@cache.value = "---\nkey: answer"
5543

5644
@backend.lookup("key", {}, nil, :priority).should == "answer"
5745
end
5846

59-
it "should not look up missing data files" do
60-
Backend.expects(:datasources).multiple_yields(["one"])
61-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns(nil)
62-
YAML.expects(:load_file).never
63-
64-
@backend.lookup("key", {}, nil, :priority)
65-
end
66-
6747
describe "handling unexpected YAML values" do
6848
before do
69-
Backend.expects(:datasources).multiple_yields(["one"])
70-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
71-
@backend.stubs(:file_exists?).with("/nonexisting/one.yaml").returns(true)
49+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).yields(["one", "/nonexisting/one.yaml"])
7250
end
7351

7452
it "returns nil when the YAML value is nil" do
@@ -88,24 +66,15 @@ def read_file(path, expected_type, &block)
8866
end
8967

9068
it "should build an array of all data sources for array searches" do
91-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
92-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
93-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
94-
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
95-
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
96-
69+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
9770
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"answer"})
9871
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>"answer"})
9972

10073
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
10174
end
10275

10376
it "should ignore empty hash of data sources for hash searches" do
104-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
105-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
106-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
107-
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
108-
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
77+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
10978

11079
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({})
11180
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
@@ -114,11 +83,7 @@ def read_file(path, expected_type, &block)
11483
end
11584

11685
it "should build a merged hash of data sources for hash searches" do
117-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
118-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
119-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
120-
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
121-
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
86+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
12287

12388
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
12489
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"b"=>"answer", "a"=>"wrong"}})
@@ -127,11 +92,7 @@ def read_file(path, expected_type, &block)
12792
end
12893

12994
it "should fail when trying to << a Hash" do
130-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
131-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
132-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
133-
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
134-
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
95+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
13596

13697
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>["a", "answer"]})
13798
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
@@ -140,11 +101,7 @@ def read_file(path, expected_type, &block)
140101
end
141102

142103
it "should fail when trying to merge an Array" do
143-
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
144-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
145-
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
146-
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
147-
File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
104+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"], ["two", "/nonexisting/two.yaml"])
148105

149106
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>{"a"=>"answer"}})
150107
@cache.expects(:read_file).with("/nonexisting/two.yaml", Hash).returns({"key"=>["a", "wrong"]})
@@ -153,19 +110,15 @@ def read_file(path, expected_type, &block)
153110
end
154111

155112
it "should parse the answer for scope variables" do
156-
Backend.expects(:datasources).yields("one")
157-
Backend.expects(:datafile).with(:yaml, {"rspec" => "test"}, "one", "yaml").returns("/nonexisting/one.yaml")
158-
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
113+
Backend.expects(:datasourcefiles).with(:yaml, {"rspec" => "test"}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"])
159114

160115
@cache.expects(:read_file).with("/nonexisting/one.yaml", Hash).returns({"key"=>"test_%{rspec}"})
161116

162117
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
163118
end
164119

165120
it "should retain datatypes found in yaml files" do
166-
Backend.expects(:datasources).yields("one").times(3)
167-
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml").times(3)
168-
File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
121+
Backend.expects(:datasourcefiles).with(:yaml, {}, "yaml", nil).multiple_yields(["one", "/nonexisting/one.yaml"]).times(3)
169122

170123

171124
@cache.value = "---\nstringval: 'string'\nboolval: true\nnumericval: 1"

0 commit comments

Comments
 (0)