2

I have data in the form of a tuple (S, T), where S is string and T is integer. Neither S nor T is unique, while their combination is unique. I need to get all tuples where S1 == S2 and |T1 - T2| <= C. Is is possible to do efficiently with Redis?

Community
  • 1
  • 1
assp1r1n3
  • 173
  • 2
  • 8
  • I think your question would benefit if you clarify whether the tuples in the dataset are unique. Regardless, because of the 64-bit requirement I believe it would be hard to pull it off (hard as in inefficient) - Redis doesn't have a native integer data type and the biggest integer it can handle is about 53 bits (scores in a Sorted Set are doubles). – Itamar Haber May 04 '16 at 00:55
  • I relaxed question conditions a bit, but are there some other options(another database) which would fit better in this task? – assp1r1n3 May 04 '16 at 07:15

1 Answers1

1

One way would be to store the data in a list and do the retrieval with a Lua script. First, for tuples of the form (Sn,Tn), insert it like this:

LPUSH myKey S1:T1
LPUSH myKey S2:T2
... and so on

Then, use the Lua script below:

local function split(div,str)
    if (div=='') then return false end
    local pos,arr = 0,{}
    for st,sp in function() return string.find(str,div,pos,true) end do
        table.insert(arr,string.sub(str,pos,st-1))
        pos = sp + 1
    end
    table.insert(arr,string.sub(str,pos))
    return arr
end

local key = KEYS[1]
local sVal = ARGV[1]
local tVal = tonumber(ARGV[2])
local cVal = tonumber(ARGV[3])
local length = redis.call("LLEN", key)

if (tonumber(length) == 0) then
    return nil
end

local data = redis.call("LRANGE", key, 0, tonumber(length))
local retval = {}

for index,val in pairs(data) do
    local parts = split(":", val)    
    if (parts[1] == sVal and math.abs(tonumber(parts[2]) - tVal) <= cVal) then
        table.insert(retval, val)
    end
end

return retval

Save it as script.lua and execute it with:

$ redis-cli "$(cat script.lua)" 1 myKey sValue tValue cValue

This will return all tuples (in Sn:Tn form) that matches S1 == S2 and |T1 - T2| <= C.

Duru Can Celasun
  • 1,621
  • 1
  • 16
  • 28
  • What is the expected time complexity of that solution? – assp1r1n3 May 04 '16 at 10:29
  • Assuming you mean time complexity, it would be `O(n)` since it has to iterate the entire list. I don't think you could do better than `O(n)` with Redis' data structures, but I'd love to be proven wrong on that :) – Duru Can Celasun May 04 '16 at 10:30