Module:Wd: Difference between revisions

Content deleted Content added
mNo edit summary
Sorting on rank upfront allows for simplified logic
Line 112:
stt.conf = cfg
stt.outPreferredresults = {}
stt.outNormal = {}
stt.outDeprecated = {}
stt.parsedFormat = {}
Line 517 ⟶ 515:
end
 
-- sorts the claims based on ranks, which is done to increase performance in certain cases;
-- e.g. with flags "normal+|best" given and claims stored in order "normal, normal, preferred",
-- then the "normal" claims would be fully processed first while the "preferred" one might be the only one returned;
-- after sorting, this would be "preferred, normal, normal" and the "normal" claims won't be processed
function sortOnRank(claims)
local rankPos
Line 1,185 ⟶ 1,179:
return matches, rankPos
end
 
function State:appendOutput(result, rankPos)
local done = false
-- a rankPos should only apply to complete claims, NOT to its individual qualifiers or references;
-- for the latter two, no rankPos should be given and their default rankPos must be the highest possible (i.e. 1)
if rankPos then
-- must NOT be reached when appending individual qualifiers or references
if self.conf.foundRank > rankPos then
self.conf.foundRank = rankPos -- must NOT be overwritten when appending individual qualifiers or references
if self.conf.bestRank or self.singleValue then
-- found a better rank, reset worse rank outputs
if self.conf.foundRank == 1 then
self.outNormal = {}
self.outDeprecated = {}
elseif self.conf.foundRank == 2 then
self.outDeprecated = {}
end
end
end
else
-- must be reached when appending individual qualifiers or references
rankPos = 1 -- must be the highest possible (i.e. 1)
end
if rankPos == 1 then
-- must always be reached when appending individual qualifiers or references
self.outPreferred[#self.outPreferred + 1] = result
if self.singleValue then
done = true
end
elseif rankPos == 2 then
self.outNormal[#self.outNormal + 1] = result
if self.singleValue and not self.conf.ranks[1] then
done = true
end
elseif rankPos == 3 then
self.outDeprecated[#self.outDeprecated + 1] = result
if self.singleValue and not self.conf.ranks[1] and not self.conf.ranks[2] then
done = true
end
end
return done
end
 
function State:out()
local result -- collection of arrays with value objects
local valuesArray -- array with value objects
local sep = ""
local out = {} -- array with value objects
Line 1,265 ⟶ 1,213:
end
-- iterate through the results from back to front, so that we know when to add separators
local function prepend(results)
for i = #self.results, 1, -1 do
local sep = ""
result = self.results[i]
local result -- collection of arrays with value objects
local valuesArray -- array with value objects
-- iterateif fromthere backis toalready frontsome output, sothen thatadd we know when to addthe separators
for i =if #results,out 1,> -10 dothen
sep = self.separator[1] -- fixed separator
result = results[i]
result[parameters.separator] = { {self.movSeparator[1]} } -- movable separator
else
-- if there is already some output, then add the separators
ifsep #out= > 0 then""
sepresult[parameters.separator] = { {self.separatorpuncMark[1]} } -- fixedoptional separatorpunctuation mark
end
result[parameters.separator] = { {self.movSeparator[1]} } -- movable separator
else
valuesArray = walk(self.parsedFormat, result)
sep = ""
result[parameters.separator] = { {self.puncMark[1]} } -- optional punctuation mark
if #valuesArray > 0 then
end
valuesArray[#valuesArray + 1] = {sep}
out = mergeTables(valuesArray, out)
valuesArray = walk(self.parsedFormat, result)
if #valuesArray > 0 then
valuesArray[#valuesArray + 1] = {sep}
out = mergeTables(valuesArray, out)
end
end
end
prepend(self.outDeprecated)
prepend(self.outNormal)
prepend(self.outPreferred)
-- reset state before next iteration
self.outDeprecatedresults = {}
self.outNormal = {}
self.outPreferred = {}
return out
Line 1,494 ⟶ 1,430:
matchHook = matchHook or alwaysTrue
local done = false
local matches = false
local rankPos = nil
local result, numValues, doAppend, gotRequired
for i, v in ipairs(statements) do
Line 1,506 ⟶ 1,441:
if matches then
result = {count = 0} -- collection of arrays with value objects
doAppend = true
local function walk(formatTable)
-- if we need to return a single value, check if we don't have one already
local miss
if self.singleValue then
if not rankPos or rankPos == 1 then
numValues = #self.outPreferred
elseif rankPos == 2 then
numValues = #self.outNormal
elseif rankPos == 3 then
numValues = #self.outDeprecated
end
for i2, v2 in pairs(formatTable.req) do
if numValues > 0 then
-- call a hook, adding its return value to the result
doAppend = false
miss = self:callHook(i2, hooks, v, result)
end
end
if doAppend then
local function walk(formatTable)
local miss
if miss then
for i2, v2 in pairs(formatTable.req) do
-- callwe miss a hook,required addingvalue itsfor returnthis valuelevel, toso thereturn resultfalse
return false
miss = self:callHook(i2, hooks, v, result)
if miss then
-- we miss a required value for this level, so return false
return false
end
if result.count == hooks.count then
-- we're done if all hooks have been called;
-- returning at this point breaks the loop
return true
end
end
if result.count == hooks.count then
for i2, v2 in ipairs(formatTable) do
if-- result.countwe're ==done if all hooks.count thenhave been called;
-- we'rereturning doneat ifthis allpoint hooksbreaks havethe been called;loop
return true
-- returning at this point prevents further childs from being processed
return trueend
end
for i2, v2 in ipairs(formatTable) do
if v2.child then
if result.count == hooks.count then
walk(v2.child)
-- we're done if all hooks have been called;
end
-- returning at this point prevents further childs from being processed
return true
end
returnif truev2.child then
walk(v2.child)
end
end
gotRequired = walk(self.parsedFormat)
return true
-- only append the result if we got values for all required parameters on the root level
end
if gotRequired then
gotRequired = walk(self.parsedFormat)
done = self:appendOutput(result, rankPos)
if done then
-- only append the result if we got values for all required parameters on the root level
break
if gotRequired then
end
-- if we have a rankPos (only with matchHook() for complete claims), then update the foundRank
if rankPos and self.conf.foundRank > rankPos then
self.conf.foundRank = rankPos
end
-- append the result
self.results[#self.results + 1] = result
-- break if we only need a single value
if self.singleValue then
break
end
end
Line 1,776 ⟶ 1,701:
if _.entity and _.entity.claims then claims = _.entity.claims[_.propertyID] end
if claims then
-- first sort the claims on ranksrank forto betterpre-define performancethe order of output (preferred first, then normal, then deprecated)
claims = sortOnRank(claims)