예제 #1
0
파일: VSpace.cs 프로젝트: ivvinokurov/VSX
        /// <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);
            }
        }
예제 #2
0
        /// <summary>
        /// Return allocated space to the free queue: update FBQE chain and trees
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        public void ReleaseSpace(long address, long length)
        {
            //VSDebug.StopPoint(address, 3740160);
            CheckFreeQueueSize();

            VSBBTree.BTResult res1 = BT_FBQE_Address.Find(address, VSBBTree.COND_LT);
            VSBBTree.BTResult res2;

            if (res1.Key < 0)               // Update 1st or insert befor 1st - left not found
            {
                // Address is before 1st FBQE. Insert new before 1st or extend 1st (new start address)
                if (this.FIRST < 0)
                {
                    AddFBQE(address, length, -1, this.FIRST);
                }
                else
                {
                    FBQE f = GetFBQE(this.FIRST);
                    if (f.ADDRESS_START == (address + length))                          // Extend 1st FBQE
                    {
                        UpdateFBQE(this.FIRST, address, f.LENGTH + length);
                    }
                    else
                    {
                        AddFBQE(address, length, -1, this.FIRST);                       // Insert new FBQE at the top of the queue
                    }
                }
            }
            else
            {
                res2 = BT_FBQE_Address.Find(address, VSBBTree.COND_GT);
                if (res2.Key < 0)                                                       // Extend last or append
                {
                    FBQE f = GetFBQE(this.LAST);
                    if (f.ADDRESS_END == address)                                       // Extend last
                    {
                        UpdateFBQE(this.LAST, f.ADDRESS_START, f.LENGTH + length);      // Extend
                    }
                    else
                    {
                        AddFBQE(address, length, this.LAST, -1);                        // Append FBQE
                    }
                }
                else
                {
                    FBQE f1 = GetFBQE((int)res1.Value);
                    FBQE f2 = GetFBQE((int)res2.Value);
                    if ((address > f1.ADDRESS_END) & ((address + length) < f2.ADDRESS_START))
                    {
                        this.AddFBQE(address, length, f1.index, f2.index);              //insert new between f1 and f2
                    }
                    else                                                                // Otherwise merge with left, right or both
                    {
                        if ((address == f1.ADDRESS_END) & ((address + length) == f2.ADDRESS_START))
                        {
                            // Merge all
                            UpdateFBQE(f1.index, f1.ADDRESS_START, f1.LENGTH + f2.LENGTH + length);
                            DeleteFBQE(f2.index);
                        }
                        else if (address == f1.ADDRESS_END)
                        {
                            // Merge with left (f1)
                            UpdateFBQE(f1.index, f1.ADDRESS_START, f1.LENGTH + length);      // Extend f1 (append)
                        }
                        else
                        {
                            // Merge with right (f2)
                            UpdateFBQE(f2.index, address, f2.LENGTH + length);              // Extend f2 (insert)
                        }
                    }
                }
            }

            //Clear memory
            byte[] b = new byte[length];
            vm.Write(address, b, length);
        }
예제 #3
0
 /// <summary>
 /// Set object full size - all chunks (descriptor length is NOT included))
 /// </summary>
 /// <param name="s"></param>
 internal void SetSize(long s)
 {
     vm.Write(DescriptorAddress + SIZE_POS, s);
 }
예제 #4
0
파일: VSEngine.cs 프로젝트: ivvinokurov/VSX
        /// <summary>
        /// Restore storage
        /// </summary>
        public void restore(VSIO IO, string name = "*")
        {
            byte[] buf;                            // Buffer

            // Check database state
            if (state != DEFS.STATE_DEFINED)
            {
                throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "- 'Restore' (storage is opened or undefined)");
            }

            // Check if length not less than 16
            if (IO.GetLength() < 32)
            {
                throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "Restore - invalid source stream (wrong source length)");
            }

            // Check encryption
            IO.SetEncryption(false);
            uint encr = IO.ReadUInt(0);

            IO.SetEncryption(encr == DEFS.DATA_ENCRYPTED);

            // Check signature
            string sig = IO.ReadString(-1, DEFS.DUMP_SIGNATURE.Length);

            if (sig != DEFS.DUMP_SIGNATURE)
            {
                throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "Restore - invalid source stream (wrong signature)");
            }

            // Check CRC
            uint old_crc = IO.ReadUInt(-1);

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

            if (old_crc != new_crc)
            {
                throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "Restore - invalid source stream (wrong CRC)");
            }

            // Check source length vs saved
            long slen = IO.ReadLong(-1);

            if (IO.GetLength() != slen)
            {
                throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "Restore - invalid source stream (wrong source length)");
            }

            long save_pos = IO.GetPosition();                // +16

            long cpos = save_pos;

            TRANSACTIONS_ON = false;
            Open();
            TA.RollMode = true;

            long splen = IO.ReadLong(cpos);      // Space length

            // Validate list of spaces
            while (splen > 0)
            {
                // Read space name length
                int n_len = IO.ReadShort(cpos + 8);

                // Read space name
                string sname = IO.ReadString(cpos + 10, n_len);

                VSpace sp = GetSpace(sname);

                if (sp == null)
                {
                    this.Close();
                    this.Create(sname);
                    this.Open();
                }
                cpos += splen;
                splen = IO.ReadLong(cpos);
            }

            // Restore position
            IO.SetPosition(save_pos);

            // Proceed with restore
            splen = IO.ReadLong(-1);

            long spcnt = 8;

            while (splen != -1)
            {
                // Read space name length
                int n_len = IO.ReadShort(-1);

                // Read space name
                string sname = IO.ReadString(-1, n_len);

                spcnt += (n_len + 2);

                // Read owner length
                int o_len = IO.ReadShort(-1);

                // Read Owner
                string sowner = IO.ReadString(-1, o_len);

                spcnt += (o_len + 2);

                VSpace sp = GetSpace(sname);

                VSVirtualMemoryManager vm = GetVM(sname);

                sp.Owner = sowner;
                vm.Write(DEFS.SYSTEM_STATUS_ADDRESS, DateTime.Now.ToBinary());            // Write timestamp - restore started

                if (!IMO)
                {
                    vm.flush();
                }

                // Restore keys
                if (IO.GetPosition() < IO.GetLength())
                {
                    sig = IO.ReadString(-1, DEFS.DUMP_KEYS_SIGNATURE.Length);

                    spcnt += DEFS.DUMP_KEYS_SIGNATURE.Length;

                    if (sig != DEFS.DUMP_KEYS_SIGNATURE)
                    {
                        throw new VSException(DEFS.E0006_INVALID_SIGNATURE_CODE, "(Restore missing start key signature)");
                    }


                    VSKeyManager kh = sp.KeyManager;

                    if (!kh.IsEmpty)
                    {
                        throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "Space '" + sname + "' is not empty. Restore terminated.");
                    }

                    long id = IO.ReadLong(-1);
                    spcnt += 8;

                    while (id >= 0)
                    {
                        //VSDebug.StopPoint(id, 23884);
                        //VSDebug.StopPoint(id, 24033);

                        kh.Add(null, id);
                        id     = IO.ReadLong(-1);
                        spcnt += 8;
                    }
                }

                // Restore data pools
                long   size       = 0;
                int    chunk_size = 0;
                ushort alloc      = 0;
                ushort fix        = 0;
                while (spcnt < splen)
                {
                    VSAllocation new_a;

                    //Read ADSC fields
                    long oldid = IO.ReadLong(-1);

                    short pool = IO.ReadShort(-1);
                    spcnt += 10;

                    size   = IO.ReadLong(-1);                   // Total size
                    spcnt += 8;

                    chunk_size = IO.ReadInt(-1);                // Chunk size
                    spcnt     += 4;

                    alloc  = IO.ReadUShort(-1);                 // Alloc
                    spcnt += 2;

                    fix    = IO.ReadUShort(-1);                 // Fixed part length
                    spcnt += 2;

                    buf    = IO.ReadBytes(-1, (int)size);
                    spcnt += size;

                    // Allocate space
                    new_a = sp.ALLOCATE_SPACE(size, pool, false, (long)chunk_size, (short)fix);

                    new_a.ALLOC = (ushort)((alloc == 0) ? 0 : 1);                      // Set allocation 0 - RAW; 1 - FIELD

                    if (oldid > 0)
                    {
                        new_a.Id = oldid;
                        sp.KeyManager.Update(oldid, new_a);
                    }

                    new_a.Write(0, buf, buf.Length);                          //Save data
                }

                vm.Write(DEFS.SYSTEM_STATUS_ADDRESS, (long)0);                          // Write 0 - restore ended for space

                splen = IO.ReadLong(-1);

                spcnt = 8;
            }
            if (!IMO)
            {
                Close();
            }

            TRANSACTIONS_ON = true;
        }