diff --git a/test/unit/set.lua b/test/unit/set.lua new file mode 100644 index 0000000000..bfb6b8c41c --- /dev/null +++ b/test/unit/set.lua @@ -0,0 +1,127 @@ +-- a set class for fast union/diff, can always return a table with the lines +-- in the same relative order in which they were added by calling the +-- to_table method. It does this by keeping two lua tables that mirror each +-- other: +-- 1) index => item +-- 2) item => index +local Set = {} + +function Set:new(items) + local obj = {} + setmetatable(obj, self) + self.__index = self + + if type(items) == 'table' then + local tempset = Set:new() + tempset:union_table(items) + obj.tbl = tempset:raw_tbl() + obj.items = tempset:raw_items() + obj.nelem = tempset:size() + else + obj.tbl = {} + obj.items = {} + obj.nelem = 0 + end + + return obj +end + +-- adds the argument Set to this Set +function Set:union(other) + for e in other:iterator() do + self:add(e) + end +end + +-- adds the argument table to this Set +function Set:union_table(t) + for k, v in pairs(t) do + self:add(v) + end +end + +-- subtracts the argument Set from this Set +function Set:diff(other) + if other:size() > self:size() then + -- this set is smaller than the other set + for e in self:iterator() do + if other:contains(e) then + self:remove(e) + end + end + else + -- this set is larger than the other set + for e in other:iterator() do + if self.items[e] then + self:remove(e) + end + end + end +end + +function Set:add(it) + if not self:contains(it) then + local idx = #self.tbl + 1 + self.tbl[idx] = it + self.items[it] = idx + self.nelem = self.nelem + 1 + end +end + +function Set:remove(it) + if self:contains(it) then + local idx = self.items[it] + self.tbl[idx] = nil + self.items[it] = nil + self.nelem = self.nelem - 1 + end +end + +function Set:contains(it) + return self.items[it] or false +end + +function Set:size() + return self.nelem +end + +function Set:raw_tbl() + return self.tbl +end + +function Set:raw_items() + return self.items +end + +function Set:iterator() + return pairs(self.items) +end + +function Set:to_table() + -- there might be gaps in @tbl, so we have to be careful and sort first + local keys + do + local _accum_0 = { } + local _len_0 = 1 + for idx, _ in pairs(self.tbl) do + _accum_0[_len_0] = idx + _len_0 = _len_0 + 1 + end + keys = _accum_0 + end + table.sort(keys) + local copy + do + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #keys do + local idx = keys[_index_0] + _accum_0[_len_0] = self.tbl[idx] + _len_0 = _len_0 + 1 + end + copy = _accum_0 + end + return copy +end + +return Set diff --git a/test/unit/set.moon b/test/unit/set.moon deleted file mode 100644 index affbd5c29a..0000000000 --- a/test/unit/set.moon +++ /dev/null @@ -1,72 +0,0 @@ --- a set class for fast union/diff, can always return a table with the lines --- in the same relative order in which they were added by calling the --- to_table method. It does this by keeping two lua tables that mirror each --- other: --- 1) index => item --- 2) item => index -class Set - new: (items) => - if type(items) == 'table' - tempset = Set() - tempset\union_table(items) - @tbl = tempset\raw_tbl! - @items = tempset\raw_items! - @nelem = tempset\size! - else - @tbl = {} - @items = {} - @nelem = 0 - - -- adds the argument Set to this Set - union: (other) => - for e in other\iterator! - @add(e) - - -- adds the argument table to this Set - union_table: (t) => - for k,v in pairs(t) - @add(v) - - -- subtracts the argument Set from this Set - diff: (other) => - if other\size! > @size! - -- this set is smaller than the other set - for e in @iterator! - if other\contains(e) - @remove(e) - else - -- this set is larger than the other set - for e in other\iterator! - if @items[e] - @remove(e) - - add: (it) => - if not @contains(it) - idx = #@tbl + 1 - @tbl[idx] = it - @items[it] = idx - @nelem += 1 - - remove: (it) => - if @contains(it) - idx = @items[it] - @tbl[idx] = nil - @items[it] = nil - @nelem -= 1 - - contains: (it) => - @items[it] or false - - size: => @nelem - raw_tbl: => @tbl - raw_items: => @items - iterator: => pairs(@items) - - to_table: => - -- there might be gaps in @tbl, so we have to be careful and sort first - keys = [idx for idx, _ in pairs(@tbl)] - table.sort(keys) - copy = [@tbl[idx] for idx in *keys] - copy - -return Set