Lmap.put() for the third time behave unexpectedly, seems to return cached result


#1

as lmap doesn’t have a “exists” or “contains_key” function, I tried to do it on my own to check the existing key before certain operation. The code is as follows:

function testPut(rec, key, val)
  local lmap = require('ldt/lib_lmap')

  if rec['_map']~=null and pcall(function() return lmap.get(rec,'_map',key)~=nil end) then
    info("testPut() - old: %s", tostring(lmap.get(rec,'_map',key)))
    lmap.put(rec,'_map',key,val)
  else
    lmap.put(rec,'_map',key,val)  
  end  
end

Then invoke it as follows:

execute testModule.testPut('a',1)  on test.map where pk ='_'
execute lmap.scan('_map') on test.map where pk ='_'
execute testModule.testPut('a',2)  on test.map where pk ='_'
execute lmap.scan('_map') on test.map where pk ='_'
execute testModule.testPut('a',3)  on test.map where pk ='_'
execute lmap.scan('_map') on test.map where pk ='_'

The lmap.scan indicate data are stored correctly, the value is updated from 1 to 2 to 3.

However, the info log files that is run in the 2nd and 3rd testPut() are as follows:

testPut() - old: {"a":1}
testPut() - old: {"a":1}

the first one is correct as it changed from 1 to 2, it print out old as 1. However, for the 3rd invoke/2nd info log, the old value remains as 1. And any subsequent invoke will never change the old value.

Is it a bug that the data is cached somewhere in the Lua engine?


#2

That’s an interesting behavior. I have not seen that one before. I’ll have to recreate it here. Thanks for providing a good example.

As users write in with questions, we’re seeing the need for more LDT functions. For example, it’s clear that we need a way to return all names, and possibly all values, independent of returning the entire LMAP with a scan. Also, it didn’t occur to me that it would be useful to have an exists() function for LMAP, but I can see that it might be useful when used from another UDF (as you’ve shown).

Toby


#3

btw, i’m not familiar with Lua and not sure of the performance characteristic of pcall(). As an example, for Java in general, it is not recommended to use try-catch as control-flow if one want to achieve the best performance. (at least, it is widely believed in the past)

And indeed, I’m not sure if using UDF may introduce “too much” latency. It would be great if there are some performance guidelines for writing UDF as people who write Lua UDF may not be familiar with Lua. <-- talking about me :smile: