Exemple #1
0
        /// <summary>
        /// Read existing descriptor
        /// </summary>
        /// <param name="s"></param>
        /// <param name="addr"></param>
        internal VSAllocation(VSVirtualMemoryManager vmem, long addr)
        {
            DescriptorAddress = addr;
            vm = vmem;
            // Check if 2 last addr bytes == signature
            string sg = vm.ReadString(DescriptorAddress + SG_POS, SG_LEN);

            if (sg != GetAddressSignature(addr))
            {
                throw new VSException(DEFS.E0006_INVALID_SIGNATURE_CODE, "- Object, address: " + addr.ToString("X"));
            }
        }
Exemple #2
0
        /// <summary>
        /// Create new descriptor
        /// </summary>
        /// <param name="s"></param>
        /// <param name="addr">Descriptor address</param>
        /// <param name="len"></param>
        /// <param name="pool"></param>
        internal VSAllocation(VSVirtualMemoryManager vmem, long addr, long len, short pool)
        {
            vm = vmem;

            DescriptorAddress = addr;

            SG = GetAddressSignature(addr);

            this.FullLength = len;

            Pool = pool;
        }
Exemple #3
0
        /// <summary>
        /// Detach space. Return 0-successful, -1 - error
        /// </summary>
        /// <returns></returns>
        internal int Detach()
        {
            if (vm == null)
            {
                error = "Space is already closed";
                return(-1);
            }

            int rc = vm.Close();

            if (rc < 0)
            {
                this.error = vm.error;
            }
            vm              = null;
            index_list      = null;
            index_list_full = null;
            return(rc);
        }
Exemple #4
0
        ////////////////////////////////////////////////////////////////////////////
        //////////////////////  COMMON METHODS   ///////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Attach new address space. Return 0 - successful; -1 - error
        /// </summary>
        /// <param name="_path"></param>
        /// <param name="_cat_file"></param>
        /// <param name="idx"></param>
        /// <returns></returns>
        internal string Attach(VSCatalogDescriptor desc, VSVirtualMemoryManager vmm, VSTransaction ta, bool imo)
        {
            DESCRIPTOR = desc;
            vm         = vmm;
            vs_imo     = imo;

            // Check if restore is not completed
            long l = vm.ReadLong(DEFS.SYSTEM_STATUS_ADDRESS);

            if (l != 0)
            {
                return(VSException.GetMessage(DEFS.E0009_RESTORE_NOT_COMPLETED_CODE) + " Space: " + Name);
            }


            // Build index list
            index_list      = new List <VSIndex>();
            index_list_full = new List <VSIndex>();
            long addr = GetRootAddress(DEFS.POOL_INDEX);            // Get 1st ADSC addredd

            while (addr > 0)
            {
                VSIndex xd = new VSIndex(this, addr);
                index_list_full.Add(xd);
                if (xd.Name.IndexOf(DEFS.INDEX_CROSS_REFERENCES) < 0)
                {
                    index_list.Add(xd);
                }

                addr = xd.NEXT;
            }

            // Set ref indexes
            for (int i = 0; i < index_list.Count; i++)
            {
                set_ref_index(index_list[i]);
            }

            return("");
        }
        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 #6
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();
            }
        }
Exemple #7
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;
        }
Exemple #8
0
        /// <summary>
        /// Open storage (all address spaces)
        /// </summary>
        /// <returns></returns>
        public void Open(string path = "", string encrypt = "")
        {
            if (state == DEFS.STATE_OPENED)
            {
                return;
            }

            string p = (root_path == DEFS.PATH_UNDEFINED) ? path : root_path;

            root_path = p.Trim();

            this.Set(p);

            // Space list
            sl = new List <VSpace>();

            // VMs list
            vl = new List <VSVirtualMemoryManager>();

            // Check if app directory exists. Create if missing
            if (!Directory.Exists(DEFS.APP_ROOT_DATA))
            {
                Directory.CreateDirectory(DEFS.APP_ROOT_DATA);
            }

            // Check if keys directory exists. Create if missing
            if (!Directory.Exists(DEFS.KEY_DIRECTORY))
            {
                Directory.CreateDirectory(DEFS.KEY_DIRECTORY);
            }

            ///////////////////////////////////////////////////////

            TA = new VSTransaction(TransactionFileName);

            if (!this.Lock())
            {
                throw new VSException(DEFS.E0001_UNABLE_TO_LOCK_CODE);
            }

            // Attach spaces
            for (int i = 0; i < CATALOG.Count; i++)
            {
                VSpace sp = new VSpace();
                VSVirtualMemoryManager vm = new VSVirtualMemoryManager();
                string err = vm.Open(CATALOG[i], TA);
                if (err == "")
                {
                    err = sp.Attach(CATALOG[i], vm, TA, IMO);
                }

                if (err != "")
                {
                    this.Release();
                    throw new VSException(DEFS.E0017_ATTACH_SPACE_ERROR_CODE, "- " + err);
                }
                else
                {
                    vl.Add(vm);
                    sl.Add(sp);
                }
            }

            // Add index spaces references
            for (int i = 0; i < sl.Count; i++)
            {
                if (CATALOG[i].IndexSpace != "")
                {
                    for (int j = 0; j < sl.Count; j++)
                    {
                        if (sl[j].Name == CATALOG[i].IndexSpace)
                        {
                            sl[i].IndexSpace = sl[j];
                            break;
                        }
                    }
                }
            }

            // Presistent only - check if rollback required
            if (!IMO)
            {
                if (TA.Pending)
                {
                    RollBackChanges();
                }
            }

            //Process new FSAT creation and new allocation descriptors, Initialize KEyManager
            for (int i = 0; i < sl.Count; i++)
            {
                sl[i].VerifySpaceChanges();
            }

            this.Commit();

            state = DEFS.STATE_OPENED;

            if (encrypt.Trim() != "")
            {
                this.encrypt = (encrypt.ToUpper().Substring(0, 1) == DEFS.CT_ENCRYPTED);
            }

            return;
        }