public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Carsey, Jaben" <jaben.carsey@intel.com>
To: "Feng, Bob C" <bob.c.feng@intel.com>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Cc: "Gao, Liming" <liming.gao@intel.com>
Subject: Re: [Patch] BaseTools: Customize deepcopy function.
Date: Thu, 8 Nov 2018 15:22:45 +0000	[thread overview]
Message-ID: <CB6E33457884FA40993F35157061515CA713EE4A@fmsmsx101.amr.corp.intel.com> (raw)
In-Reply-To: <20181108060338.40404-1-bob.c.feng@intel.com>

Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> BobCF
> Sent: Wednesday, November 07, 2018 10:04 PM
> To: edk2-devel@lists.01.org
> Cc: Carsey, Jaben <jaben.carsey@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Subject: [edk2] [Patch] BaseTools: Customize deepcopy function.
> Importance: High
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=1288
> 
> This patch is one of build tool performance improvement
> series patches.
> 
> This patch is going to customize the deepcopy function for
> SkuClass, PcdClassObject and python dictionary.
> 
> python deepcopy copy everything of a object, but for our current
> usage we just need to copy the data we care about recursively.
> 
> By implementing __deepcopy__ for SkuClass, PcdClassObject, we can
> customize
> deepcopy function for them.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: BobCF <bob.c.feng@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Jaben Carsey <jaben.carsey@intel.com>
> ---
>  BaseTools/Source/Python/Common/Expression.py  |  4 +-
>  BaseTools/Source/Python/Common/Misc.py        | 16 ++++++
>  .../Python/CommonDataClass/CommonClass.py     | 15 ++++++
>  .../Python/Workspace/BuildClassObject.py      | 52 +++++++++++++++++++
>  .../Source/Python/Workspace/DscBuildData.py   |  6 +--
>  5 files changed, 88 insertions(+), 5 deletions(-)
> 
> diff --git a/BaseTools/Source/Python/Common/Expression.py
> b/BaseTools/Source/Python/Common/Expression.py
> index a21ab5daa7..091c0f4296 100644
> --- a/BaseTools/Source/Python/Common/Expression.py
> +++ b/BaseTools/Source/Python/Common/Expression.py
> @@ -15,11 +15,11 @@
>  from __future__ import print_function
>  from __future__ import absolute_import
>  from Common.GlobalData import *
>  from CommonDataClass.Exceptions import BadExpression
>  from CommonDataClass.Exceptions import WrnExpression
> -from .Misc import GuidStringToGuidStructureString, ParseFieldValue
> +from .Misc import GuidStringToGuidStructureString,
> ParseFieldValue,CopyDict
>  import Common.EdkLogger as EdkLogger
>  import copy
>  from Common.DataType import *
>  import sys
>  from random import sample
> @@ -353,11 +353,11 @@ class ValueExpression(BaseExpression):
>              raise BadExpression(ERR_EMPTY_EXPR)
> 
>          #
>          # The symbol table including PCD and macro mapping
>          #
> -        self._Symb = copy.deepcopy(SymbolTable)
> +        self._Symb = CopyDict(SymbolTable)
>          self._Symb.update(self.LogicalOperators)
>          self._Idx = 0
>          self._Len = len(self._Expr)
>          self._Token = ''
>          self._WarnExcept = None
> diff --git a/BaseTools/Source/Python/Common/Misc.py
> b/BaseTools/Source/Python/Common/Misc.py
> index 3b8efb2e71..80236db160 100644
> --- a/BaseTools/Source/Python/Common/Misc.py
> +++ b/BaseTools/Source/Python/Common/Misc.py
> @@ -39,10 +39,11 @@ from Common.LongFilePathSupport import
> OpenLongFilePath as open
>  from Common.MultipleWorkspace import MultipleWorkspace as mws
>  import uuid
>  from CommonDataClass.Exceptions import BadExpression
>  from Common.caching import cached_property
>  import subprocess
> +from collections import OrderedDict
>  ## Regular expression used to find out place holders in string template
>  gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE |
> re.UNICODE)
> 
>  ## regular expressions for map file processing
>  startPatternGeneral = re.compile("^Start[' ']+Length[' ']+Name[' ']+Class")
> @@ -2129,10 +2130,25 @@ def PackByteFormatGUID(Guid):
>                  Guid[8],
>                  Guid[9],
>                  Guid[10],
>                  )
> 
> +## DeepCopy dict/OrderedDict recusively
> +#
> +#   @param      ori_dict    a nested dict or ordereddict
> +#
> +#   @retval     new dict or orderdict
> +#
> +def CopyDict(ori_dict):
> +    dict_type = ori_dict.__class__
> +    new_dict = dict_type()
> +    for key in ori_dict:
> +        if isinstance(ori_dict[key],(dict,OrderedDict)):
> +            new_dict[key] = CopyDict(ori_dict[key])
> +        else:
> +            new_dict[key] = ori_dict[key]
> +    return new_dict
>  ##
>  #
>  # This acts like the main() function for the script, unless it is 'import'ed into
> another
>  # script.
>  #
> diff --git a/BaseTools/Source/Python/CommonDataClass/CommonClass.py
> b/BaseTools/Source/Python/CommonDataClass/CommonClass.py
> index a98cf8a7c5..336bb11671 100644
> --- a/BaseTools/Source/Python/CommonDataClass/CommonClass.py
> +++ b/BaseTools/Source/Python/CommonDataClass/CommonClass.py
> @@ -78,5 +78,20 @@ class SkuInfoClass(object):
>                      'VariableOffset = ' + str(self.VariableOffset) + "," + \
>                      'HiiDefaultValue = ' + str(self.HiiDefaultValue) + "," + \
>                      'VpdOffset = ' + str(self.VpdOffset) + "," + \
>                      'DefaultValue = ' + str(self.DefaultValue) + ","
>          return Rtn
> +
> +    def __deepcopy__(self,memo):
> +        new_sku = SkuInfoClass()
> +        new_sku.SkuIdName = self.SkuIdName
> +        new_sku.SkuId = self.SkuId
> +        new_sku.VariableName = self.VariableName
> +        new_sku.VariableGuid = self.VariableGuid
> +        new_sku.VariableGuidValue = self.VariableGuidValue
> +        new_sku.VariableOffset = self.VariableOffset
> +        new_sku.HiiDefaultValue = self.HiiDefaultValue
> +        new_sku.VariableAttribute = self.VariableAttribute
> +        new_sku.DefaultStoreDict = {key:value for key,value in
> self.DefaultStoreDict.items()}
> +        new_sku.VpdOffset = self.VpdOffset
> +        new_sku.DefaultValue = self.DefaultValue
> +        return new_sku
> diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> index 95edc376fe..7d10391c1e 100644
> --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> @@ -14,10 +14,12 @@
>  from collections import OrderedDict, namedtuple
>  from Common.DataType import *
>  import collections
>  import re
>  from collections import OrderedDict
> +from Common.Misc import CopyDict
> +import copy
>  StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_\[\]]*$')
>  ArrayIndex = re.compile("\[\s*\d{0,1}\s*\]")
>  ## PcdClassObject
>  #
>  # This Class is used for PcdObject
> @@ -152,10 +154,41 @@ class PcdClassObject(object):
>      # @retval truple() Key for hash table
>      #
>      def __hash__(self):
>          return hash((self.TokenCName, self.TokenSpaceGuidCName))
> 
> +    def sharedcopy(self,new_pcd):
> +        new_pcd.TokenCName = self.TokenCName
> +        new_pcd.TokenSpaceGuidCName = self.TokenSpaceGuidCName
> +        new_pcd.TokenSpaceGuidValue = self.TokenSpaceGuidValue
> +        new_pcd.Type = self.Type
> +        new_pcd.DatumType = self.DatumType
> +        new_pcd.DefaultValue = self.DefaultValue
> +        new_pcd.TokenValue = self.TokenValue
> +        new_pcd.MaxDatumSize = self.MaxDatumSize
> +
> +        new_pcd.Phase = self.Phase
> +        new_pcd.Pending = self.Pending
> +        new_pcd.IsOverrided = self.IsOverrided
> +        new_pcd.IsFromBinaryInf = self.IsFromBinaryInf
> +        new_pcd.IsFromDsc = self.IsFromDsc
> +        new_pcd.PcdValueFromComm = self.PcdValueFromComm
> +        new_pcd.PcdValueFromFdf = self.PcdValueFromFdf
> +        new_pcd.UserDefinedDefaultStoresFlag =
> self.UserDefinedDefaultStoresFlag
> +        new_pcd.DscRawValue = self.DscRawValue
> +        new_pcd.CustomAttribute = self.CustomAttribute
> +        new_pcd.validateranges = [item for item in self.validateranges]
> +        new_pcd.validlists = [item for item in self.validlists]
> +        new_pcd.expressions = [item for item in self.expressions]
> +        new_pcd.SkuInfoList = {key: copy.deepcopy(skuobj) for key,skuobj in
> self.SkuInfoList.items()}
> +        return new_pcd
> +
> +    def __deepcopy__(self,memo):
> +        new_pcd = PcdClassObject()
> +        self.sharedcopy(new_pcd)
> +        return new_pcd
> +
>  class StructurePcd(PcdClassObject):
>      def __init__(self, StructuredPcdIncludeFile=None, Packages=None,
> Name=None, Guid=None, Type=None, DatumType=None, Value=None,
> Token=None, MaxDatumSize=None, SkuInfoList=None, IsOverrided=False,
> GuidValue=None, validateranges=None, validlists=None,
> expressions=None,default_store = TAB_DEFAULT_STORES_DEFAULT):
>          if SkuInfoList is None:
>              SkuInfoList = {}
>          if validateranges is None:
> @@ -240,10 +273,29 @@ class StructurePcd(PcdClassObject):
>              self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else
> self.PkgPath
>              self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else
> self.ValueChain
>              self.PcdFieldValueFromComm = PcdObject.PcdFieldValueFromComm
> if PcdObject.PcdFieldValueFromComm else self.PcdFieldValueFromComm
>              self.PcdFieldValueFromFdf = PcdObject.PcdFieldValueFromFdf if
> PcdObject.PcdFieldValueFromFdf else self.PcdFieldValueFromFdf
> 
> +    def __deepcopy__(self,memo):
> +        new_pcd = StructurePcd()
> +        self.sharedcopy(new_pcd)
> +
> +        new_pcd.DefaultValueFromDec = self.DefaultValueFromDec
> +        new_pcd.PcdMode = self.PcdMode
> +        new_pcd.StructName = self.DatumType
> +        new_pcd.PcdDefineLineNo = self.PcdDefineLineNo
> +        new_pcd.PkgPath = self.PkgPath
> +        new_pcd.StructuredPcdIncludeFile = [item for item in
> self.StructuredPcdIncludeFile]
> +        new_pcd.PackageDecs = [item for item in self.PackageDecs]
> +        new_pcd.DefaultValues = CopyDict(self.DefaultValues)
> +        new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
> +        new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
> +        new_pcd.PcdFieldValueFromComm =
> CopyDict(self.PcdFieldValueFromComm)
> +        new_pcd.PcdFieldValueFromFdf =
> CopyDict(self.PcdFieldValueFromFdf)
> +        new_pcd.ValueChain = {item for item in self.ValueChain}
> +        return new_pcd
> +
>  LibraryClassObject = namedtuple('LibraryClassObject',
> ['LibraryClass','SupModList'], verbose=False)
> 
>  ## ModuleBuildClassObject
>  #
>  # This Class defines ModuleBuildClass
> diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
> b/BaseTools/Source/Python/Workspace/DscBuildData.py
> index 11aa63fb26..5655034b88 100644
> --- a/BaseTools/Source/Python/Workspace/DscBuildData.py
> +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
> @@ -970,11 +970,11 @@ class DscBuildData(PlatformBuildClassObject):
>              for skuid in pcd.SkuInfoList:
>                  skuobj = pcd.SkuInfoList.get(skuid)
>                  if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
>                      PcdDefaultStoreSet = set(defaultstorename  for defaultstorename
> in skuobj.DefaultStoreDict)
>                      mindefaultstorename =
> DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
> -                    skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] =
> copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
> +                    skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] =
> CopyDict(skuobj.DefaultStoreDict[mindefaultstorename])
>          return Pcds
> 
>      def RecoverCommandLinePcd(self):
>          def UpdateCommandLineValue(pcd):
>              if pcd.Type in
> [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
> @@ -1501,11 +1501,11 @@ class DscBuildData(PlatformBuildClassObject):
>                      PcdDefaultStoreSet = set(defaultstorename  for defaultstorename
> in stru_pcd.SkuOverrideValues[nextskuid])
>                      mindefaultstorename =
> DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
> 
>                      for defaultstoreid in DefaultStores:
>                          if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
> -                            stru_pcd.SkuOverrideValues[skuid][defaultstoreid] =
> copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorena
> me])
> +                            stru_pcd.SkuOverrideValues[skuid][defaultstoreid] =
> CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
>                              stru_pcd.ValueChain.add((skuid, defaultstoreid))
>          S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
>          S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
>          Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
>          if Str_Pcd_Values:
> @@ -2597,11 +2597,11 @@ class DscBuildData(PlatformBuildClassObject):
>                  for skuid in PcdObj.SkuInfoList:
>                      skuobj = PcdObj.SkuInfoList[skuid]
>                      mindefaultstorename =
> DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in
> skuobj.DefaultStoreDict))
>                      for defaultstorename in DefaultStores:
>                          if defaultstorename not in skuobj.DefaultStoreDict:
> -                            skuobj.DefaultStoreDict[defaultstorename] =
> copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
> +                            skuobj.DefaultStoreDict[defaultstorename] =
> CopyDict(skuobj.DefaultStoreDict[mindefaultstorename])
>                      skuobj.HiiDefaultValue =
> skuobj.DefaultStoreDict[mindefaultstorename]
>              for skuname, skuid in SkuIds.items():
>                  if skuname not in PcdObj.SkuInfoList:
>                      nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
>                      while nextskuid not in PcdObj.SkuInfoList:
> --
> 2.19.1.windows.1
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


      reply	other threads:[~2018-11-08 15:22 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-08  6:03 [Patch] BaseTools: Customize deepcopy function BobCF
2018-11-08 15:22 ` Carsey, Jaben [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CB6E33457884FA40993F35157061515CA713EE4A@fmsmsx101.amr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox