golang 多維哈希(map,hashmap)實踐隨筆


  有些場景使用多維哈希來存儲數據,時間復雜度恆定,簡單粗暴好用。這里記錄一下。

  如下是三維哈希的簡單示意圖,建議層數不要太多,否則時間久了,自己寫的代碼都不認識。

下圖是三維哈希在內存的存儲形式,hashmap嵌套了3層。圖里一層數組存放entry和鏈表next指針,每個節點里面都存放一個數組,數組存放下一層hashcode和下一層鏈表指針。(沒有將哈希分桶鏈表完整畫出來,本圖重點是哈希嵌套)

 

 

這個數據結構我是用來解析保存不同設備的配置,每個設備有兩個配置文件。當新來一個該設備的數據(base64加密后的json序列化字符串),通過這個三維哈希層層解析,返回給用戶直觀的表象。這里不談業務,只談如何暴力存,暴力解。

/*****************************************************************************
   結 構 名  : StringStu
   功能描述  : 設備string文件數據結構
*****************************************************************************/
type StringStu struct {
	Cat_name    string      `json:"cat_name,omitempty"`
	Dev_name    string      `json:"dev_name,omitempty"`
	Pid         string      `json:"pid,omitempty"`
	Error       interface{} `json:"error,omitempty"`
	Intfs       interface{} `json:"intfs,omitempty"`
	Vendor_name string      `json:"vendor_name,omitempty"`
}

/*****************************************************************************
   結 構 名  : 產品string文件相關處理
   功能描述  :
*****************************************************************************/
func GetAllProductString() (Slice []ProfileSuidsStu) {
	StringStu := ReadStringFile()
	for _, StringOne := range StringStu {
		LoadDevStrings2Cache(StringOne.Pid, libf.StructToJsonStringOne(StringOne.Intfs))
	}
	return
}

func ReadStringFile() []StringStu {
	var file string = ""
	var StringSlice = make([]StringStu, 0)
	file = libf.KeyfileT(file).GetFileName("strings.json")

	Byte, Error := ioutil.ReadFile(file)
	if Error != nil {
		prnLog.LogPrint(libf.LOG_ERROR, 0, false, false, "", "ReadFile error", Error)
		return nil
	}

	msg, ret := libf.ParseJsonByStructMsg(Byte, &StringSlice)
	return StringSlice
}

/*****************************************************************************
   結 構 名  : StringIntfsStu
   功能描述  : 設備string文件,設備Intfs屬性
*****************************************************************************/
type StringsIntfsStu struct {
	Name   string            `json:"name,omitempty"`   //字段的中文名稱,例如:電量,背景燈光
	Unit   string            `json:"unit,omitempty"`   //單元,例如溫度°C
	Values map[string]string `json:"values,omitempty"` //字段值對應的中文枚舉,例如:0是關,1是開
}

type ParamAttr = map[string]StringsIntfsStu

var ProductStrings = make(map[string](ParamAttr), 0)

/*****************************************************************************
* \author      pxx
* \date        2018/08/25
* \brief		將所有設備的strings配置,載入一個三維哈希中。
			一維哈希是ProductStrings,key為pid,
			二維哈希是ParamAttr,key為字段英文名稱,
			三維哈希是StringIntfsStu結構體內的Values,key為字段的值
* \param[in]
* \param[out]
* \return
* \ingroup
* \remarks
******************************************************************************/
func LoadDevStrings2Cache(pid, String string) {
	var (
		keyListString map[string]interface{} = make(map[string]interface{}, 0)
		_param_attr                          = make(ParamAttr, 0)
	)
	ProductStrings[pid] = _param_attr
	msg, ret := libf.ParseJsonByStructMsg([]byte(String), &keyListString)
    
	for key, value := range keyListString {
		var string1 StringsIntfsStu //注意作用域

		msg, ret = libf.ParseJsonByStructMsg([]byte(libf.StructToJsonStringOne(value)), &string1)
		if ret != libf.Success {
			prnLog.LogPrint(libf.LOG_DEBUG, 0, false, false, "msg=%v,ret=%v", msg, ret)
			continue
		}
		_param_attr[key] = string1
	}
}

  

上面的代碼是粗暴的將所有設備的配置文件存入內存,下面則是根據這個三維哈希去解析數據。

/*****************************************************************************
* \author      pxx
* \date        2018/08/27
* \brief	將json序列化的無結構數據,映射為結構化數據
* \param[in]
* \param[out]
* \return
* \ingroup
* \remarks  開源代碼說明:https://www.jb51.net/article/73996.htm
******************************************************************************/
func FormatUploadData(StringData string) (StructData StructUploadDataStu) {
	StructData.Did = gojson.Json(StringData).Get("did").Tostring()
	StructData.Pid = gojson.Json(StringData).Get("pid").Tostring()

	for k, v := range ProductProfile[StructData.Pid] { //k是字段名稱,v是這個字段的子屬性
		value := gojson.Json(StringData).Get(k).Tostring()

		//根據設備每個字段的不同屬性,來映射對應的中文名稱,枚舉值,字符串值還有整數值
		switch v.In[0] {
		case 1, 3: //1表示枚舉,2表示是連續型的參數,3 string
			StructData.Data += ProductStrings[StructData.Pid][k].Name + ":" + ProductStrings[StructData.Pid][k].Values[value] + ",  "

		case 2:
			StructData.Data += ProductStrings[StructData.Pid][k].Name + ":" + value + ",  "

		default:

		}
	}
	return
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM