You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by gi...@apache.org on 2020/12/29 13:01:58 UTC
[buildstream] 08/27: _variables: Convert ValuePart to C struct
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch tristan/partial-variables-manual-string-join
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit c67fe08ff1cc9ff5b8203d0bb3742c39b801acb1
Author: Tristan van Berkom <tr...@codethink.co.uk>
AuthorDate: Thu Jul 2 03:45:07 2020 +0900
_variables: Convert ValuePart to C struct
---
src/buildstream/_variables.pyx | 100 ++++++++++++++++++++++++++---------------
1 file changed, 65 insertions(+), 35 deletions(-)
diff --git a/src/buildstream/_variables.pyx b/src/buildstream/_variables.pyx
index 245cbab..9512ab5 100644
--- a/src/buildstream/_variables.pyx
+++ b/src/buildstream/_variables.pyx
@@ -409,29 +409,6 @@ cdef class ResolutionStep:
detail="\n".join(reversed(error_lines)))
-# ValuePart()
-#
-# Represents a part of a value (a string and an indicator
-# of whether the string is a variable or not).
-#
-# This only exists for better performance than constructing
-# and unpacking tuples.
-#
-# Args:
-# text (str): The text of this part
-# is_variable (bint): True if the text is a variable, False if it's literal
-#
-cdef class ValuePart:
- cdef str text
- cdef bint is_variable
- cdef ValuePart next_part
-
- cdef init(self, str text, bint is_variable):
- self.text = text
- self.is_variable = is_variable
- self.next_part = None
-
-
cdef EMPTY_SET = set()
# Value():
@@ -474,7 +451,7 @@ cdef class Value:
cdef str resolve(self, dict values):
cdef str dep_name
cdef Value part_var
- cdef ValuePart part
+ cdef ValuePart *part
cdef object part_object
cdef list parts = []
@@ -483,10 +460,10 @@ cdef class Value:
while part:
if part.is_variable:
- part_var = <Value> values[part.text]
+ part_var = <Value> values[<str>part.text]
parts.append(part_var._resolved)
else:
- parts.append(part.text)
+ parts.append(<str>part.text)
part = part.next_part
@@ -564,7 +541,7 @@ cdef class ValueClass:
# Public
#
cdef set variable_names # A set of variable names
- cdef ValuePart parts # The linked list of ValuePart objects
+ cdef ValuePart *parts
# init():
#
@@ -574,10 +551,15 @@ cdef class ValueClass:
# string (str): The string which can contain variables
#
cdef init(self, str string):
+
self.variable_names = set()
- self.parts = None
+ self.parts = NULL
+
self._parse_string(string)
+ def __dealloc__(self):
+ free_value_parts(self.parts)
+
# _parse_string()
#
# Parse the string for this ValueClass, breaking it down into
@@ -604,19 +586,21 @@ cdef class ValueClass:
# What do you expect ? These are regular expressions after all,
# they are *supposed* to be weird.
#
- cdef list splits = VALUE_CLASS_PARSE_EXPANSION.split(string)
+ cdef splits = VALUE_CLASS_PARSE_EXPANSION.split(string)
cdef object split_object
cdef str split
cdef Py_ssize_t split_idx = 0
- cdef bint is_variable
- cdef ValuePart part
- cdef ValuePart last_part = None
+ cdef int is_variable
+
+ # Adding parts
+ #
+ cdef ValuePart *part
+ cdef ValuePart *last_part = NULL
#
# Collect the weird regex return value into something
# more comprehensible.
#
-
for split_object in splits:
split = <str> split_object
if split:
@@ -633,8 +617,7 @@ cdef class ValueClass:
is_variable = True
self.variable_names.add(split)
- part = ValuePart()
- part.init(split, is_variable)
+ part = new_value_part(split, is_variable)
if last_part:
last_part.next_part = part
else:
@@ -664,3 +647,50 @@ cdef class ValueIterator:
def __next__(self):
name = next(self._iter)
return name, self._variables[name]
+
+
+############################## BASEMENT ########################################
+
+
+from cpython.mem cimport PyMem_Malloc, PyMem_Free
+from cpython.object cimport PyObject
+from cpython.ref cimport Py_XINCREF, Py_XDECREF
+
+# ValuePart()
+#
+# Represents a part of a value (a string and an indicator
+# of whether the string is a variable or not).
+#
+# This only exists for better performance than constructing
+# and unpacking tuples.
+#
+# Args:
+# text (str): The text of this part
+# is_variable (bint): True if the text is a variable, False if it's literal
+#
+ctypedef struct ValuePart:
+ PyObject *text
+ int is_variable
+ ValuePart *next_part
+
+cdef ValuePart *new_value_part(str text, int is_variable):
+ cdef ValuePart *part = <ValuePart *>PyMem_Malloc(sizeof(ValuePart))
+ if not part:
+ raise MemoryError()
+
+ part.text = <PyObject *>text
+ part.is_variable = is_variable
+ part.next_part = NULL
+ Py_XINCREF(part.text)
+ return part
+
+cdef void free_value_part(ValuePart *part):
+ Py_XDECREF(part.text)
+ PyMem_Free(part)
+
+cdef void free_value_parts(ValuePart *part):
+ cdef ValuePart *to_free
+ while part:
+ to_free = part
+ part = part.next_part
+ free_value_part(to_free)