Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Module handling flags while doing stream parsing. | |
| 6 | |
| 7 ``ParsingFlag`` has name, a condition function which returns boolean predicate | |
|
wrengr
2016/12/28 23:34:09
"has name" -> "has a name"
"returns boolean predi
Sharu Jiang
2016/12/29 18:20:22
Done.
| |
| 8 and a boolean value. We call a flag with ``True`` value is ``on``, and a flag | |
|
wrengr
2016/12/28 23:34:10
"call a..." -> "We say that a flag with the boolea
Sharu Jiang
2016/12/29 18:20:21
Done.
| |
| 9 with ``False`` value is ``off``. | |
| 10 The condition function is used to check whether a flag should be turned ``on`` | |
|
wrengr
2016/12/28 23:34:09
should use "on" rather than ``on`` (ditto "off" ra
Sharu Jiang
2016/12/29 18:20:22
Done.
| |
| 11 while it is ``off``. | |
| 12 | |
| 13 ``FlagManager`` is a managing class of all the flags while doing stream parsing. | |
|
wrengr
2016/12/28 23:34:09
"managing class of" -> "class for managing"
Sharu Jiang
2016/12/29 18:20:21
Done.
| |
| 14 In order to get tracked in stream parsing, all flags must be registered in | |
|
wrengr
2016/12/28 23:34:10
"to get tracked in" -> "to be tracked during"
Sharu Jiang
2016/12/29 18:20:21
Done.
| |
| 15 ``FlagManager`` with a certain group (differentiate different namespaces). | |
| 16 | |
| 17 For example: | |
| 18 | |
| 19 | |
| 20 stacktrace = "blabla\nSUMMARY:\nblabla" | |
| 21 flag = ParsingFlag('after_summary_flag', lambda line: 'SUMMARY:' in line, | |
| 22 value=False) | |
| 23 flag_manager = FlagManager() | |
| 24 flag_manager.Register('stacktrace_group', flag) | |
| 25 | |
| 26 for line in stacktrace.splitlines(): | |
| 27 flag_manager.ConditionallyTurnOnFlags(line) | |
| 28 | |
| 29 | |
| 30 The ``after_summary_flag`` will be turned on (set the value to True) when | |
| 31 parsing the second line, because the initial value of the flag is ``False`` and | |
| 32 the condition function returns ``True`` for the second line. | |
| 33 | |
| 34 The flag will stay ``on``, until ``flag.Off()`` is called to set the value to | |
| 35 ``False`` explictly. | |
| 36 """ | |
| 37 | |
| 38 from collections import defaultdict | |
| 39 | |
| 40 | |
| 41 class ParsingFlag(object): | |
| 42 """Represents a flag in stream parsing. | |
| 43 | |
| 44 This object serves like a delegation to manipulate flag of obj, | |
|
wrengr
2016/12/28 23:34:10
"obj" -> "object"
Sharu Jiang
2016/12/29 18:20:22
Done.
| |
| 45 condition will be used to evaluate the flag value. | |
| 46 """ | |
| 47 def __init__(self, name, condition=None, value=False): | |
| 48 """ | |
| 49 Args: | |
| 50 name (str): Name of the flag. | |
| 51 condition (function): Funtion that takes str line as input and returns | |
| 52 boolean value indicating whether the flag should be turned on or not. | |
| 53 Note, the condition should only be checked when the flag is off. | |
|
wrengr
2016/12/28 23:34:09
The first sentence is ambiguous about the meaning
Sharu Jiang
2016/12/29 18:20:21
Done.
| |
| 54 value (bool): Initial value of the flag. | |
| 55 """ | |
| 56 self._name = name | |
| 57 self._condition = condition | |
| 58 self._value = value | |
| 59 | |
| 60 @property | |
| 61 def name(self): | |
| 62 return self._name | |
| 63 | |
| 64 @property | |
| 65 def value(self): | |
| 66 return self._value | |
| 67 | |
| 68 def On(self): | |
|
wrengr
2016/12/28 23:34:10
I'd call this ``TurnOn`` rather than just ``On``.
Sharu Jiang
2016/12/29 18:20:22
Ok... I just thought that flag is "on" and flag ma
| |
| 69 self._value = True | |
| 70 | |
| 71 def Off(self): | |
|
wrengr
2016/12/28 23:34:09
ditto
Sharu Jiang
2016/12/29 18:20:21
Done.
| |
| 72 self._value = False | |
| 73 | |
| 74 def __nonzero__(self): | |
| 75 return self._value | |
| 76 | |
| 77 __bool__ = __nonzero__ | |
| 78 | |
| 79 def ConditionallyTurnOn(self, line): | |
| 80 """When the flag is off, turns on it if conditions met.""" | |
| 81 if not self._value and self._condition and self._condition(line): | |
|
wrengr
2016/12/28 23:34:09
is there a reason to check ``bool(self._condition)
Sharu Jiang
2016/12/29 18:20:22
No, but I think the performance should be the same
wrengr
2016/12/29 19:56:25
Performance would be marginally better (since you
Sharu Jiang
2017/01/03 22:13:27
Will address this in another cl
| |
| 82 self.On() | |
| 83 | |
| 84 | |
| 85 class FlagManager(object): | |
| 86 """A manager to track all the registered flags. | |
| 87 | |
| 88 FlagManager collects and manages flags based on group names. FlagManager takes | |
| 89 care of manipulating flags during the stream parsing, including evaluating | |
| 90 based on the conditions of flags, and resetting flags. | |
| 91 | |
| 92 Note, flag manager only keeps distinct flags(with distinct flag name), one | |
|
wrengr
2016/12/28 23:34:10
", one" -> ", and one"
Sharu Jiang
2016/12/29 18:20:21
Done.
| |
| 93 flag cannot be registered with different groups. | |
|
wrengr
2016/12/28 23:34:09
"different" -> "multiple"
Sharu Jiang
2016/12/29 18:20:22
Done.
| |
| 94 """ | |
| 95 | |
| 96 def __init__(self): | |
| 97 self.flag_groups = defaultdict(list) | |
| 98 self.flags = {} | |
| 99 | |
| 100 def ClearFlags(self): | |
| 101 """Deletes all the flags.""" | |
| 102 self.flag_groups = defaultdict(list) | |
| 103 self.flags = {} | |
| 104 | |
| 105 def Register(self, group_name, flag): | |
| 106 """Registers a flag with a group. | |
| 107 | |
| 108 Flags under the same group should have the same scope. | |
| 109 For example, in stacktrace parsing, the scope of a flag like | |
| 110 ``after_sumary_line`` is the whole stacktrace, so it should be under | |
| 111 ``stacktrace_flags`` group, while the scope of | |
| 112 ``callstack_top_frame_has_no_symbol`` is callstack, and it should be | |
| 113 under ``callstack_flags`` group. | |
| 114 """ | |
| 115 self.flag_groups[group_name].append(flag) | |
| 116 self.flags[flag.name] = flag | |
| 117 | |
| 118 def GetAllFlags(self): | |
| 119 """Returns all registered flags.""" | |
| 120 return self.flags.values() | |
| 121 | |
| 122 def GetGroupFlags(self, group_name): | |
| 123 """Returns a certain group of flags.""" | |
| 124 return self.flag_groups.get(group_name, []) | |
| 125 | |
| 126 def ResetAllFlags(self): | |
| 127 """Turns off all registered flags.""" | |
| 128 for flag in self.GetAllFlags(): | |
| 129 flag.Off() | |
| 130 | |
| 131 def ResetGroupFlags(self, group_name): | |
| 132 """Turns off a certain group of flags.""" | |
| 133 for flag in self.GetGroupFlags(group_name): | |
| 134 flag.Off() | |
| 135 | |
| 136 def ConditionallyTurnOnFlags(self, line): | |
| 137 """Turns on flags which are off and the conditions are met by the line.""" | |
| 138 for flag in self.GetAllFlags(): | |
| 139 flag.ConditionallyTurnOn(line) | |
| 140 | |
| 141 def Get(self, flag_name): | |
| 142 """Gets the instance with flag_name.""" | |
| 143 return self.flags.get(flag_name) | |
| 144 | |
| 145 def TurnOn(self, flag_name): | |
| 146 """Sets the instance with flag_name to True.""" | |
| 147 flag = self.flags.get(flag_name) | |
| 148 if flag is None: | |
| 149 return | |
| 150 | |
| 151 flag.On() | |
| 152 | |
| 153 def TurnOff(self, flag_name): | |
| 154 """Sets the instance with flag_name to False.""" | |
| 155 flag = self.flags.get(flag_name) | |
| 156 if flag is None: | |
| 157 return | |
| 158 | |
| 159 flag.Off() | |
| OLD | NEW |