Browse files

Sorted array

  • Loading branch information...
1 parent 2f867c4 commit d98fc1d842883db86c937e65c1c87c4ea31983e5 @delamonpansie delamonpansie committed Oct 3, 2011
Showing with 155 additions and 0 deletions.
  1. +155 −0 sorted_array.lua
View
155 sorted_array.lua
@@ -0,0 +1,155 @@
+local bit = require("bit")
+local table = require("table")
+local string = require("string")
+local floor = require("math").floor
+
+local function s_to_a(data)
+ local a = {}
+ local bytes = {string.byte(data, i, #data)}
+ for i = 1, #data / 8 do
+ a[i] = 0
+ for c = 0, 7 do
+ a[i] = bit.lshift(a[i], 8)
+ a[i] = a[i] + bytes[i * 8 - c]
+ end
+ end
+ return a
+end
+
+local function a_to_s(a)
+ local bytes = {}
+ for i = 1, #a do
+ for c = 0, 7 do
+ table.insert(bytes, bit.band(a[i], 0xff))
+ a[i] = bit.rshift(a[i], 8)
+ end
+ end
+ return string.char(unpack(bytes))
+end
+
+local limit = 500
+local function amerge(a, b)
+ local r = {}
+ local n = limit
+ while #a > 0 and #b > 0 and n > 0 do
+ if a[1] > b[1] then
+ table.insert(r, table.remove(a, 1))
+ else
+ table.insert(r, table.remove(b, 1))
+ end
+ n = n - 1
+ end
+ while #a > 0 and n > 0 do
+ table.insert(r, table.remove(a, 1))
+ n = n - 1
+ end
+ while #b > 0 and n > 0 do
+ table.insert(r, table.remove(b, 1))
+ n = n - 1
+ end
+ return r
+end
+
+local function afind_ge(a, x)
+ if #a == 0 then
+ return 1
+ end
+
+ local min, max = 1, #a
+ repeat
+ mid = floor((min + max) / 2)
+ if x < a[mid] then
+ min = mid + 1
+ else
+ max = mid - 1
+ end
+ until a[mid] == b or min > max
+ return mid
+end
+
+local function ains(a, key)
+ key = tonumber(key)
+
+ local i = afind_ge(a, key)
+ if a[i] and a[i] >= key then
+ table.insert(a, i + 1, key) -- next to equal or greater
+ else
+ table.insert(a, i, key)
+ end
+
+ while #a > limit do
+ table.remove(a)
+ end
+end
+
+local function adel(a, key)
+ key = tonumber(key)
+ local i = afind_ge(a, key)
+ if a[i] == key then
+ table.remove(a, i)
+ end
+end
+
+local function get(space, key)
+ local tuple = box.select(space, 0, key)
+ if tuple then
+ return s_to_a(tuple[1])
+ else
+ return {}
+ end
+end
+
+local function store(space, key, a)
+ return box.replace(space, key, a_to_s(a))
+end
+
+
+function box.sa_insert(space, key, value)
+ local a = get(space, key)
+ ains(a, value)
+ print(unpack(a))
+ return store(space, key, a)
+end
+
+function box.sa_delete(space, key, ...)
+ local a = get(space, key)
+ for i, d in pairs({...}) do
+ adel(a, d)
+ end
+ return store(space, key, a)
+end
+
+function box.sa_select(space, key, from, limit)
+ if from ~= '' then
+ from = afind_ge(a, tonumber(from))
+ else
+ from = 1
+ end
+
+ if limit ~= '' then
+ limit = tonumber(limit)
+ else
+ limit = 0
+ end
+
+ local a = get(space, key)
+ local r = {}
+ for i = from, #a - from + 1 do
+ if a[i] == nil then
+ break
+ end
+ table.insert(r, a[i])
+ limit = limit - 1
+ if limit == 0 then
+ break
+ end
+ end
+ return key, a_to_s(r)
+end
+
+function box.sa_merge(space, key_a, key_b)
+ local a = get(space, key_a)
+ local b = get(space, key_b)
+ local r = amerge(a, b)
+ return a_to_s(r)
+end

0 comments on commit d98fc1d

Please sign in to comment.