diff --git a/temp_file/config/process_share_wrapper.rb b/temp_file/config/process_share_wrapper.rb new file mode 100644 index 0000000..839a3c1 --- /dev/null +++ b/temp_file/config/process_share_wrapper.rb @@ -0,0 +1,132 @@ +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 \ No newline at end of file