gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/datax/modifyx2/modify-array.go (about)

     1  package modifyx
     2  
     3  import (
     4  	"gitee.com/zhongguo168a/gocodes/datax/convertx"
     5  	"strconv"
     6  )
     7  
     8  func newArray() (obj *Array) {
     9  	obj = &Array{}
    10  	obj.disablePoolField = []bool{}
    11  	return
    12  }
    13  
    14  // 修正对象
    15  // 如果需要在运行时,替换源的数据,可通过设置runtime实现
    16  type Array struct {
    17  	source *Source
    18  	// 字段的路径
    19  	path string
    20  	// 在父对象中的字段名字
    21  	field string
    22  	// 父数据
    23  	parent map[string]interface{}
    24  	// 缓存的map/array/struct等对象, 避免重复创建对象
    25  	temps []interface{}
    26  	//
    27  	creator func(obj IObject) IObject
    28  	// 当前修正对象指向的源数据
    29  	sourceData []interface{}
    30  	// 运行时设置的数据
    31  	runtime []interface{}
    32  	// 最终的数据, 采用不同类型的原因是,初始值
    33  	ints    []int
    34  	uints   []uint
    35  	floats  []float64
    36  	strings []string
    37  	bools   []bool
    38  	// 需要使用修正池修正的字段
    39  	// 用于性能优化,避免进入修正池流程。
    40  	disablePoolField []bool
    41  	//
    42  	disabelPool bool
    43  }
    44  
    45  func (s *Array) initData() {
    46  	s.ints = make([]int, len(s.sourceData), len(s.sourceData))
    47  	s.uints = make([]uint, len(s.sourceData), len(s.sourceData))
    48  	s.floats = make([]float64, len(s.sourceData), len(s.sourceData))
    49  	s.strings = make([]string, len(s.sourceData), len(s.sourceData))
    50  	s.bools = make([]bool, len(s.sourceData), len(s.sourceData))
    51  	s.temps = make([]interface{}, len(s.sourceData), len(s.sourceData))
    52  	s.disablePoolField = make([]bool, len(s.sourceData), len(s.sourceData))
    53  
    54  	for key, val := range s.sourceData {
    55  		switch v := val.(type) {
    56  		case int:
    57  			s.ints[key] = v
    58  		case uint:
    59  			s.uints[key] = v
    60  		case float64:
    61  			s.floats[key] = v
    62  		case bool:
    63  			s.bools[key] = v
    64  		case string:
    65  			s.strings[key] = v
    66  		}
    67  	}
    68  }
    69  
    70  func (s *Array) Dispose() {
    71  	s.sourceData = nil
    72  	s.ints = nil
    73  	s.floats = nil
    74  	s.strings = nil
    75  	s.bools = nil
    76  	s.parent = nil
    77  	s.temps = nil
    78  	s.source = nil
    79  }
    80  
    81  func (s *Array) getOriginBool(field int) bool {
    82  	// 运行时
    83  	if s.runtime != nil {
    84  		if rval := s.runtime[field]; rval != nil {
    85  			return rval.(bool)
    86  		}
    87  	}
    88  
    89  	return convertx.AnyToBool(s.sourceData[field])
    90  }
    91  
    92  func (s *Array) getOriginFloat(field int) float64 {
    93  	// 运行时
    94  	if s.runtime != nil {
    95  		if rval := s.runtime[field]; rval != nil {
    96  			return rval.(float64)
    97  		}
    98  	}
    99  
   100  	return convertx.AnyToFloat64(s.sourceData[field])
   101  }
   102  func (s *Array) getOriginInt(field int) int {
   103  	// 运行时
   104  	if s.runtime != nil {
   105  		if rval := s.runtime[field]; rval != nil {
   106  			return rval.(int)
   107  		}
   108  	}
   109  	return convertx.AnyToInt(s.sourceData[field])
   110  }
   111  
   112  // 修正后的整型
   113  func (s *Array) RefInt(field int) int {
   114  	origin := s.getOriginInt(field)
   115  	s.ints[field] = origin
   116  	// 池修正
   117  	if !s.disabelPool {
   118  		if !s.disablePoolField[field] {
   119  			pools := s.source.pools
   120  			if pools != nil {
   121  				lastkey := s.path + "/" + strconv.Itoa(field)
   122  				if pools.IsPropChanged(lastkey) {
   123  					// 更新属性
   124  					s.ints[field] = pools.GetNewPropInt(lastkey, origin)
   125  				}
   126  			}
   127  		}
   128  	}
   129  
   130  	return s.ints[field]
   131  }
   132  
   133  // 修正后的整型
   134  func (s *Array) RefBool(field int) bool {
   135  	origin := s.getOriginBool(field)
   136  	s.bools[field] = origin
   137  	// 池修正
   138  	if !s.disabelPool {
   139  		if !s.disablePoolField[field] {
   140  			pools := s.source.pools
   141  			if pools != nil {
   142  				lastkey := s.path + "/" + strconv.Itoa(field)
   143  				if pools.IsPropChanged(lastkey) {
   144  					// 更新属性
   145  					s.bools[field] = pools.GetNewPropBool(lastkey, origin)
   146  				}
   147  			}
   148  		}
   149  	}
   150  
   151  	return s.bools[field]
   152  
   153  }
   154  
   155  // 修正后的浮点型
   156  func (s *Array) RefFloat(field int) float64 {
   157  	origin := s.getOriginFloat(field)
   158  	s.floats[field] = origin
   159  	// 池修正
   160  	if !s.disabelPool {
   161  		if !s.disablePoolField[field] {
   162  			pools := s.source.pools
   163  			if pools != nil {
   164  				lastkey := s.path + "/" + strconv.Itoa(field)
   165  				if pools.IsPropChanged(lastkey) {
   166  					// 更新属性
   167  					s.floats[field] = pools.GetNewPropFloat(lastkey, origin)
   168  				}
   169  			}
   170  		}
   171  	}
   172  
   173  	return s.floats[field]
   174  }
   175  
   176  // 获取原始数据
   177  func (s *Array) RefSourceData() []interface{} {
   178  	return s.sourceData
   179  }
   180  
   181  func (s *Array) RefUint(index int) (val uint) {
   182  	return uint(s.RefInt(index))
   183  }
   184  
   185  func (s *Array) RefString(index int) (val string) {
   186  	return s.strings[index]
   187  }
   188  
   189  func (s *Array) RefObject(index int) (r IObject) {
   190  	iobj := s.temps[index]
   191  	if iobj == nil {
   192  		obj := newObject()
   193  		obj.source = s.source
   194  		obj.field = strconv.Itoa(index)
   195  		obj.path = s.path + "/" + obj.field
   196  		obj.temps = map[string]interface{}{}
   197  		//
   198  		m := s.sourceData[index]
   199  		if m != nil {
   200  			obj.sourceData = m.(map[string]interface{})
   201  			obj.initData()
   202  		}
   203  
   204  		creator := s.creator
   205  		if creator != nil {
   206  			iobj = creator(obj)
   207  		} else {
   208  			iobj = obj
   209  		}
   210  
   211  		s.temps[index] = iobj
   212  	}
   213  
   214  	r = iobj.(IObject)
   215  	return
   216  }
   217  
   218  func (s *Array) RefLength() int {
   219  	return len(s.sourceData)
   220  }