|
@@ -18,11 +18,14 @@ import (
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
var (
|
|
|
Sysconfig map[string]interface{} //配置文件
|
|
|
mconf map[string]interface{} //mongodb配置信息
|
|
|
mgo *mongodb.MongodbSim //mongodb操作对象
|
|
|
-
|
|
|
+ siteMgo *mongodb.MongodbSim
|
|
|
//mgoTest *mongodb.MongodbSim //mongodb操作对象
|
|
|
|
|
|
extract string
|
|
@@ -31,18 +34,21 @@ var (
|
|
|
udpclient mu.UdpClient //udp对象
|
|
|
nextNode []map[string]interface{} //下节点数组
|
|
|
dupdays = 5 //初始化判重范围
|
|
|
- DM *datamap //判重数据
|
|
|
- lastid = "5da3f2c5a5cb26b9b79847fe"
|
|
|
+ DM *datamap //
|
|
|
+ HM *historymap //判重数据
|
|
|
+ lastid = "5d767728a5cb26b9b7748868"
|
|
|
//5da3f2c5a5cb26b9b79847fc
|
|
|
-
|
|
|
+ //ObjectId("5d767728a5cb26b9b7748868")
|
|
|
+ //5da3f2c5a5cb26b9b79847fe
|
|
|
//正则筛选相关
|
|
|
FilterRegTitle = regexp.MustCompile("^_$")
|
|
|
FilterRegTitle_1 = regexp.MustCompile("^_$")
|
|
|
FilterRegTitle_2 = regexp.MustCompile("^_$")
|
|
|
|
|
|
|
|
|
- siteArr []map[string]interface{} //站点
|
|
|
- inV_n int //无效数据数量
|
|
|
+
|
|
|
+
|
|
|
+ SiteMap map[string]interface{} //站点map
|
|
|
)
|
|
|
|
|
|
func init() {
|
|
@@ -51,7 +57,6 @@ func init() {
|
|
|
//172.17.145.163:27080
|
|
|
util.ReadConfig(&Sysconfig)
|
|
|
nextNode = util.ObjArrToMapArr(Sysconfig["nextNode"].([]interface{}))
|
|
|
- siteArr = util.ObjArrToMapArr(Sysconfig["site"].([]interface{}))
|
|
|
mconf = Sysconfig["mongodb"].(map[string]interface{})
|
|
|
|
|
|
mgo = &mongodb.MongodbSim{
|
|
@@ -65,12 +70,12 @@ func init() {
|
|
|
mgo.InitPool()
|
|
|
|
|
|
|
|
|
- //测试临时注释
|
|
|
+ //测试需临时注释
|
|
|
dupdays = util.IntAllDef(Sysconfig["dupdays"], 3)
|
|
|
//加载数据
|
|
|
DM = NewDatamap(dupdays, lastid)
|
|
|
- fmt.Println(DM.keys)
|
|
|
- fmt.Println(DM.data)
|
|
|
+ //fmt.Println(DM.keys)
|
|
|
+ //fmt.Println(DM.data)
|
|
|
FilterRegTitle = regexp.MustCompile(util.ObjToString(Sysconfig["specialwords"]))
|
|
|
FilterRegTitle_1 = regexp.MustCompile(util.ObjToString(Sysconfig["specialtitle_1"]))
|
|
|
FilterRegTitle_2 = regexp.MustCompile(util.ObjToString(Sysconfig["specialtitle_2"]))
|
|
@@ -78,15 +83,34 @@ func init() {
|
|
|
|
|
|
|
|
|
|
|
|
- //数据库
|
|
|
- //mongodb.InitMongodbPool(5, "192.168.3.207:27081", "")
|
|
|
+ //站点相关数据库
|
|
|
+ mongodb.InitMongodbPool(5, "192.168.3.207:27082", "")
|
|
|
|
|
|
- //mgoTest = &mongodb.MongodbSim{
|
|
|
- // MongodbAddr: "192.168.3.207:27081",
|
|
|
- // Size: 5,
|
|
|
- // DbName: "qfw",
|
|
|
- //}
|
|
|
- //mgoTest.InitPool()
|
|
|
+ siteMgo = &mongodb.MongodbSim{
|
|
|
+ MongodbAddr: "192.168.3.207:27082",
|
|
|
+ Size: 5,
|
|
|
+ DbName: "zhaolongyue",
|
|
|
+ }
|
|
|
+ siteMgo.InitPool()
|
|
|
+
|
|
|
+
|
|
|
+ SiteMap = make(map[string]interface{},0)
|
|
|
+
|
|
|
+ start := int(time.Now().Unix())
|
|
|
+ //站点配置
|
|
|
+ sess_site := siteMgo.GetMgoConn()
|
|
|
+ defer sess_site.Close()
|
|
|
+ res_site := sess_site.DB("zhaolongyue").C("site").Find(nil).Sort("_id").Iter()
|
|
|
+ for site_dict := make(map[string]interface{}); res_site.Next(&site_dict); {
|
|
|
+ data_map := map[string]string{
|
|
|
+ "area":util.ObjToString(site_dict["area"]),
|
|
|
+ "city":util.ObjToString(site_dict["city"]),
|
|
|
+ "district":util.ObjToString(site_dict["district"]),
|
|
|
+ }
|
|
|
+ SiteMap[site_dict["site"].(string)]= data_map
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Printf("用时:%d秒,%d个",int(time.Now().Unix())-start,len(SiteMap))
|
|
|
|
|
|
|
|
|
}
|
|
@@ -190,7 +214,7 @@ func mainTest() {
|
|
|
}
|
|
|
|
|
|
}
|
|
|
- //打印 1:0情况 66989
|
|
|
+ //打印 1:0情况 66989;
|
|
|
mm:=0
|
|
|
for _,v:=range arr1 {
|
|
|
mm++
|
|
@@ -224,6 +248,7 @@ func mainTest() {
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
+
|
|
|
go checkMapJob()
|
|
|
|
|
|
updport := Sysconfig["udpport"].(string)
|
|
@@ -247,9 +272,7 @@ func processUdpMsg(act byte, data []byte, ra *net.UDPAddr) {
|
|
|
} else if mapInfo != nil {
|
|
|
|
|
|
//更新流程
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ //go historyTask(data,mapInfo)
|
|
|
|
|
|
|
|
|
//判重流程
|
|
@@ -272,7 +295,6 @@ func processUdpMsg(act byte, data []byte, ra *net.UDPAddr) {
|
|
|
//开始判重程序
|
|
|
func task(data []byte, mapInfo map[string]interface{}) {
|
|
|
|
|
|
-
|
|
|
//
|
|
|
fmt.Println("开始判重")
|
|
|
defer util.Catch()
|
|
@@ -308,7 +330,6 @@ func task(data []byte, mapInfo map[string]interface{}) {
|
|
|
|
|
|
//是否为无效数据
|
|
|
if invalidData(info.buyer,info.projectname,info.projectcode) {
|
|
|
- inV_n++
|
|
|
mapLock.Lock()
|
|
|
updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
map[string]interface{}{
|
|
@@ -329,15 +350,15 @@ func task(data []byte, mapInfo map[string]interface{}) {
|
|
|
}else {
|
|
|
//判重原因 reason
|
|
|
// tmp["_id"] 对比id id原始id
|
|
|
+ mapLock.Lock()
|
|
|
b, source,reason := DM.check(info)
|
|
|
if b { //有重复,生成更新语句,更新抽取和更新招标
|
|
|
repeateN++
|
|
|
- mapLock.Lock()
|
|
|
-
|
|
|
var mergeArr []int64 //更改合并数组记录
|
|
|
var newData *Info //更换新的数据池数据
|
|
|
|
|
|
var id_map = map[string]interface{}{}
|
|
|
+ repeat_id := ""
|
|
|
//合并操作--评功权重打分-合并完替换原始数据池
|
|
|
basic_bool := basicDataScore(source,info)
|
|
|
if basic_bool {
|
|
@@ -345,48 +366,55 @@ func task(data []byte, mapInfo map[string]interface{}) {
|
|
|
newData,mergeArr= mergeDataFields(source,info)
|
|
|
DM.replaceSourceData(newData,source.id) //替换
|
|
|
id_map["_id"]= util.StringTOBsonId(source.id)
|
|
|
-
|
|
|
+ repeat_id = source.id
|
|
|
//对比的数据打判重标签
|
|
|
- updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
- map[string]interface{}{
|
|
|
- "_id": tmp["_id"],
|
|
|
- },
|
|
|
- map[string]interface{}{
|
|
|
- "$set": map[string]interface{}{
|
|
|
- "repeat": 1,
|
|
|
- "repeatid": source.id,
|
|
|
- },
|
|
|
- },
|
|
|
- })
|
|
|
-
|
|
|
-
|
|
|
+ //updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
+ // map[string]interface{}{
|
|
|
+ // "_id": tmp["_id"],
|
|
|
+ // },
|
|
|
+ // map[string]interface{}{
|
|
|
+ // "$set": map[string]interface{}{
|
|
|
+ // "repeat": 1,
|
|
|
+ // "repeatid": source.id,
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ //})
|
|
|
+ //if len(updateExtract) > 500 {
|
|
|
+ // mgo.UpdateBulk(extract, updateExtract...)
|
|
|
+ // updateExtract = [][]map[string]interface{}{}
|
|
|
+ //}
|
|
|
|
|
|
}else {
|
|
|
//已对比数据为标准 ,数据池的数据打判重标签
|
|
|
newData,mergeArr= mergeDataFields(info,source)
|
|
|
DM.replaceSourceData(newData,source.id)//替换
|
|
|
id_map["_id"]= util.StringTOBsonId(info.id)
|
|
|
-
|
|
|
+ repeat_id = info.id
|
|
|
//数据池的数据打判重标签
|
|
|
- updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
- map[string]interface{}{
|
|
|
- "_id": util.StringTOBsonId(source.id),
|
|
|
- },
|
|
|
- map[string]interface{}{
|
|
|
- "$set": map[string]interface{}{
|
|
|
- "repeat": 1,
|
|
|
- "repeatid": info.id,
|
|
|
- },
|
|
|
- },
|
|
|
- })
|
|
|
+ //updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
+ // map[string]interface{}{
|
|
|
+ // "_id": util.StringTOBsonId(source.id),
|
|
|
+ // },
|
|
|
+ // map[string]interface{}{
|
|
|
+ // "$set": map[string]interface{}{
|
|
|
+ // "repeat": 1,
|
|
|
+ // "repeatid": info.id,
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ //})
|
|
|
+ //
|
|
|
+ //if len(updateExtract) > 500 {
|
|
|
+ // mgo.UpdateBulk(extract, updateExtract...)
|
|
|
+ // updateExtract = [][]map[string]interface{}{}
|
|
|
+ //}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
//
|
|
|
var update_map = map[string]interface{}{
|
|
|
"$set": map[string]interface{}{
|
|
|
"reason":reason,
|
|
|
+ "repeat":"1",
|
|
|
+ "repeatid":repeat_id,
|
|
|
"merge":newData.mergemap,
|
|
|
},
|
|
|
}
|
|
@@ -451,6 +479,7 @@ func task(data []byte, mapInfo map[string]interface{}) {
|
|
|
|
|
|
} else {
|
|
|
//IS.Add("new")
|
|
|
+ mapLock.Unlock()
|
|
|
}
|
|
|
}
|
|
|
}(tmp)
|
|
@@ -461,7 +490,7 @@ func task(data []byte, mapInfo map[string]interface{}) {
|
|
|
mgo.UpdateBulk(extract, updateExtract...)
|
|
|
//mgo.UpdateBulk(bidding, updateBidding...)
|
|
|
}
|
|
|
- log.Println("this task over.", n, "repeateN:", repeateN, mapInfo["stop"],"无效数据:",inV_n)
|
|
|
+ log.Println("this task over.", n, "repeateN:", repeateN, mapInfo["stop"])
|
|
|
|
|
|
//任务完成,开始发送广播通知下面节点
|
|
|
if n > repeateN && mapInfo["stop"] == nil {
|
|
@@ -486,6 +515,260 @@ func task(data []byte, mapInfo map[string]interface{}) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+//支持历史更新
|
|
|
+func historyTask(data []byte, mapInfo map[string]interface{}) {
|
|
|
+
|
|
|
+ fmt.Println("开始取历史时间段")
|
|
|
+ defer util.Catch()
|
|
|
+ sess := mgo.GetMgoConn()
|
|
|
+ defer mgo.DestoryMongoConn(sess)
|
|
|
+ q := map[string]interface{}{
|
|
|
+ "_id": map[string]interface{}{
|
|
|
+ "$gt": util.StringTOBsonId(mapInfo["gtid"].(string)),
|
|
|
+ "$lte": util.StringTOBsonId(mapInfo["lteid"].(string)),
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ it := sess.DB(mgo.DbName).C(extract).Find(&q).Iter()
|
|
|
+ minTime,maxTime:=int64(0),int64(0)
|
|
|
+ for tmp := make(map[string]interface{}); it.Next(&tmp);{
|
|
|
+ //取出最大最小时间
|
|
|
+ if minTime==0||maxTime ==0 {
|
|
|
+ minTime = util.Int64All(tmp["comeintime"])
|
|
|
+ maxTime = util.Int64All(tmp["comeintime"])
|
|
|
+ }else {
|
|
|
+ t := util.Int64All(tmp["comeintime"])
|
|
|
+ if t<minTime&&t!=0 {
|
|
|
+ minTime = t
|
|
|
+ }
|
|
|
+ if t>maxTime&&t!=0 {
|
|
|
+ maxTime = t
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fmt.Println(minTime,maxTime)
|
|
|
+
|
|
|
+ HM = NewHistorymap(util.ObjToString(mapInfo["gtid"]),
|
|
|
+ util.ObjToString(mapInfo["lteid"]),minTime,maxTime)
|
|
|
+
|
|
|
+
|
|
|
+ //开始判重...
|
|
|
+ defer util.Catch()
|
|
|
+ sess_task := mgo.GetMgoConn()
|
|
|
+ defer mgo.DestoryMongoConn(sess_task)
|
|
|
+ q_task := map[string]interface{}{
|
|
|
+ "_id": map[string]interface{}{
|
|
|
+ "$gt": util.StringTOBsonId(mapInfo["gtid"].(string)),
|
|
|
+ "$lte": util.StringTOBsonId(mapInfo["lteid"].(string)),
|
|
|
+ },
|
|
|
+ }
|
|
|
+ it_task := sess.DB(mgo.DbName).C(extract).Find(&q_task).Iter()
|
|
|
+ updateExtract := [][]map[string]interface{}{}
|
|
|
+ pool := make(chan bool, 16)
|
|
|
+ wg := &sync.WaitGroup{}
|
|
|
+ mapLock := &sync.Mutex{}
|
|
|
+ n, repeateN := 0, 0
|
|
|
+
|
|
|
+ for tmp := make(map[string]interface{}); it_task.Next(&tmp); n++ {
|
|
|
+
|
|
|
+ if n%10000 == 0 {
|
|
|
+ log.Println("current:", n, tmp["_id"],"repeateN:",repeateN)
|
|
|
+ }
|
|
|
+ pool <- true
|
|
|
+ wg.Add(1)
|
|
|
+ go func(tmp map[string]interface{}) {
|
|
|
+ defer func() {
|
|
|
+ <-pool
|
|
|
+ wg.Done()
|
|
|
+ }()
|
|
|
+ info := NewInfo(tmp)
|
|
|
+
|
|
|
+ //是否为无效数据
|
|
|
+ if invalidData(info.buyer,info.projectname,info.projectcode) {
|
|
|
+ mapLock.Lock()
|
|
|
+ updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
+ map[string]interface{}{
|
|
|
+ "_id": tmp["_id"],
|
|
|
+ },
|
|
|
+ map[string]interface{}{
|
|
|
+ "$set": map[string]interface{}{
|
|
|
+ "repeat": -1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+ if len(updateExtract) > 500 {
|
|
|
+ mgo.UpdateBulk(extract, updateExtract...)
|
|
|
+ updateExtract = [][]map[string]interface{}{}
|
|
|
+ }
|
|
|
+ mapLock.Unlock()
|
|
|
+ }else {
|
|
|
+ b, source,reason := HM.check(info)
|
|
|
+ if b { //有重复,生成更新语句,更新抽取和更新招标
|
|
|
+
|
|
|
+ if reason == "未判重记录" {
|
|
|
+ //把info的数据判重的标签更换,并新增字段
|
|
|
+ mapLock.Lock()
|
|
|
+ //构建数据库更新用到的
|
|
|
+ //对比的数据打判重标签
|
|
|
+ DM.replaceSourceData(info,info.id) //替换即添加
|
|
|
+ updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
+ map[string]interface{}{
|
|
|
+ "_id": tmp["_id"],
|
|
|
+ },
|
|
|
+ map[string]interface{}{
|
|
|
+ "$set": map[string]interface{}{
|
|
|
+ "repeat": 0,
|
|
|
+ "repeatid": "-1",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+ if len(updateExtract) > 500 {
|
|
|
+ mgo.UpdateBulk(extract, updateExtract...)
|
|
|
+ updateExtract = [][]map[string]interface{}{}
|
|
|
+ }
|
|
|
+ mapLock.Unlock()
|
|
|
+ }else {
|
|
|
+ repeateN++
|
|
|
+ mapLock.Lock()
|
|
|
+
|
|
|
+ var mergeArr []int64 //更改合并数组记录
|
|
|
+ var newData *Info //更换新的数据池数据
|
|
|
+
|
|
|
+ var id_map = map[string]interface{}{}
|
|
|
+ //合并操作--评功权重打分-合并完替换原始数据池
|
|
|
+ basic_bool := basicDataScore(source,info)
|
|
|
+ if basic_bool {
|
|
|
+ //已原始数据为标准-对比数据打判重标签
|
|
|
+ newData,mergeArr= mergeDataFields(source,info)
|
|
|
+ DM.replaceSourceData(newData,source.id) //替换
|
|
|
+ id_map["_id"]= util.StringTOBsonId(source.id)
|
|
|
+
|
|
|
+ //对比的数据打判重标签
|
|
|
+ updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
+ map[string]interface{}{
|
|
|
+ "_id": tmp["_id"],
|
|
|
+ },
|
|
|
+ map[string]interface{}{
|
|
|
+ "$set": map[string]interface{}{
|
|
|
+ "repeat": 1,
|
|
|
+ "repeatid": source.id,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }else {
|
|
|
+ //已对比数据为标准 ,数据池的数据打判重标签
|
|
|
+ newData,mergeArr= mergeDataFields(info,source)
|
|
|
+ DM.replaceSourceData(newData,source.id)//替换
|
|
|
+ id_map["_id"]= util.StringTOBsonId(info.id)
|
|
|
+
|
|
|
+ //数据池的数据打判重标签
|
|
|
+ updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
+ map[string]interface{}{
|
|
|
+ "_id": util.StringTOBsonId(source.id),
|
|
|
+ },
|
|
|
+ map[string]interface{}{
|
|
|
+ "$set": map[string]interface{}{
|
|
|
+ "repeat": 1,
|
|
|
+ "repeatid": info.id,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //
|
|
|
+ var update_map = map[string]interface{}{
|
|
|
+ "$set": map[string]interface{}{
|
|
|
+ "reason":reason,
|
|
|
+ "merge":newData.mergemap,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ //更新合并后的数据
|
|
|
+ for _,value :=range mergeArr {
|
|
|
+ if value==1 {
|
|
|
+ update_map["$set"].(map[string]interface{})["area"] = newData.area
|
|
|
+ update_map["$set"].(map[string]interface{})["city"] = newData.city
|
|
|
+ }else if value==2 {
|
|
|
+ update_map["$set"].(map[string]interface{})["projectname"] = newData.projectname
|
|
|
+ }else if value==3 {
|
|
|
+ update_map["$set"].(map[string]interface{})["projectcode"] = newData.projectcode
|
|
|
+ }else if value==4 {
|
|
|
+ update_map["$set"].(map[string]interface{})["buyer"] = newData.buyer
|
|
|
+ }else if value==5 {
|
|
|
+ update_map["$set"].(map[string]interface{})["budget"] = newData.budget
|
|
|
+ }else if value==6 {
|
|
|
+ update_map["$set"].(map[string]interface{})["winner"] = newData.winner
|
|
|
+ }else if value==7 {
|
|
|
+ update_map["$set"].(map[string]interface{})["bidamount"] = newData.bidamount
|
|
|
+ }else if value==8 {
|
|
|
+ update_map["$set"].(map[string]interface{})["bidopentime"] = newData.bidopentime
|
|
|
+ }else {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //构建数据库更新用到的
|
|
|
+ updateExtract = append(updateExtract, []map[string]interface{}{
|
|
|
+ id_map,
|
|
|
+ update_map,
|
|
|
+ })
|
|
|
+ if len(updateExtract) > 500 {
|
|
|
+ mgo.UpdateBulk(extract, updateExtract...)
|
|
|
+ updateExtract = [][]map[string]interface{}{}
|
|
|
+ }
|
|
|
+ mapLock.Unlock()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //IS.Add("new")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }(tmp)
|
|
|
+ tmp = make(map[string]interface{})
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+ if len(updateExtract) > 0 {
|
|
|
+ mgo.UpdateBulk(extract, updateExtract...)
|
|
|
+ //mgo.UpdateBulk(bidding, updateBidding...)
|
|
|
+ }
|
|
|
+ log.Println("this task over.", n, "repeateN:", repeateN, mapInfo["stop"])
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //任务完成,开始发送广播通知下面节点
|
|
|
+ if n > repeateN &&mapInfo["stop"] == nil {
|
|
|
+ for _, to := range nextNode {
|
|
|
+ sid, _ := mapInfo["gtid"].(string)
|
|
|
+ eid, _ := mapInfo["lteid"].(string)
|
|
|
+ key := sid + "-" + eid + "-" + util.ObjToString(to["stype"])
|
|
|
+ by, _ := json.Marshal(map[string]interface{}{
|
|
|
+ "gtid": sid,
|
|
|
+ "lteid": eid,
|
|
|
+ "stype": util.ObjToString(to["stype"]),
|
|
|
+ "key": key,
|
|
|
+ })
|
|
|
+ addr := &net.UDPAddr{
|
|
|
+ IP: net.ParseIP(to["addr"].(string)),
|
|
|
+ Port: util.IntAll(to["port"]),
|
|
|
+ }
|
|
|
+ node := &udpNode{by, addr, time.Now().Unix(), 0}
|
|
|
+ udptaskmap.Store(key, node)
|
|
|
+ udpclient.WriteUdp(by, mu.OP_TYPE_DATA, addr)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
//合并字段
|
|
|
func mergeDataFields(source *Info, info *Info) (*Info,[]int64){
|