/// <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();
            }
        }
Exemple #4
0
        /// <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);
        }