mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 08:52:00 +00:00
Lunatic: 'bitar': rewrite ops for colon syntax, serialization, set ops.
git-svn-id: https://svn.eduke32.com/eduke32@2862 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
569f0dbe7c
commit
f4c7e3f77e
5 changed files with 138 additions and 28 deletions
|
@ -170,7 +170,8 @@ ifneq (0,$(LUNATIC))
|
|||
$(OBJ)/luaJIT_BC_lunacon.$o \
|
||||
$(OBJ)/luaJIT_BC_geom.$o \
|
||||
$(OBJ)/luaJIT_BC_randgen.$o \
|
||||
$(OBJ)/luaJIT_BC_stat.$o
|
||||
$(OBJ)/luaJIT_BC_stat.$o \
|
||||
$(OBJ)/luaJIT_BC_bitar.$o
|
||||
|
||||
# now, take care of having the necessary symbols (sector, wall, etc.) in the
|
||||
# executable no matter what the debugging level
|
||||
|
|
|
@ -1,33 +1,18 @@
|
|||
|
||||
-- "Bit array" module based on LuaJIT's BitOp.
|
||||
|
||||
local ffi = require "ffi"
|
||||
local bit = require "bit"
|
||||
|
||||
local error = error
|
||||
local assert = assert
|
||||
local type = type
|
||||
|
||||
local setmetatable=setmetatable
|
||||
|
||||
|
||||
module(...)
|
||||
|
||||
-- Create new bit array.
|
||||
-- Returns a table p in which entries p[0] through p[floor((size+31)/32)]
|
||||
-- are set to an initialization value: 0 if 0 has been passed, -1 if 1
|
||||
-- has been passed.
|
||||
function new(size, initval)
|
||||
if (type(size) ~= "number" or size < 0) then
|
||||
error("bad argument #1 to newarray (must be a nonnegative number)", 2)
|
||||
end
|
||||
|
||||
if (initval ~= 0 and initval ~= 1) then
|
||||
error("bad argument #2 to newarray (must be either 0 or 1)", 2)
|
||||
end
|
||||
|
||||
local p = {}
|
||||
for i=0,(size+31)/32 do
|
||||
p[i] = -initval
|
||||
end
|
||||
|
||||
return p
|
||||
end
|
||||
|
||||
-- Is bit i set in bit array ar?
|
||||
function isset(ar, i)
|
||||
|
@ -45,3 +30,109 @@ function set1(ar, j)
|
|||
local jx = bit.rshift(j, 5)
|
||||
ar[jx] = bit.bor(ar[jx], bit.rol(0x00000001, j))
|
||||
end
|
||||
|
||||
local ops = { isset=isset, set0=set0, set1=set1 }
|
||||
local mt
|
||||
mt = {
|
||||
__index=ops,
|
||||
|
||||
-- set ops disguised as arithmetic ones...
|
||||
|
||||
__mul = function(ar1, ar2) -- set intersection
|
||||
assert(#ar1 == #ar2)
|
||||
local p = {}
|
||||
for i=0,#ar1 do
|
||||
p[i] = bit.band(ar1[i], ar2[i])
|
||||
end
|
||||
return setmetatable(p, mt)
|
||||
end,
|
||||
|
||||
__add = function(ar1, ar2) -- set union
|
||||
assert(#ar1 == #ar2)
|
||||
local p = {}
|
||||
for i=0,#ar1 do
|
||||
p[i] = bit.bor(ar1[i], ar2[i])
|
||||
end
|
||||
return setmetatable(p, mt)
|
||||
end,
|
||||
|
||||
__sub = function(ar1, ar2) -- set difference
|
||||
assert(#ar1 == #ar2)
|
||||
local p = {}
|
||||
for i=0,#ar1 do
|
||||
p[i] = bit.band(ar1[i], bit.bnot(ar2[i]))
|
||||
end
|
||||
return setmetatable(p, mt)
|
||||
end,
|
||||
|
||||
-- serialization
|
||||
__tostring = function(ar)
|
||||
local maxidx=#ar
|
||||
local size=maxidx+1
|
||||
|
||||
local hdr = "bitar.new('"
|
||||
local ofs = #hdr
|
||||
local totalstrlen = ofs+8*size+2
|
||||
local str = ffi.new("char [?]", totalstrlen)
|
||||
|
||||
ffi.copy(str, hdr, ofs)
|
||||
|
||||
for i=0,maxidx do
|
||||
-- 'a' is ASCII 97
|
||||
for nib=0,7 do
|
||||
str[ofs + 8*i + nib] = 97 + bit.band(bit.rshift(ar[i], 4*nib), 0x0000000f)
|
||||
end
|
||||
end
|
||||
|
||||
ffi.copy(str+totalstrlen-2, "')", 2)
|
||||
|
||||
return ffi.string(str, totalstrlen)
|
||||
end,
|
||||
}
|
||||
|
||||
-- Create new bit array.
|
||||
-- Returns a table p in which entries p[0] through p[floor((maxbidx+31)/32)]
|
||||
-- are set to an initialization value: 0 if 0 has been passed, -1 if 1
|
||||
-- has been passed.
|
||||
-- Storage: 4 bits/bit + O(1)? (per 32 bits: 64 bits key, 64 bits value)
|
||||
function new(maxbidx, initval)
|
||||
local p = {}
|
||||
|
||||
if (type(maxbidx)=="string") then
|
||||
-- string containing hex digits (a..p) given, internal
|
||||
local lstr = maxbidx
|
||||
|
||||
local numnibs = #lstr
|
||||
assert(numnibs%8 == 0)
|
||||
|
||||
local size = numnibs/8
|
||||
local maxidx = size-1
|
||||
|
||||
local str = ffi.new("char [?]", numnibs)
|
||||
ffi.copy(str, lstr, numnibs)
|
||||
|
||||
for i=0,maxidx do
|
||||
p[i] = 0
|
||||
|
||||
for nib=0,7 do
|
||||
local hexdig = str[8*i + nib]
|
||||
assert(hexdig >= 97 and hexdig < 97+16)
|
||||
p[i] = bit.bor(p[i], bit.lshift(hexdig-97, 4*nib))
|
||||
end
|
||||
end
|
||||
else
|
||||
if (type(maxbidx) ~= "number" or not (maxbidx >= 0)) then
|
||||
error("bad argument #1 to newarray (must be a nonnegative number)", 2)
|
||||
end
|
||||
|
||||
if (initval ~= 0 and initval ~= 1) then
|
||||
error("bad argument #2 to newarray (must be either 0 or 1)", 2)
|
||||
end
|
||||
|
||||
for i=0,maxbidx/32 do
|
||||
p[i] = -initval
|
||||
end
|
||||
end
|
||||
|
||||
return setmetatable(p, mt)
|
||||
end
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
local string = require "string"
|
||||
|
||||
local getticks
|
||||
|
||||
local bit = require("bit")
|
||||
local bitar = require "bitar"
|
||||
|
||||
local print = print
|
||||
local tonumber = tonumber
|
||||
|
||||
local getticks
|
||||
|
||||
if (string.dump) then
|
||||
-- stand-alone
|
||||
local os = require "os"
|
||||
|
@ -27,8 +27,6 @@ end
|
|||
|
||||
-- based on example from http://bitop.luajit.org/api.html
|
||||
|
||||
local isset, set0 = bitar.isset, bitar.set0
|
||||
|
||||
local m = string.dump and tonumber(arg[1]) or 1e7
|
||||
|
||||
local ffiar_p, boundchk_p = false, false
|
||||
|
@ -82,17 +80,35 @@ function sieve()
|
|||
local t = getticks()
|
||||
|
||||
for i=2,m do
|
||||
if (isset(p, i)) then
|
||||
if (p:isset(i)) then
|
||||
count = count + 1
|
||||
for j=i+i,m,i do set0(p, j); end
|
||||
for j=i+i,m,i do p:set0(j); end
|
||||
end
|
||||
end
|
||||
|
||||
print(string.format("[%s] Found %d primes up to %d (%.02f ms)",
|
||||
ffiar_p and "ffi-ar"..(boundchk_p and ", bchk" or "") or "tab-ar",
|
||||
count, m, getticks()-t))
|
||||
|
||||
return p
|
||||
end
|
||||
|
||||
if (string.dump) then
|
||||
sieve()
|
||||
local p = sieve()
|
||||
local t = getticks()
|
||||
|
||||
-- test serialization
|
||||
local p2 = bitar.new(string.match(tostring(p), "'(.*)'"))
|
||||
print(getticks()-t)
|
||||
|
||||
for i=0,#p do
|
||||
assert(p[i]==p2[i])
|
||||
end
|
||||
|
||||
for i = 3,#p do
|
||||
p[i] = nil
|
||||
end
|
||||
|
||||
print(p)
|
||||
print(p-p) -- test set difference
|
||||
end
|
||||
|
|
|
@ -548,6 +548,7 @@ local allowed_modules = {
|
|||
randgen = require("randgen"),
|
||||
geom = require("geom"),
|
||||
stat = require("stat"),
|
||||
bitar = require("bitar"),
|
||||
}
|
||||
|
||||
local package_loaded = {}
|
||||
|
|
|
@ -43,6 +43,7 @@ luaJIT_BC_con_lang;
|
|||
luaJIT_BC_geom;
|
||||
luaJIT_BC_randgen;
|
||||
luaJIT_BC_stat;
|
||||
luaJIT_BC_bitar;
|
||||
|
||||
rand_jkiss_u32;
|
||||
rand_jkiss_dbl;
|
||||
|
|
Loading…
Reference in a new issue