announcement-test/temp_file/config/process_share_wrapper.rb

132 lines
3.3 KiB
Ruby
Raw Normal View History

2023-12-14 23:58:10 +00:00
require 'process_shared'
class ProcessShareWrapper
attr_accessor :data
attr_accessor :need_process
def parse_value(v)
if v[0] == Fixnum
v[1].read_int64
elsif v[0] == Float
v[1].read_float
else
byte_size = v[3].read_int64
if v[0] == String
v[1].read_string(byte_size).force_encoding('utf-8')
else
Marshal.load(v[1].read_bytes(byte_size))
end
end
end
def save_value(h,v)
if h[0] == Fixnum
h[1].write_int64(v)
elsif h[0] == Float
h[1].write_float(v)
else
if h[0] == String
tmp_obj = "#{v}\0"
else
tmp_obj = Marshal.dump(v)
end
str_len = h[2].read_int64
if tmp_obj.bytesize > str_len
h[1].write_string("\0")
puts "#{v.class}: out of memory"
puts v
# puts "-------------------------------"
else
begin
h[1].write_string(tmp_obj)
rescue => e
puts "#{v.class}: #{e.to_s}"
puts v
puts "-------------------------------"
end
h[3].write_int64(tmp_obj.bytesize)
end
end
end
def initialize(data, min_byte_size=256)
self.need_process = true
def process_string(tmp_obj, str_len)
pointer = ProcessShared::SharedMemory.new(:uint8, str_len)
pointer.write_string(tmp_obj)
pointer
end
def process_value(v, min_byte_size)
case v
when String
str_len = v.bytesize * 2
str_len = min_byte_size if str_len < min_byte_size
str_len_obj = ProcessShared::SharedMemory.new(:int64)
str_len_obj.write_int64(str_len)
byte_size_obj = ProcessShared::SharedMemory.new(:int64)
byte_size_obj.write_int64(v.bytesize)
[String, process_string(v, str_len), str_len_obj, byte_size_obj]
when Fixnum
tmp = ProcessShared::SharedMemory.new(:int64)
tmp.write_int64(v)
[Fixnum,tmp]
when Float
tmp = ProcessShared::SharedMemory.new(:float)
tmp.write_float(v)
[Float,tmp]
else
tmp_obj = Marshal.dump(v)
str_len = tmp_obj.bytesize*2
if v.respond_to?(:min_memory)
str_len = [str_len, v.min_memory].max
else
str_len = [str_len, 1000].max
end
str_len_obj = ProcessShared::SharedMemory.new(:int64)
str_len_obj.write_int64(str_len)
byte_size_obj = ProcessShared::SharedMemory.new(:int64)
byte_size_obj.write_int64(tmp_obj.bytesize)
[Object, process_string(tmp_obj, str_len), str_len_obj, byte_size_obj]
end
end
case data
when Hash
self.data = data.map do |k,v|
[k,process_value(v, min_byte_size)]
end.to_h
when Array
self.data = data.map{|v| process_value(v, min_byte_size)}
else
self.need_process = false
self.data = process_value(data, min_byte_size)
end
end
def value
if self.need_process
case self.data
when Hash
self.data.map{|k,v| [k,parse_value(v)]}.to_h
when Array
self.data.map{|v| parse_value(v)}
end
else
parse_value(self.data)
end
end
def value=(v)
if self.need_process
raise 'You cannot change value.'
else
save_value(self.data,v)
end
end
def [](k)
parse_value(self.data[k])
end
def []=(k,v)
save_value(self.data[k],v)
end
end