Exemplo n.º 1
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);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Return unused pool number
        /// </summary>
        /// <returns></returns>
        public short GetFreePoolNumber()
        {
            long n = A_POOL_DYNAMIC.Size / DEFS.SYSTEM_POOL_DESCRIPTOR_LENGTH;

            for (int iteration = 0; iteration < 2; iteration++)
            {
                for (long i = 0; i < n; i++)
                {
                    long a = A_POOL_DYNAMIC.ReadLong(i * DEFS.SYSTEM_POOL_DESCRIPTOR_LENGTH);
                    if (a == 0)
                    {
                        return((short)(i + DEFS.POOL_MIN_DYNAMIC));
                    }
                }
                ExtendSpace(A_POOL_DYNAMIC, DEFS.ALLOCATION_DYNAMIC);
            }
            return(-1);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Get/set pool descriptot address (first or last)
        /// </summary>
        /// <param name="pool"></param>
        /// <param name="op">0 - read; 1 - write</param>
        /// <param name="n">0 - first; 1 - last</param>
        /// <param name="value">optional. of op=1 only</param>
        /// <returns></returns>
        private long PoolDescriptorAddressIO(int pool, int op, int n, long value = 0)
        {
            long offs = (n == 0) ? 0 : 8;                                               // Offset in the descriptor
            long addr = 0;

            if (pool < DEFS.POOL_MIN_USER_DEFINED)
            { // System pool
                if (Math.Abs(pool) >= DEFS.SYSTEM_POOL_DESCRIPTOR_NUMBER)
                {
                    throw new VSException(DEFS.E0012_INVALID_POOL_NUMBER_CODE, "- " + pool.ToString());
                }

                addr = DEFS.SYSTEM_POOL_AREA_ADDRESS + (long)(Math.Abs(pool) * DEFS.SYSTEM_POOL_DESCRIPTOR_LENGTH + offs);

                if (op == 0)
                {
                    return(vm.ReadLong(addr));
                }
                else
                {
                    vm.Write(addr, value);
                    return(0);
                }
            }
            else if (pool < DEFS.POOL_MIN_DYNAMIC)
            { // User-defined
                addr = (pool - DEFS.POOL_MIN_USER_DEFINED) * DEFS.SYSTEM_POOL_DESCRIPTOR_LENGTH + offs;

                while (addr >= A_POOL_USER_DEFINED.Size)
                {
                    ExtendSpace(A_POOL_USER_DEFINED, DEFS.ALLOCATION_USER_DEFINED);            // Extend if needed
                }
                if (op == 0)
                {
                    return(A_POOL_USER_DEFINED.ReadLong(addr));
                }
                else
                {
                    A_POOL_USER_DEFINED.Write(addr, value);
                    return(0);
                }
            }
            else
            { // Dynamic
                addr = (pool - DEFS.POOL_MIN_DYNAMIC) * DEFS.SYSTEM_POOL_DESCRIPTOR_LENGTH + offs;

                while (addr >= A_POOL_DYNAMIC.Size)
                {
                    ExtendSpace(A_POOL_USER_DEFINED, DEFS.ALLOCATION_DYNAMIC);                 // Extend if needed
                }
                if (op == 0)
                {
                    return(A_POOL_DYNAMIC.ReadLong(addr));
                }
                else
                {
                    A_POOL_DYNAMIC.Write(addr, value);
                    return(0);
                }
            }
        }
Exemplo n.º 5
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);
        }