--[[******************************************************************************]] --[[* Project ib_win_core *]] --[[* Copyright 2023 Incredibuild Software Ltd. *]] --[[* All rights reserved *]] --[[******************************************************************************]] local function binary_search(arr, target) local left, right = 1, #arr while left <= right do local mid = math.floor((left + right) / 2) local current = tonumber(arr[mid]) if current == target then return mid elseif current < target then left = mid + 1 else right = mid - 1 end end return left end local function remove_inconsistent(inconsistent) local times = redis.call('KEYS', '*') table.sort(times) local unfixed = 0 for _, item in ipairs(inconsistent) do local found = false local pos = binary_search(times, item.l) if (pos > 1) then for i = pos-1, 1, -1 do local prev = times[i] if redis.call('HEXISTS', prev, item.u) == 1 then redis.call('HDEL', prev, item.u) found = true break end end if not found then unfixed = unfixed + 1 end end end if unfixed > 0 then error(unfixed .. ' items inconsistency detected') end end local function update(items) local inconsistent = {}; for i,str in ipairs(items) do local uuid,prev,last,size = loadstring('return '..str)() if redis.call('HDEL', prev, uuid) ~= 1 then inconsistent[#inconsistent + 1] = { u = uuid, l = last } end redis.call('HSET', last, uuid, size) end if #inconsistent > 0 then remove_inconsistent(inconsistent) end return 'OK' end local function main(usageDB, items) redis.call('SELECT', usageDB) return update(items) end local ok, result = pcall(main, KEYS[1], ARGV) return result