/// <summary> /// Write FBQE /// </summary> /// <param name="f"></param> private void SerializeFBQE(FBQE f) { VSLib.CopyBytes(buffer, VSLib.ConvertStringToByte(DEFS.FBQE_SIGNATURE), f.address + SG_POS, SG_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_START), f.address + ADDRESS_START_POS, ADDRESS_START_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_END), f.address + ADDRESS_END_POS, ADDRESS_END_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.LENGTH), f.address + LENGTH_POS, LENGTH_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.PREV), f.address + PREV_POS, PREV_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.NEXT), f.address + NEXT_POS, NEXT_LEN); F_Object.Write(f.address, VSLib.GetByteArray(buffer, f.address, FBQE_LENGTH), FBQE_LENGTH); }
internal const long FBQE_HEADER_LENGTH = LAST_Q_POS + LAST_Q_LEN + 4; // 4-reserve /////////////////////////////////////////////////// ///////////////////// METHODS ///////////////////// /////////////////////////////////////////////////// /// <summary> /// Get by index /// </summary> /// <param name="idx"></param> /// <returns></returns> public FBQE GetFBQE(int idx) { FBQE f = new FBQE(); f.index = idx; f.address = idx * FBQE_LENGTH; f.SG = VSLib.ConvertByteToString(VSLib.GetByteArray(buffer, f.address + SG_POS, SG_LEN)); f.ADDRESS_START = VSLib.ConvertByteToLong(VSLib.GetByteArray(buffer, f.address + ADDRESS_START_POS, ADDRESS_START_LEN)); f.ADDRESS_END = VSLib.ConvertByteToLong(VSLib.GetByteArray(buffer, f.address + ADDRESS_END_POS, ADDRESS_END_LEN)); f.LENGTH = VSLib.ConvertByteToLong(VSLib.GetByteArray(buffer, f.address + LENGTH_POS, LENGTH_LEN)); f.PREV = VSLib.ConvertByteToInt(VSLib.GetByteArray(buffer, f.address + PREV_POS, PREV_LEN)); f.NEXT = VSLib.ConvertByteToInt(VSLib.GetByteArray(buffer, f.address + NEXT_POS, NEXT_LEN)); if (f.SG != DEFS.FBQE_SIGNATURE) { throw new VSException(DEFS.E0006_INVALID_SIGNATURE_CODE, "(FBQE)"); } return(f); }
public VSFreeSpaceManager(VSpace _sp) { Space = _sp; vm = Space.VM; long hdr_address = Space.GetFirstAddress(DEFS.POOL_FREE_SPACE); if (hdr_address == 0) { // Initialization // 1. Create H-block (header) H_Object = new VSAllocation(vm, DEFS.FBQE_HEADER_ADDRESS, DEFS.FBQE_HEADER_LENGTH_FULL, 0); H_Object.Write(0, DEFS.FBQE_HEADER_SIGNATURE); this.MAX = DEFS.FBQE_ALLOCATION_NUMBER; // Max number of FBQE this.FREE = MAX; this.FIRST = -1; this.LAST = -1; this.FIRST_Q = 0; this.LAST_Q = FREE - 1; // 2. Save H-block address (1st object) Space.SetFirstAddress(DEFS.POOL_FREE_SPACE, H_Object.DescriptorAddress); // 1st object // 3. Create 1st FBQE block F_Object = new VSAllocation(vm, H_Object.DescriptorAddress + H_Object.FullLength, (DEFS.FBQE_ALLOCATION_LENGTH + DEFS.BaseDescriptorLength), 0); // 4. Set initial size F_Object.SetSize(DEFS.FBQE_ALLOCATION_LENGTH); buffer = new byte[F_Object.Size]; // Create buffer // 5. Set references F_Object.PREV = H_Object.DescriptorAddress; H_Object.NEXT = F_Object.DescriptorAddress; // Address of the 1st block F-block // 6. Save F-block address (last object) Space.SetLastAddress(DEFS.POOL_FREE_SPACE, F_Object.DescriptorAddress); //last object // 1.3 Initiate Free queue for (int i = 0; i < FREE; i++) { CreateFBQE(i); } BuildBTrees(); // 1.4 Create initial FBQE long fa = F_Object.DescriptorAddress + F_Object.FullLength; // 1st free address AddFBQE(fa, (Space.vm.Size - fa), -1, -1); // Create 1st FBQE } else { H_Object = Space.GetAllocationByDescriptor(hdr_address); F_Object = Space.GetAllocationByDescriptor(H_Object.NEXT); byte[] b = H_Object.ReadBytes(0, FBQE_HEADER_LENGTH); this.v_MAX = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, MAX_POS, MAX_LEN)); this.v_FREE = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, FREE_POS, FREE_LEN)); this.v_FIRST = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, FIRST_POS, FIRST_LEN)); this.v_LAST = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, LAST_POS, LAST_LEN)); this.v_FIRST_Q = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, FIRST_Q_POS, FIRST_Q_LEN)); this.v_LAST_Q = VSLib.ConvertByteToInt(VSLib.GetByteArray(b, LAST_Q_POS, LAST_Q_LEN)); buffer = F_Object.ReadBytes(0, F_Object.Size); // Read buffer BuildBTrees(); } }
/// <summary> /// Load cahce fields /// </summary> private void deserialize() { CURRENT_ALLOC = base.ALLOC; // Create/cleanup fields cache if (FCache == null) { FCache = new List <FieldCache>(32); } else { FCache.Clear(); } // Create cache binary tree FCacheTree = new VSBBTree(FCT_NAME, 32, true); // Read variable data into the buffer byte[] data = base.ReadBytes(base.FIXED, (long)FIELDS_SIZE); int offset = FIRST_FIELD_OFFSET_REL; // Offset inside buffer (relative, doesn't include fixed part) int n = (int)FIELDS_NUMBER; // Number of fields // Load fields for (int i = 0; i < n; i++) { // Create field FieldCache f = new FieldCache(); f.OFFSET = offset; // Field offset in object f.TYPE = data[offset + FIELD_TYPE_POS]; // Field type byte name_length = data[offset + FIELD_NAME_LENGTH_POS]; // Name length f.NAME = VSLib.ConvertByteToString(VSLib.GetByteArray(data, (int)(offset + FIELD_NAME_POS), (int)name_length)); // Name int value_offset = FIELD_FIXED_LENGTH + name_length; // Value offset // Get value depending on type if ((f.TYPE == FIELD_TYPE_BYTE) | (f.TYPE == FIELD_TYPE_SHORT) | (f.TYPE == FIELD_TYPE_DATETIME)) { f.DATA_OFFSET = value_offset; // Shift to value offset f.LENGTH = FIELD_LENGTHS[f.TYPE]; } else if ((f.TYPE == FIELD_TYPE_INT) | (f.TYPE == FIELD_TYPE_LONG)) { f.DATA_OFFSET = value_offset + 1; // Shift to value offset (+ 1 byte length) f.LENGTH = (int)data[offset + value_offset]; } else if ((f.TYPE == FIELD_TYPE_BYTES) | (f.TYPE == FIELD_TYPE_STRING)) { int l = (int)data[offset + value_offset]; // Read number of length bytes if (l > 0) { byte[] ba = VSLib.GetByteArray(data, (int)(offset + value_offset + 1), (int)l); // Read length f.LENGTH = VSLib.ConvertByteToInt(decompress(ba, FIELD_TYPE_LONG)); } else { f.LENGTH = 0; } f.DATA_OFFSET = value_offset + 1 + l; } else { throw new VSException(DEFS.E0029_INVALID_FIELD_TYPE_CODE, "- " + f.TYPE.ToString()); } f.OLDLENGTH = f.LENGTH; f.STATE = STATE_LOADED; f.FULL_LENGTH = f.DATA_OFFSET + f.LENGTH; if (f.LENGTH > 0) { f.VALUE = VSLib.GetByteArray(data, (int)(offset + f.DATA_OFFSET), (int)f.LENGTH); } else { f.VALUE = new byte[0]; } offset += f.FULL_LENGTH; f.DELETED = false; // Add to cache FCache.Add(f); // Add to the tree FCacheTree.Insert(f.NAME, i); } FreeSpace = (int)(this.Size - base.FIXED - offset); }