您只需要以 ID 开头的条目的排序表。该代码可以为您创建索引,并将索引与二进制搜索一起使用进行查找。索引将是 40kb。您可能可以节省那么多。如果 ID 真的只有 3 字节,它可以变成 30kb,但除非你真的短 10kb,否则这将是一个不必要的复杂化。
哈希可以放弃索引,但节省空间值得吗?如果条目比它们的 ID 大得多,那么就不会占用那么多空位来用完节省的空间。
VAR_GLOBAL
entries : ARRAY[1..entryCount] OF ST_Entry := ...; // you need to preinitialize this array here
index: ARRAY[1..entryCount] OF DINT;
_dummy : BOOL := BuildIndex(ADR(index), ADR(entries), entryCount);
END_VAR
VAR_GLOBAL CONSTANT
entryCount : DINT := 10000;
END_VAR
// Called once during PLC initialization only. Returns FALSE always.
FUNCTION BuildIndex : BOOL
VAR_INPUT
index: POINTER TO DINT;
entries : POINTER TO ST_ENTRY;
count : DINT;
END_VAR
WHILE count > 0 DO
index[count] := entries[count].Id;
count := count - 1;
END_WHILE
END_FUNCTION
使用此设置,通过二进制搜索进行索引查找很容易:
FUNCTION LookupEntry : REFERENCE TO ST_Entry
VAR_INPUT
id : DINT;
END_VAR
VAR
begin : DINT := 1;
mid : DINT;
end : DINT := GVL.entryCount;
midId : DINT;
END_VAR
WHILE TRUE DO
mid := (begin + end) / 2;
midId := index[mid];
IF midId = id THEN
LookupEntry REF= entries[mid];
EXIT;
END_IF
IF mid=begin AND mid=end THEN
EXIT;
END_IF
IF midId < id THEN
begin := mid;
ELSE
end := mid;
END_IF
END_WHILE;
// may return an invalid reference, use of reference will throw
END_FUNCTION