Exemple #1
0
        /// <summary>
        /// Shrink space
        /// </summary>
        internal void ShrinkObject(VSObject o, long new_size)
        {
            if (o.Chunk == 1)
            {
                long         current_size = o.Size;
                VSAllocation a            = o.LastChunk;
                while ((current_size - a.Length) >= new_size)
                {
                    VSAllocation prev_alloc = a.PrevChunk;


                    if (prev_alloc.Chunk == 1)          // 1st segment
                    {
                        o.LAST  = 0;
                        o.Chunk = 0;
                    }
                    else
                    {
                        o.LAST           = prev_alloc.DescriptorAddress;
                        prev_alloc.Chunk = (short)(prev_alloc.Chunk * (-1));
                    }

                    current_size -= a.Length;
                    o.SetSize(current_size);
                    FreeSpaceSegment(a, false);
                    a = prev_alloc;
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Free space by allocation address (protected)
        /// </summary>
        internal void Free(VSAllocation a, bool deleteID = true)
        {
            VSAllocation nxt = null;

            if (a.Chunk != 0)
            {
                nxt = GetAllocationByDescriptor(a.NEXT);
            }

            FreeSpaceSegment(a, deleteID);

            while (nxt != null)
            {
                long  nextAddr = nxt.NEXT;
                short ch       = nxt.Chunk;
                FreeSpaceSegment(nxt, false);
                if ((nextAddr > 0) & (ch > 0))
                {
                    nxt = GetAllocationByDescriptor(nextAddr);
                }
                else
                {
                    nxt = null;
                }
            }
        }
Exemple #3
0
        /************************************************************************************/
        /************************   Space management    *************************************/
        /************************************************************************************/
        /************************************************************************************/
        /******************   Protected space management (system methods) *******************/
        /************************************************************************************/

        /// <summary>
        /// Allocate space
        /// </summary>
        /// <param name="size"></param>
        /// <param name="pool"></param>
        /// <param name="generateID"></param>
        /// <returns></returns>
        internal VSAllocation ALLOCATE_SPACE(long size, short pool, bool generateID = true, long chunk = 0, short fixed_size = 0)
        {
            long ch = size;
            long s  = 0;

            if (chunk > 0)
            {
                ch = chunk;
            }

            VSAllocation a = AllocateSpaceSegment(ch, pool, generateID);

            a.FIXED     = (ushort)fixed_size;
            a.ChunkSize = (int)chunk;

            s += ch;
            while (s < size)
            {
                long a_size = (ch > (size - s)) ? (size - s) : ch;
                AllocateSpaceSegment(a_size, 0, false, a);
                s += a_size;
            }

            return(a);
        }
Exemple #4
0
        /// <summary>
        /// Update refrence by Key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public void Update(long key, VSAllocation a)
        {
            long[] ret = this.SearchKey(key);

            if (ret[2] >= 0)
            {
                KeyBlockAllocWrite.Write((ret[2] * KeyBlockDef.BLOCK_ITEM_LENGTH) + KeyBlockDef.A_Address, a.DescriptorAddress);
            }
        }
Exemple #5
0
        /// <summary>
        /// Delete this node and free space
        /// </summary>
        public bool Delete()
        {
            //VSDebug.StopPoint(this.ID, 41);
            bool root_deleted = ((PARENT == 0) & (LEFT == 0) & (RIGHT == 0));

            sp.Free(ALLOCATION);
            ALLOCATION = null;
            return(root_deleted);
        }
Exemple #6
0
        /// <summary>
        /// Initialize data structures
        /// </summary>
        private void Initialize()
        {
            KeyHeader = new KeyHeaderDef();

            // Get root allocation
            KeyHeaderAlloc = sp.GetRootAllocation(DEFS.POOL_KEY);

            // If ROOT doesn't exist yet - initial allocation
            if (KeyHeaderAlloc == null)
            {
                // Allocate header space
                KeyHeaderAlloc = sp.AllocateSpace(KeyHeaderDef.KEYROOT_SIZE, DEFS.POOL_KEY, generateID: false);
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorLast, -1);

                // Allocate descriptor space
                KeyDescriptorAlloc = sp.AllocateSpace(KeyDescriptorDef.DESCRIPTOR_CHUNK_SIZE, DEFS.POOL_KEY, generateID: false);

                //Set initial values to memory object
                KeyHeader.DescriptorAddress = KeyDescriptorAlloc.DescriptorAddress;
                KeyHeader.DescriptorLength  = KeyDescriptorDef.DESCRIPTOR_CHUNK_LENGTH;
                KeyHeader.DescriptorLast    = -1;
                KeyHeader.DescriptorUsed    = 0;
                KeyHeader.LastKey           = 0;

                // Save initial values
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorAddress, KeyHeader.DescriptorAddress);
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorLength, KeyHeader.DescriptorLength);
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorLast, KeyHeader.DescriptorLast);
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorUsed, KeyHeader.DescriptorUsed);
                KeyHeaderAlloc.Write(KeyHeaderDef.A_LastKey, KeyHeader.LastKey);

                // Create descriptor
                KeyDescriptor = new KeyDescriptorDef[KeyHeader.DescriptorLength];
            }
            else
            {
                // Read header
                KeyHeader.DescriptorAddress = KeyHeaderAlloc.ReadLong(KeyHeaderDef.A_DescriptorAddress);
                KeyHeader.DescriptorLength  = KeyHeaderAlloc.ReadInt(KeyHeaderDef.A_DescriptorLength);
                KeyHeader.DescriptorLast    = KeyHeaderAlloc.ReadInt(KeyHeaderDef.A_DescriptorLast);
                KeyHeader.DescriptorUsed    = KeyHeaderAlloc.ReadInt(KeyHeaderDef.A_DescriptorUsed);
                KeyHeader.LastKey           = KeyHeaderAlloc.ReadLong(KeyHeaderDef.A_LastKey);


                // Read descriptor
                KeyDescriptor      = new KeyDescriptorDef[KeyHeader.DescriptorLength];
                KeyDescriptorAlloc = sp.GetAllocationByDescriptor(KeyHeader.DescriptorAddress);

                for (int i = 0; i < KeyHeader.DescriptorLength; i++)
                {
                    KeyDescriptor[i].Address  = KeyDescriptorAlloc.ReadLong((KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH * i) + KeyDescriptorDef.A_Address);
                    KeyDescriptor[i].FirstKey = KeyDescriptorAlloc.ReadLong((KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH * i) + KeyDescriptorDef.A_FirstKey);
                    KeyDescriptor[i].Used     = KeyDescriptorAlloc.ReadInt((KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH * i) + KeyDescriptorDef.A_Used);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Roll Changes (create FBQE for new space, process new allocation)
        /// Call from VSEngine when 'Open' or after extesion
        /// </summary>
        internal void VerifySpaceChanges()
        {
            FreeSpaceMgr = new VSFreeSpaceManager(this);

            // Process new allocations if exists
            short n_new = vm.ReadShort(DEFS.SYSTEM_ALLOCATION_ADDRESS);

            if (n_new > 0)
            {
                long e_address = DEFS.SYSTEM_ALLOCATION_ADDRESS + 2;
                for (int i = 0; i < n_new; i++)
                {
                    long fstart = vm.ReadLong(e_address);
                    long fend   = vm.ReadLong(e_address + 8);
                    if (FreeSpaceMgr.LAST < 0)
                    {
                        FreeSpaceMgr.AddFBQE(fstart, fend - fstart, FreeSpaceMgr.LAST, -1);
                    }
                    else
                    {
                        VSFreeSpaceManager.FBQE fp = FreeSpaceMgr.GetFBQE(FreeSpaceMgr.LAST);
                        if (fp.ADDRESS_END == fstart)      //Extend last FBQE
                        {
                            FreeSpaceMgr.UpdateFBQE(FreeSpaceMgr.LAST, fp.ADDRESS_START, fp.LENGTH + fend - fstart);
                        }
                        else
                        {
                            FreeSpaceMgr.AddFBQE(fstart, fend - fstart, FreeSpaceMgr.LAST, -1);
                        }
                    }
                    e_address += 16;
                }
                // Cleanup allocation table
                vm.Write(DEFS.SYSTEM_ALLOCATION_ADDRESS, (short)0);

                // Expand FBQE block if needed
                FreeSpaceMgr.CheckFreeQueueSize();
            }

            //Initialize KeyHelper
            key_manager = new VSKeyManager(this);

            //Check pool areas descriptors, create if nulls
            A_POOL_USER_DEFINED = GetRootAllocation(DEFS.POOL_USER_DEFINED);
            if (A_POOL_USER_DEFINED == null)
            {
                A_POOL_USER_DEFINED = AllocateSpace(DEFS.ALLOCATION_USER_DEFINED, DEFS.POOL_USER_DEFINED, false, 0);
            }

            A_POOL_DYNAMIC = GetRootAllocation(DEFS.POOL_DYNAMIC);
            if (A_POOL_DYNAMIC == null)
            {
                A_POOL_DYNAMIC = AllocateSpace(DEFS.ALLOCATION_DYNAMIC, DEFS.POOL_DYNAMIC, false, 0);
            }
        }
Exemple #8
0
        /// <summary>
        /// Free space by ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int ReleaseID(long id)
        {
            VSAllocation a = GetAllocation(id);

            if (a == null)
            {
                return(-1);
            }
            Free(a);
            return(0);
        }
Exemple #9
0
        /// <summary>
        /// Return index of the descriptor item of -1 - not found
        /// </summary>
        /// <param name="key"></param>
        /// <returns>
        /// ret[0] - object address (if found); -1 - not found;
        /// ret[1] - descriptor index (if found)
        /// ret[2] - block index (if found)
        /// </returns>
        private long[] SearchKey(long key)
        {
            long[] ret = new long[3];
            ret[0] = -1;
            ret[1] = -1;
            ret[2] = -1;

            long lastk = 0;

            // 1. Check last used block
            if (KeyBlockReadIndex >= 0)                                                           // Not 1st search
            {
                lastk = KeyDescriptor[KeyBlockReadIndex].FirstKey + KeyBlockDef.BLOCK_LENGTH - 1; // Last key in block
                if ((key < KeyDescriptor[KeyBlockReadIndex].FirstKey) | (key > lastk))
                {
                    KeyBlockReadIndex = -1;
                }
            }

            // 2. No last used - find descriptor
            if (KeyBlockReadIndex < 0)
            {
                for (int i = KeyHeader.DescriptorLast; i >= 0; i--)
                {
                    if (KeyDescriptor[i].Used > 0)
                    {
                        lastk = KeyDescriptor[i].FirstKey + KeyBlockDef.BLOCK_LENGTH - 1;      // Last key in block
                        if ((key >= KeyDescriptor[i].FirstKey) & (key <= lastk))
                        {
                            KeyBlockReadIndex = i;
                            break;
                        }
                    }
                }
            }

            // 3. Descriptor found - check if key is allocated
            if (KeyBlockReadIndex >= 0)
            {
                KeyBlockAllocWrite = sp.GetAllocationByDescriptor(KeyDescriptor[KeyBlockReadIndex].Address);
                long obj_index = key - KeyDescriptor[KeyBlockReadIndex].FirstKey;
                long addr      = (obj_index * KeyBlockDef.BLOCK_ITEM_LENGTH) + KeyBlockDef.A_Address;
                long obj_addr  = KeyBlockAllocWrite.ReadLong(addr);
                if (obj_addr >= 0)
                {
                    ret[0] = obj_addr;
                    ret[1] = KeyBlockReadIndex;
                    ret[2] = obj_index;
                }
            }

            // Assuming KeyBlockAlloc is loaded if ret[0] >= 0
            return(ret);
        }
Exemple #10
0
        /// <summary>
        /// Create object
        /// </summary>
        /// <param name="size"></param>
        /// <param name="pool"></param>
        /// <param name="chunk"></param>
        /// <returns></returns>
        public VSObject Allocate(long size, short pool, long chunk = 0, short fixed_size = 0)
        {
            // Cannot be a system pool (0 or less)
            if (pool < 1)
            {
                throw new VSException(DEFS.E0012_INVALID_POOL_NUMBER_CODE, "- " + pool.ToString() + " (Allocate)");
            }

            VSAllocation a = ALLOCATE_SPACE(size, pool, true, chunk, fixed_size);

            return(GetObject(a.Id));
        }
Exemple #11
0
        ///////////////////////////////////////////////////////////////////
        ///////////  METHODS //////   /////////////////////////////////////
        ///////////////////////////////////////////////////////////////////
        /// <summary>
        /// Read node
        /// </summary>
        /// <param name="id"></param>
        public void Read(long id)
        {
            //VSDebug.StopPoint(id, 1323);
            ALLOCATION = sp.GetAllocation(id);

            string s = ALLOCATION.ReadString(0, 4);

            if (s != DEFS.AVL_SIGNATURE)
            {
                throw new VSException(DEFS.E0006_INVALID_SIGNATURE_CODE, "- VSAVL, at address 0x" + ALLOCATION.Address.ToString("X"));
            }
        }
Exemple #12
0
        /// <summary>
        /// Constructor - read index descriptor
        /// </summary>
        /// <param name="s"></param>
        /// <param name="addr"></param>
        internal VSIndex(VSpace space, long addr)
        {
            this.sp = space;

            this.ALLOCATION = sp.GetAllocationByDescriptor(addr);

            string s = ALLOCATION.ReadString(0, 4);

            if (s != DEFS.INDEX_SIGNATURE)
            {
                throw new VSException(DEFS.E0006_INVALID_SIGNATURE_CODE, " (Index Descriptor)");
            }
            this.space_name = DEFS.ParseIndexSpace(this.Name);
            this.index_name = DEFS.ParseIndexName(this.Name);
        }
Exemple #13
0
        /// <summary>
        /// Delete index
        /// </summary>
        internal void purge()
        {
            if (ALLOCATION == null)
            {
                return;
            }

            // Delete all cross-references

            if (POOL > 0)
            {
                sp.ReleasePool(POOL);                // Delete all nodes
            }
            sp.Free(ALLOCATION);                     // Delete descriptor

            ALLOCATION = null;
        }
Exemple #14
0
        /// <summary>
        /// Free all pool data
        /// </summary>
        /// <param name="n"></param>
        public void ReleasePool(short n)
        {
            if (n < 1)
            {
                throw new VSException(DEFS.E0014_INVALID_POOL_NUMBER_CODE, "- " + n.ToString());
            }

            long addr = GetRootAddress(n);

            while (addr > 0)
            {
                VSAllocation a = GetAllocationByDescriptor(addr);
                addr = a.NEXT;

                FreeSpaceSegment(a);
                addr = GetRootAddress(n);
            }
        }
Exemple #15
0
        /// <summary>
        /// Constructor - create index descriptor
        /// </summary>
        /// <param name="s"></param>
        /// <param name="name"></param>
        /// <param name="unique"></param>
        internal VSIndex(VSpace space, string name, bool unique)
        {
            this.sp = space;

            this.ALLOCATION = sp.AllocateSpace(VSIndex.INDEX_DESCRIPTOR_LEN, DEFS.POOL_INDEX, true);

            this.ALLOCATION.Write(0, DEFS.INDEX_SIGNATURE);

            this.Name = name.Trim().ToLower();

            this.ROOT = 0;

            this.POOL = 0;

            this.UNIQUE = (short)(unique ? 1 : 0);

            this.space_name = DEFS.ParseIndexSpace(this.Name);
            this.index_name = DEFS.ParseIndexName(this.Name);
        }
Exemple #16
0
        /// <summary>
        /// Create new node
        /// </summary>
        /// <returns>id</returns>
        public long Create(byte[] key, long value, long parent, short pool)
        {
            long base_size = VARIABLE_POS + key.Length + 8;

            long alloc_size = (ix.UniqueIndex) ? base_size : DEFS.MIN_SPACE_ALLOCATION_CHUNK * 2;

            this.ALLOCATION = sp.AllocateSpace(alloc_size, pool);

            this.SG = DEFS.AVL_SIGNATURE;

            this.REF_COUNT = 1;

            this.KEYLEN = key.Length;

            this.ALLOCATION.Write(KEY_POS, key, key.Length);

            this.PARENT = parent;

            this.INDEX = ix.Id;            // Index Id

            this.REF = value;              // 1st ref value

            return(ID);
        }
Exemple #17
0
        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 #18
0
        /// <summary>
        /// Create new KEY for address
        /// If use_key > 0 then add specified key (used by restore)
        /// If alloc=null - add 0 address (restore)
        /// </summary>
        /// <returns>new SID</returns>
        public long Add(VSAllocation alloc, long use_key = 0)
        {
            //VSDebug.StopPoint(alloc.Address, 45724);
            long address = (alloc == null) ? 0 : alloc.DescriptorAddress;
            long addr    = 0;

            // 1. Generate new key
            if (use_key > 0)
            {
                if (use_key <= KeyHeader.LastKey)
                {
                    throw new VSException(DEFS.E0023_INVALID_KEY_SEQUENCE_CODE, " Lask key: " + KeyHeader.LastKey.ToString() + " Use key: " + use_key.ToString());
                }
                KeyHeader.LastKey = use_key;
            }
            else
            {
                KeyHeader.LastKey++;
            }

            // Write new key
            KeyHeaderAlloc.Write(KeyHeaderDef.A_LastKey, KeyHeader.LastKey);

            // Lookup place to add
            KeyBlockAllocWrite = null;
            if (KeyHeader.DescriptorLast >= 0)
            {
                if (KeyHeader.LastKey < (KeyDescriptor[KeyHeader.DescriptorLast].FirstKey + KeyBlockDef.BLOCK_LENGTH))
                {
                    KeyBlockAllocWrite = sp.GetAllocationByDescriptor(KeyDescriptor[KeyHeader.DescriptorLast].Address);
                }
            }

            // Not found, allocate new block
            if (KeyBlockAllocWrite == null)
            {
                KeyBlockAllocWrite = sp.AllocateSpace(KeyBlockDef.BLOCK_SIZE, DEFS.POOL_KEY, generateID: false);
                byte[] b = new byte[KeyBlockDef.BLOCK_SIZE];
                // Fill all by -1
                for (int i = 0; i < KeyBlockDef.BLOCK_SIZE; i++)
                {
                    b[i] = 255;
                }
                KeyBlockAllocWrite.Write(0, b, b.Length);

                KeyHeader.DescriptorLast++;
                KeyHeader.DescriptorUsed++;

                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorLast, KeyHeader.DescriptorLast);
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorUsed, KeyHeader.DescriptorUsed);

                // Extend if required
                if (KeyHeader.DescriptorLast == KeyHeader.DescriptorLength)
                {
                    sp.Extend(KeyHeaderAlloc, KeyDescriptorDef.DESCRIPTOR_CHUNK_SIZE);
                    KeyHeader.DescriptorLength += KeyDescriptorDef.DESCRIPTOR_CHUNK_LENGTH;
                    KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorLength, KeyHeader.DescriptorLength);
                }

                KeyDescriptor[KeyHeader.DescriptorLast].FirstKey = KeyHeader.LastKey;
                KeyDescriptor[KeyHeader.DescriptorLast].Address  = KeyBlockAllocWrite.DescriptorAddress;
                KeyDescriptor[KeyHeader.DescriptorLast].Used     = 0;

                addr = KeyHeader.DescriptorLast * KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH;
                KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_Address, KeyDescriptor[KeyHeader.DescriptorLast].Address);
                KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_FirstKey, KeyDescriptor[KeyHeader.DescriptorLast].FirstKey);
            }

            // Write to block
            KeyBlockAllocWrite = sp.GetAllocationByDescriptor(KeyDescriptor[KeyHeader.DescriptorLast].Address);
            addr = ((KeyHeader.LastKey - KeyDescriptor[KeyHeader.DescriptorLast].FirstKey) * KeyBlockDef.BLOCK_ITEM_LENGTH);
            KeyBlockAllocWrite.Write(addr + KeyBlockDef.A_Address, address);

            // Update used
            KeyDescriptor[KeyHeader.DescriptorLast].Used++;
            KeyDescriptorAlloc.Write((KeyHeader.DescriptorLast * KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH) + KeyDescriptorDef.A_Used, KeyDescriptor[KeyHeader.DescriptorLast].Used);

            // Set read cache
            KeyBlockAllocRead = KeyBlockAllocWrite;
            KeyBlockReadIndex = KeyHeader.DescriptorLast;

            // Return key
            return(KeyHeader.LastKey);
        }
Exemple #19
0
        ////////////////////////////////////////////////////////////////////////////////
        //////////////////// I/O METHODS ///////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Read/Write bytes
        /// </summary>
        /// <param name="op">DEFS.OP_READ or DEFS.OP_WRITE</param>
        /// <param name="address"></param>
        /// <param name="data"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        protected void io_protected(int op, long address, ref byte[] data, long length)
        {
            if (length <= 0)
            {
                throw new VSException(DEFS.E0028_INVALID_LENGTH_ERROR_CODE, "- " + length.ToString());
            }

            long r_length  = length;            // Remaining length
            long s_address = 0;                 // Shifted address

            VSAllocation obj      = this;
            bool         eo_chunk = false;

            if (address < this.Length)
            {
                s_address = 0;             // Address is in the current chunk
            }
            else
            { // Search cache
                obj = null;
                for (int i = (SCache.Count - 1); i >= 0; i--)
                {
                    if ((address >= SCache[i].VIRTUAL_ADDRESS) & (address < (SCache[i].VIRTUAL_ADDRESS + SCache[i].LENGTH)))
                    {
                        s_address = SCache[i].VIRTUAL_ADDRESS;
                        obj       = new VSAllocation(vm, SCache[i].DESCRIPTOR_ADDRESS);
                        break;
                    }
                }
                if (obj == null)
                { // NOT found in cache
                    if ((this.Chunk == 0) | (this.NEXT == 0))
                    {
                        eo_chunk = true;
                    }
                    else
                    {
                        obj       = this.NextChunk;
                        s_address = this.Length;
                        while (!eo_chunk)
                        {
                            if (address < (s_address + obj.Length))
                            { // Address is in chunk, add to cache
                                if (SCache.Count == cache_size)
                                {
                                    SCache.RemoveAt(0);
                                }
                                SegmentCache ac = new SegmentCache();
                                ac.VIRTUAL_ADDRESS    = s_address;
                                ac.LENGTH             = obj.Length;
                                ac.DESCRIPTOR_ADDRESS = obj.DescriptorAddress;
                                SCache.Add(ac);
                                break;
                            }
                            else
                            { //start address not in this chunk
                                if ((obj.Chunk > 0) & (obj.NEXT > 0))
                                {
                                    s_address += obj.Length;
                                    obj        = obj.NextChunk;
                                }
                                else
                                {
                                    eo_chunk = true;
                                }
                            }
                        }
                    }
                }
            }

            if (obj != null)
            {
                long l_address = address - s_address;           // Local address in chunk
                long r_address = 0;                             // Relative address in the input array
                while ((obj != null) & (r_length > 0) & !eo_chunk)
                {
                    long l_length = (r_length > (obj.Length - l_address)) ? (obj.Length - l_address) : r_length;
                    vm.Io(obj.Address + l_address, ref data, l_length, op, r_address);
                    l_address  = 0;
                    r_length  -= l_length;
                    r_address += l_length;
                    obj        = obj.NextChunk;
                }
            }
            if ((r_length > 0) | (length <= 0) | (address < 0))
            {
                throw new VSException(DEFS.E0019_INVALID_OP_ADDRESS_ERROR_CODE, "- address " + address.ToString() + "; lenght " + length.ToString());
            }
        }
Exemple #20
0
        /// <summary>
        /// Delete existing ID
        /// </summary>
        /// <param name="sid"></param>
        public int Delete(long key)
        {
            // Get key
            long[] keyloc = SearchKey(key);
            if (keyloc[0] == 0)
            {
                return(-1);
            }

            // Delete key in the block
            long addr = keyloc[2] * KeyBlockDef.BLOCK_ITEM_LENGTH;

            KeyBlockAllocWrite.Write(addr + KeyBlockDef.A_Address, KeyBlockDef.KEY_DELETED);

            // Update descriptor (not last key)
            if (KeyDescriptor[keyloc[1]].Used > 1)
            {
                KeyDescriptor[keyloc[1]].Used--;
                addr = keyloc[1] * KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH;
                KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_Used, KeyDescriptor[keyloc[1]].Used);
            }
            // If last key in the block - free block
            else
            {
                KeyBlockReadIndex = -1;
                KeyBlockAllocRead = null;

                sp.Free(KeyBlockAllocWrite, false);
                KeyDescriptor[keyloc[1]].Used     = 0;
                KeyDescriptor[keyloc[1]].Address  = 0;
                KeyDescriptor[keyloc[1]].FirstKey = 0;
                addr = keyloc[1] * KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH;
                KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_Used, KeyDescriptor[keyloc[1]].Used);
                KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_Address, KeyDescriptor[keyloc[1]].Address);
                KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_FirstKey, KeyDescriptor[keyloc[1]].FirstKey);

                KeyHeader.DescriptorUsed--;
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorUsed, KeyHeader.DescriptorUsed);

                for (int i = 0; i < KeyHeader.DescriptorLength; i++)
                {
                    if (KeyDescriptor[i].Address == 0)
                    {
                        for (int j = i + 1; j < KeyHeader.DescriptorLength; j++)
                        {
                            if (KeyDescriptor[j].Address != 0)
                            {
                                KeyDescriptor[i].Address  = KeyDescriptor[j].Address;
                                KeyDescriptor[i].FirstKey = KeyDescriptor[j].FirstKey;
                                KeyDescriptor[i].Used     = KeyDescriptor[j].Used;

                                KeyDescriptor[j].Address  = 0;
                                KeyDescriptor[j].FirstKey = 0;
                                KeyDescriptor[j].Used     = 0;

                                break;
                            }
                        }
                    }
                }

                // Update header last
                int save_last = KeyHeader.DescriptorLast;
                KeyHeader.DescriptorLast = KeyHeader.DescriptorUsed - 1;
                KeyHeaderAlloc.Write(KeyHeaderDef.A_DescriptorLast, KeyHeader.DescriptorLast);

                // Rewrite header
                for (int i = 0; i <= save_last; i++)
                {
                    addr = i * KeyDescriptorDef.DESCRIPTOR_ITEM_LENGTH;
                    KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_Address, KeyDescriptor[i].Address);
                    KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_FirstKey, KeyDescriptor[i].FirstKey);
                    KeyDescriptorAlloc.Write(addr + KeyDescriptorDef.A_Used, KeyDescriptor[i].Used);
                }
            }
            return(0);
        }
Exemple #21
0
        /// <summary>
        /// Free space
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        private int FreeSpaceSegment(VSAllocation a, bool deleteID = true)
        {
            long  a_prev = a.PREV;
            long  a_next = a.NEXT;
            short a_pool = a.Pool;
            long  a_id   = a.Id;

            // Delete indexes
            if (deleteID & (a_id > 0) & (a_pool > 0))
            {
                if (this.IndexSpace == null)
                {
                    remove_all_indexes("", a_id);                                           // Remove all local indexes
                }
                else
                {
                    this.IndexSpace.remove_all_indexes(this.Name, a_id);                    // Remove all external indexes
                }
            }

            long address = a.DescriptorAddress;

            long length = a.FullLength;

            long end_address = address + length;

            if (end_address > this.vm.Size)
            {
                throw new VSException(DEFS.E0015_INVALID_ADDRESS_CODE, "Address is out of space boundaries - " + address.ToString());
            }

            // Delete index if required
            if (deleteID & (a_id > 0))
            {
                key_manager.Delete(a_id);
            }

            // return space to free and purge it
//            VSDebug.StopPoint(address, 57916);
            FreeSpaceMgr.ReleaseSpace(address, length);

            //Update descriptors
            //Ref to prev
            if (a_prev == 0)
            {
                SetFirstAddress(a_pool, a_next);
            }
            else
            {
                VSAllocation p = GetAllocationByDescriptor(a_prev);
                p.NEXT = a_next;
            }

            //Ref to next
            if (a_next == 0)
            {
                SetLastAddress(a_pool, a_prev);
            }
            else
            {
                VSAllocation n = GetAllocationByDescriptor(a_next);
                n.PREV = a_prev;
            }

            return(0);
        }
Exemple #22
0
        /// <summary>
        /// Get the 1st key
        /// </summary>
        /// <returns></returns>
        public long GetRootID(short pool)
        {
            VSAllocation a = GetAllocationByDescriptor(GetFirstAddress(pool));

            return((a == null) ? 0 : a.Id);
        }
Exemple #23
0
        /************************************************************************************/
        /************************   Memory management (system methods)***********************/
        /************************************************************************************/


        /// <summary>
        /// Allocate space (system method)
        /// </summary>
        /// <param name="size">Allocation size</param>
        /// <param name="pool">Allocation pool. 0 if base_address != 0</param>
        /// <param name="generateID">True id ID is required. false if base_address != 0</param>
        /// <param name="base_address"> 1st allocated address (extend)</param>
        /// <returns>
        /// 0 - address
        /// 1 - ID (or 0)
        /// </returns>
        internal VSAllocation AllocateSpaceSegment(long size, short pool, bool generateID = true, VSAllocation base_alloc = null)
        {
#if (DEBUG)
            __TIMER.START("alloc:main");
#endif

            if ((base_alloc != null) & ((pool != 0) | (generateID == true)))
            {
                throw new VSException(DEFS.E0020_INVALID_EXTENSION_PARAMETERS_ERROR_CODE);
            }

            //VSFreeSpaceManager.FBQE f;
            long alloc_addr  = 0;
            long length_desc = (base_alloc == null)? DEFS.BaseDescriptorLength: DEFS.ExpansionDescriptorLength;       // Descriptor length


            // Calculate allocation size)
            long length = size / DEFS.MIN_SPACE_ALLOCATION_CHUNK;

            if (length == 0)
            {
                length++;
            }
            else if ((length * DEFS.MIN_SPACE_ALLOCATION_CHUNK) < size)
            {
                length++;
            }

            long length_use = (length * DEFS.MIN_SPACE_ALLOCATION_CHUNK);

            length = length_use + length_desc;

            // Acquire free space location
            alloc_addr = FreeSpaceMgr.AcquireSpace(length);

            while (alloc_addr == 0)
            {
                if (vm.Extend() != 0)
                {
                    throw new VSException(DEFS.E0013_SPACE_NOT_AVAILABLE_CODE, "Requested size: " + length.ToString());
                }
                else
                {
                    this.VerifySpaceChanges();         //Process new if space is successfully extended
                }
                alloc_addr = FreeSpaceMgr.AcquireSpace(length);
            }


            short new_pool = pool;

            // If base_address != 0 - take pool# from the root descriptor
            if (base_alloc != null)
            {
                new_pool = base_alloc.Pool;
            }

            // Create allocated space descriptor
            VSAllocation new_obj = new VSAllocation(vm, alloc_addr, length, new_pool);

            long last_obj = GetLastAddress(new_pool);

            VSAllocation prev_obj;
            if (base_alloc == null)
            { // Initial allocation
#if (DEBUG)
                __TIMER.START("alloc:new_alloc");
#endif
#if (DEBUG)
                __TIMER.START("alloc:gen_id");
#endif
                if (generateID)
                {
                    new_obj.Id = key_manager.Add(new_obj);              // Generate ID if required
                }
#if (DEBUG)
                __TIMER.END("alloc:gen_id");
#endif

                if (last_obj == 0)
                { // First allocation for pool
                    SetFirstAddress(new_pool, alloc_addr);
                    SetLastAddress(new_pool, alloc_addr);
                }
                else
                {
                    prev_obj      = GetAllocationByDescriptor(last_obj);
                    prev_obj.NEXT = new_obj.DescriptorAddress;
                    new_obj.PREV  = prev_obj.DescriptorAddress;
                    SetLastAddress(new_pool, new_obj.DescriptorAddress);        // New Last
                }
#if (DEBUG)
                __TIMER.END("alloc:new_alloc");
#endif
            }
            else
            { //Extend
#if (DEBUG)
                __TIMER.START("alloc:extend_obj");
#endif

                prev_obj = base_alloc;
                if (base_alloc.Chunk == 0)
                {
                    base_alloc.Chunk = 1;
                    new_obj.Chunk    = -2;
                }
                else
                {
                    prev_obj = GetAllocationByDescriptor(base_alloc.LAST);
                    short ch = (short)(prev_obj.Chunk * -1);
                    if (ch == DEFS.MAX_SPACE_ALLOCATION_CHUNKS)
                    {
                        throw new VSException(DEFS.E0021_MAX_ALLOCATION_CHUNKS_REACHED_CODE, "- " + DEFS.MAX_SPACE_ALLOCATION_CHUNKS.ToString());
                    }
                    prev_obj.Chunk = ch;
                    new_obj.Chunk  = (short)((ch + 1) * -1);
                }

                base_alloc.LAST = new_obj.DescriptorAddress;                      // New pointer to last

                if (prev_obj.NEXT == 0)
                {
                    prev_obj.NEXT = new_obj.DescriptorAddress;
                    new_obj.PREV  = prev_obj.DescriptorAddress;
                    SetLastAddress(new_pool, new_obj.DescriptorAddress);        // New last
                }
                else
                {
                    VSAllocation next_obj = GetAllocationByDescriptor(prev_obj.NEXT);
                    prev_obj.NEXT = new_obj.DescriptorAddress;
                    new_obj.NEXT  = next_obj.DescriptorAddress;
                    new_obj.PREV  = prev_obj.DescriptorAddress;
                    next_obj.PREV = new_obj.DescriptorAddress;
                }
#if (DEBUG)
                __TIMER.END("alloc:extend_obj");
#endif
            }

            if (base_alloc == null)
            {
                new_obj.SetSize(length_use);
            }
            else
            {
                base_alloc.SetSize(base_alloc.Size + length_use);
            }
#if (DEBUG)
            __TIMER.END("alloc:main");
#endif

            return(new_obj);
        }
Exemple #24
0
        /************************************************************************************/
        /************************   Memory management (system methods)***********************/
        /************************************************************************************/

        /// <summary>
        /// Extend space (protected)
        /// </summary>
        /// <param name="address">Data address to extend</param>
        /// <param name="size">Additional size to add if > 0. Otherwise - min space chunk</param>
        public void Extend(VSAllocation o, long size)
        {
            VSAllocation a = AllocateSpaceSegment(size, 0, false, o);
        }
Exemple #25
0
        /// <summary>
        /// Next node
        /// </summary>
        /// <returns></returns>
        public bool Next()
        {
            if (action == Action.End)
            {
                return(false);
            }

            current = -1;
            // Cases - assuming index is not empty (action !- Action.End)
            // 1. Initial: D_Current < 0
            if (D_current < 0)
            {
                D_current          = 0; // Set 1st desc
                B_current          = -1;
                KeyBlockAllocWrite = null;
                n   = 0;
                NUM = (KeyHeader.DescriptorLast + 1) * KeyBlockDef.BLOCK_LENGTH;      // Total numeber of items in all blocks (including empty and deleted)
            }

            while (n < NUM)
            {
                if (KeyDescriptor[D_current].Used == 0)     // If empty block
                {
                    n += KeyBlockDef.BLOCK_LENGTH;
                    D_current++;
                    B_current = -1;
                }
                else
                {
                    B_current++;
                    if (B_current == KeyBlockDef.BLOCK_LENGTH)   // Out of block
                    {
                        KeyBlockAllocWrite = null;
                        D_current++;
                        B_current = -1;
                    }
                    else                                        // Within block
                    {
                        if (KeyBlockAllocWrite == null)
                        {
                            KeyBlockAllocWrite = sp.GetAllocationByDescriptor(KeyDescriptor[D_current].Address);
                        }

                        if (KeyBlockAllocWrite.ReadLong(B_current * KeyBlockDef.BLOCK_ITEM_LENGTH + KeyBlockDef.A_Address) > 0)
                        {
                            current = KeyDescriptor[D_current].FirstKey + B_current;
                            n++;
                            break;
                        }
                        else
                        {
                            n++;
                        }
                    }
                }
            }


            if (current < 0)
            {
                action = Action.End;
                return(false);
            }


            return(true);
        }
Exemple #26
0
 /// <summary>
 /// Extend space (protected)
 /// </summary>
 /// <param name="address">Data address to extend</param>
 /// <param name="size">Additional size to add if > 0. Otherwise - min space chunk</param>
 internal void ExtendSpace(VSAllocation o, long size)
 {
     VSAllocation a = AllocateSpaceSegment(size, 0, false, o);
 }
Exemple #27
0
        /// <summary>
        /// Dump storage
        /// Space name - 32
        /// System area - 1024
        /// Pool area - 4096
        /// </summary>
        private void dump(VSIO IO, string name)
        {
            bool was_opened = false;

            uint e_code = IO.GetEncryption() ? e_code = DEFS.DATA_ENCRYPTED : e_code = DEFS.DATA_NOT_ENCRYPTED;

            if (state == DEFS.STATE_OPENED)
            {
                if (TA.Started)
                {
                    throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "- Dump (transaction is in progress)");
                }
                was_opened = true;
            }
            else
            {
                Open(null);
            }

            string[] spaces = this.GetSpaceList();
            bool     encr   = IO.GetEncryption();

            IO.SetEncryption(false);

            IO.Write(0, e_code);                                                     // + 0 (4)Encryption indicator

            IO.SetEncryption(encr);

            IO.Write(-1, DEFS.DUMP_SIGNATURE_INCOMPLETE);                            // + 4 (4) Signature 'incomplete'
            IO.Write(-1, (int)0);                                                    // + 8 (4) CRC placeholder
            IO.Write(-1, (long)0);                                                   // +12 (8)Total length


            for (int sp_index = 0; sp_index < spaces.Length; sp_index++)
            {
                VSpace sp = GetSpace(spaces[sp_index]);
                VSVirtualMemoryManager vm = GetVM(spaces[sp_index]);

                if ((name == "") | (VSLib.Compare(name, sp.Name)))
                {
                    long sp_hdr_pos = IO.GetPosition();                          // Position for header(number of bytes)

                    IO.Write(-1, (long)0);

                    // Save space header
                    IO.Write(-1, (short)sp.Name.Length);                             // Space neme length (short)
                    IO.Write(-1, sp.Name);                                           // Space name

                    IO.Write(-1, (short)sp.Owner.Length);                            // Space owner length (short)
                    IO.Write(-1, sp.Owner);                                          // Space owner

                    //////////////////////////////////////////////////////////////
                    // Save keys
                    //////////////////////////////////////////////////////////////
                    IO.Write(-1, DEFS.DUMP_KEYS_SIGNATURE);                                // Start keys
                    VSKeyManager kh = sp.KeyManager;
                    kh.Reset();

                    while (kh.Next())
                    {
                        long k = kh.Current;
                        IO.Write(-1, k);
                    }

                    IO.Write(-1, (long)-1);                                   // End keys

                    // Save pool ares (starting from 2)

                    short[] pools = sp.GetPoolsForDump();                           // Create list of pools

                    for (int i = 0; i < pools.Length; i++)
                    {
                        long a_desc = sp.GetFirstAddress(pools[i]);
                        while (a_desc > 0)
                        {
                            VSAllocation a = sp.GetAllocationByDescriptor(a_desc);

                            //////////// Save ADSC fields ///////////
                            IO.Write(-1, a.Id);
                            IO.Write(-1, a.Pool);

                            IO.Write(-1, (a.Chunk == 0) ? a.Length : a.Size);    // Memory size
                            IO.Write(-1, a.ChunkSize);                           // Chunk sizeMemory size

                            IO.Write(-1, a.ALLOC);                               // Alloc version (object)
                            IO.Write(-1, a.FIXED);                               // Fixed part (object)

                            //////////// Save data //////////////////
                            byte[] b = vm.ReadBytes(a.Address, a.Length);
                            IO.Write(-1, ref b);
                            a_desc = a.NEXT;
                            if (a.Chunk != 0)
                            {
                                while (a_desc != 0)
                                {
                                    a = sp.GetAllocationByDescriptor(a_desc);
                                    if ((a.Chunk == 0) | (a.Chunk == 1))
                                    {
                                        break;
                                    }
                                    b = vm.ReadBytes(a.Address, a.Length);
                                    IO.Write(-1, ref b);
                                    a_desc = a.NEXT;
                                }
                            }
                        }
                    }
                    long sp_count    = IO.GetPosition() - sp_hdr_pos;           // Calculate count
                    long current_pos = IO.GetPosition();                        // Save current position
                    IO.Write(sp_hdr_pos, sp_count);                             // Write count to the header (incl hdr)
                    IO.SetPosition(current_pos);                                // Restore position
                }
            }

            IO.Write(-1, (long)-1);                                      // Write eof indicator

            IO.Write(12, (long)IO.GetLength());                          // + 8 (8) - Total length

            IO.Flush();

            uint c = IO.GetCRC32(12, -1);                                // calculate CRC32

            IO.Write(8, c);                                              // + 4 (4) - CRC32

            IO.Write(4, DEFS.DUMP_SIGNATURE);                            // Signature 'complete'

            IO.Flush();

            if (!was_opened)
            {
                Close();
            }
        }