Directory Value: Make `isArrayParent` faster
This commit closes
@@ -154,6 +154,40 @@ CppKey convertToDirectChild (CppKey const & parent, CppKey const & child)
return directChild;
}
+/**
+ * @brief This function checks if `element` is an array element of `parent`.
+ *
+ * @pre The key `child` must be below `parent`.
+ *
+ * @param parent This parameter specifies a parent key.
+ * @param keys This variable stores a direct or indirect child of `parent`.
+ *
+ * @retval true If `element` is an array element
+ * @retval false Otherwise
+ */
+bool inline isArrayElementOf (CppKey const & parent, CppKey const & child)
+{
+ char const * relative = elektraKeyGetRelativeName (*child, *parent);
+ if (relative[0] != '#') return false;
+ relative++; // Skip leading `#`
+ size_t underscores = 0;
+ while (relative[underscores] == '_')
+ {
+ underscores++;
+ }
+ relative = &relative[underscores]; // Skip underscores
+ // Check index
+ for (size_t digit = 0; digit <= underscores; digit++)
+ {
+ if (relative[digit] < '0' || relative[digit] > '9') return false;
+ }
+ relative = &relative[underscores + 1]; // Skip index
+ // The next character has to be the separation char (`/`) or end of string
+ if (relative[0] != '\0' && relative[0] != '/') return false;
+
+ return true;
+}
+
/**
* @brief This function determines if the given key is an array parent.
*
@@ -168,9 +202,7 @@ bool isArrayParent (CppKey const & parent, CppKeySet const & keys)
for (auto const & key : keys)
{
if (!key.isBelow (parent)) continue;
-
- CppKey directChild = convertToDirectChild (parent, key);
- if (elektraArrayValidateName (*directChild) < 0) return false;
+ if (!isArrayElementOf (parent, key)) return false;
}
return true;
