vso*_*tka 2 progress-4gl openedge
背景故事
我负责 Android 客户端的后端工作。有很多数据要显示,还需要一些离线功能,所以必须解决同步问题。所述数据由临时表组成。
我们的解决方案
现在,为了让客户端了解可能的更改,而不是强制执行完整的客户端数据库擦除和创建(需要大量时间),我对每个临时表行进行了哈希处理。所述哈希值是通过获取临时表行、为其创建 JSON,然后从该 JSON 生成哈希值来创建的。这是工作。
我对这个解决方案的问题
我认为这不是理想的解决方案。所有这些操作看起来要求很高,从我的测试来看,它表明:
我想要的是
我很感兴趣我们是否做错了什么。对于这个问题有更好的解决方案吗?是否有要求较低的方法来从每个单独的临时表记录中创建哈希?
我们目前使用的是OpenEdge 10.2B。
程序负责hash创建,create_hash 创建widget-pool。
define input parameter inp_hBuffer as handle no-undo.
define output parameter out_cHash as c no-undo.
define var ttDynamic as handle no-undo.
define var hBufferTT as handle no-undo.
define var lResult as l no-undo.
define var cDataTT as longchar no-undo.
define var itime as i.
do on error undo,return error:
if not(valid-handle(inp_hBuffer) and inp_hBuffer:type = 'BUFFER':u) then
return error substitute('Neplatny typ vstupniho parametru predaneho procedure "&1".','m_ghashb':u).
create temp-table ttDynamic.
ttDynamic:add-fields-from(inp_hBuffer).
ttDynamic:temp-table-prepare(inp_hBuffer:table).
hBufferTT = ttDynamic:default-buffer-handle.
hBufferTT:buffer-copy(inp_hBuffer).
ttDynamic:write-json('longchar':u,cDataTT).
out_cHash = hex-encode(md5-digest(cDataTT)).
end.
return.
Run Code Online (Sandbox Code Playgroud)
及其用途
for first lbUsrtab where
lbUsrtab.ucje = GetUcje('m_usrtab':U) and
lbUsrtab.login-name = LoginName no-lock,
each lbWcesta where
lbWcesta.ucje = GetUcje('wcesta':U) and
lbWcesta.kodu = lbUsrtab.kodu no-lock,
each lbWciorg where
lbWciorg.ucje = GetUcje('wciorg':U) and
lbWciorg.cest = lbWcesta.cest no-lock,
each lbKontaktr where
lbKontaktr.ucje = GetUcje('kontaktr':U) and
lbKontaktr.corg = lbWciorg.corg no-lock
by lbKontaktr.zako descending
on error undo, return error return-value:
create ttKontaktr.
buffer-copy lbKontaktr to ttKontaktr.
run create_hash(input buffer ttKontaktr:handle, output ttKontaktr.hash).
end.
Run Code Online (Sandbox Code Playgroud)
我想要的是
这是一个几乎快 20 倍的哈希解决方案(对于 1000 次调用,它是 320 毫秒 vs 17 毫秒):
PROCEDURE hash2:
DEFINE INPUT PARAMETER inp_hBuffer AS HANDLE NO-UNDO .
DEFINE OUTPUT PARAMETER out_cHash AS CHARACTER NO-UNDO .
inp_hBuffer:RAW-TRANSFER (TRUE, hRawField) .
out_cHash = HEX-ENCODE (MD5-DIGEST (ttWithRaw.raw_field)).
END PROCEDURE .
Run Code Online (Sandbox Code Playgroud)
您需要一个带有 RAW 字段和单个记录的辅助临时表,因为缓冲区对象句柄的 RAW-TRANSFER 方法仅适用于缓冲区字段对象句柄,因此在 hash2 过程之外有类似的内容,您需要仅运行一次:
DEFINE VARIABLE hRawField AS HANDLE NO-UNDO.
DEFINE TEMP-TABLE ttWithRaw NO-UNDO
FIELD raw_field AS RAW .
ASSIGN hRawField = BUFFER ttWithRaw:BUFFER-FIELD("raw_field") .
CREATE ttWithRaw .
Run Code Online (Sandbox Code Playgroud)
我还没有尝试优化你的代码。
我很感兴趣我们是否做错了什么。对于这个问题有更好的解决方案吗?是否有要求较低的方法来从每个单独的临时表记录中创建哈希?
运行时的很大一部分将来自为每个记录创建动态临时表 - 我怀疑您是否需要一遍又一遍地为每个记录创建该临时表。
也许,通过移动这部分
create temp-table ttDynamic.
ttDynamic:add-fields-from(inp_hBuffer).
ttDynamic:temp-table-prepare(inp_hBuffer:table).
Run Code Online (Sandbox Code Playgroud)
脱离了哈希过程,您的代码也会得到改进。但我怀疑它会比基于 RAW-TRANSFER 方法的版本更快。