Пример #1
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);
            }
        }
Пример #2
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();
            }
        }
Пример #3
0
        /// <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;
        }