/// <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); }
/// <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); }
/// <summary> /// Constructor - get existing object /// </summary> /// <param name="s"></param> /// <param name="addr"></param> internal VSObject(VSpace s, long addr) : base(s.VM, addr) { sp = s; }
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(); } }
private VSpace sp; // Space object /// <summary> /// Constructor /// </summary> /// <param name="_s"></param> public VSKeyManager(VSpace _s) { sp = _s; Initialize(); }
/// <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(); } }
/// <summary> /// Get free space info /// </summary> /// <param name="name"></param> /// <returns></returns> public string[] GetFreeSpaceInfo(string name) { VSpace sp = GetSpace(name); return(sp.GetFreeSpaceInfo()); }
/// <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; }
/// <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; }