Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import System
- import System.IO
- import System.Collections.Generic
- import System.Runtime.InteropServices
- import System.IO.MemoryMappedFiles
- struct memblock:
- """
- блок памяти
- """
- static _delta as int
- static delta as int:
- get:
- if _delta == 0:
- _delta = Marshal.SizeOf(memblock)
- return _delta
- static def size_type(type as Type):
- """
- из-за глюка Marshal.SizeOf(char) == 1
- """
- if type == char:
- return 2
- return Marshal.SizeOf(type)
- public length as int //длинна содержащегося блока
- size as int:
- //блок со структурой
- get:
- add = (length % 4) //выравнивание границы блока
- if add:
- add = 4 - add
- return delta + length + add
- def constructor(count as int, type as Type):
- length = count * size_type(type)
- struct root_data:
- d_free as int//смещение первого свободного блока
- d_new as int //смещение чистой памяти
- d_root_obj as int //рутовый объект
- class datamap_file:
- """
- управляющая структура
- """
- root_obj as int:
- get:
- return root.d_root_obj
- set:
- root.d_root_obj = value
- use_size as int:
- get:
- return root.d_new
- mmf as MemoryMappedFile
- accessor as MemoryMappedViewAccessor
- root as root_data
- //хранение соответствий адрес - объект
- public map_objects = Dictionary[of int, object]()
- def constructor(fname as string, size as int):
- exist = File.Exists(fname)
- mmf = MemoryMappedFile.CreateFromFile(fname, FileMode.OpenOrCreate, fname, size)
- accessor = mmf.CreateViewAccessor()
- if exist:
- root = load[of root_data](0)
- else:
- root.d_new = memblock(1,root_data).size
- save_root()
- def save_root():
- """
- вызывать всегда после коррекции базы
- """
- accessor.Write[of root_data](memblock.delta, root)
- def free(delta_block as int):
- """
- освободить массив по смещению array_index
- """
- delta = memblock.delta + delta_block
- accessor.Write(delta, root.d_free)
- root.d_free = delta_block
- def try_from_free(need_size as int):
- if root.d_free:
- o as memblock
- prev_delta = 0
- free_delta = root.d_free
- while free_delta:
- accessor.Read[of memblock](free_delta, o)
- if o.size >= need_size:
- if prev_delta:
- //смещение следующего за free
- next_free as int
- accessor.Read[of int](o.delta + free_delta, next_free)
- accessor.Write(o.delta + prev_delta,next_free) //записать предыдущему
- else: //это первый блок
- root.d_free = 0
- return free_delta
- prev_delta = free_delta
- accessor.Read[of int](o.delta + free_delta, free_delta)
- return 0
- def write[of T(struct)](dinfo as T, ref delta as int):
- """
- загрузить первое T из блока по смещению delta
- """
- delta = alloc(1,T) if not delta
- accessor.Write[of T](delta + memblock.delta, dinfo)
- def write_arr[of T(struct)](arr as (T), ref delta as int):
- """
- загрузить первое T из блока по смещению delta
- """
- count = arr.Length
- if not delta:
- delta = alloc(count,T) if count
- else:
- if count == 0:
- free(delta)
- delta = 0
- else:
- block as memblock
- accessor.Read[of memblock](delta, block)
- size = block.length / memblock.size_type(T)
- if size < count:
- free(delta)
- delta = alloc(count,T)
- else:
- requiest = memblock(count, T)
- if block != requiest:
- accessor.Write[of memblock](delta, requiest)
- if delta:
- accessor.WriteArray[of T](delta + memblock.delta, arr, 0, count)
- def write_string(str as string, ref delta as int):
- write_arr[of Char](str.ToCharArray(), delta)
- def load[of T(struct)](delta as int):
- """
- загрузить первое T из блока по смещению delta
- """
- dinfo as T
- accessor.Read[of T](delta + memblock.delta, dinfo)
- return dinfo
- def load_arr[of T(struct)](delta as int):
- """
- загрузить массив T из блока по смещению delta
- """
- dinfo as memblock
- accessor.Read[of memblock](delta, dinfo)
- size = dinfo.length / memblock.size_type(T)
- res = array(T, size)
- accessor.ReadArray[of T](delta + memblock.delta, res, 0, size)
- return res
- def load_string(delta as int):
- arr = load_arr[of Char](delta)
- return string(arr)
- def alloc(leng as int, type as Type):
- """
- рассчитать смещение массива и разметить
- """
- block = memblock(leng, type)
- delta = try_from_free(block.size)
- if delta == 0:
- delta = root.d_new
- root.d_new += block.size
- accessor.Write[of memblock](delta, block)
- return delta
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement