/// <summary> /// Get numeric value /// </summary> /// <param name="sourse"></param> /// <returns></returns> private long GetNumericValue(string p) { long n = -1; try { string ost = ""; string ist = GetStringValue(p); for (int i = 0; i < ist.Length; i++) { int res = 0; string sym = ist.Substring(i, 1); if (int.TryParse(sym, out res)) { ost += sym; } else { break; } } n = VSLib.ConvertStringToLong(ost); } catch (Exception e1) { this.Error = e1.Message; return(-1); } return(n); }
/// <summary> /// Save catalog content /// </summary> public void Save() { string ost = sg_ok + DEFS.VSTORAGE_VERSION + "$" + ste + "$" + DEFS.DELIM_NEWLINE; for (int i = 0; i < dl.Count; i++) { ost += "[" + dl[i].Name + "]" + DEFS.DELIM_NEWLINE; ost += DEF_ID + "=" + dl[i].Id.ToString() + DEFS.DELIM_NEWLINE; ost += DEF_PAGESIZE + "=" + dl[i].page_size_kb.ToString() + "Kb" + DEFS.DELIM_NEWLINE; ost += DEF_SIZE + "=" + dl[i].space_size_pg.ToString() + "Pages" + DEFS.DELIM_NEWLINE; ost += DEF_EXTENSION + "=" + dl[i].extension_pg.ToString() + "Pages" + DEFS.DELIM_NEWLINE; ost += DEF_PARTITIONS + "=" + dl[i].partitions.ToString() + DEFS.DELIM_NEWLINE; ost += DEF_TIMESTAMP + "=" + dl[i].creation_timestamp + DEFS.DELIM_NEWLINE; ost += DEF_PATH + "=" + dl[i].path + DEFS.DELIM_NEWLINE; ost += DEF_INDEXSPACE + "=" + dl[i].indexspace + DEFS.DELIM_NEWLINE; // Create signature ost += DEF_SIGNATURE + "=" + dl[i].CalculateSignature() + DEFS.DELIM_NEWLINE; } if (File.Exists(catalog_file_name)) { if (File.Exists(backup_file_name)) { File.Delete(backup_file_name); } File.Move(catalog_file_name, backup_file_name); } File.WriteAllBytes(catalog_file_name, VSLib.ConvertStringToByte(ost)); }
/// <summary> /// Delete key /// </summary> /// <param name="key"></param> /// <returns></returns> private bool delete(byte[] key, long value = -1) { //VSDebug.StopPoint(Name, "SIZE"); int nodeID = ROOT; while (nodeID >= 0) { int compare = VSLib.CompareKeys(key, BTree[nodeID].Key); if (compare < 0) { nodeID = BTree[nodeID].Left; } else if (compare > 0) { nodeID = BTree[nodeID].Right; } else { return(delete_avl_node(nodeID, value)); } } return(false); }
/// <summary> /// Set multiple string values /// </summary> /// <param name="fields"> /// Array of fieldsin format: {name}={value} /// </param> /// <returns></returns> public void Set(string[] fields) { bool upd = false; if (fields != null) { if (fields.Length > 0) { for (int i = 0; i < fields.Length; i++) { int j = fields[i].IndexOf("="); if (j >= 0) { string name = fields[i].Substring(0, j); string value = ""; if (j < (fields[i].Length - 1)) { value = fields[i].Substring(j + 1, fields[i].Length - j - 1); } set_field(name, FIELD_TYPE_STRING, VSLib.ConvertStringToByte(value), false); upd = true; } } } } if (upd) { serialize(); } }
/// <summary> /// Delete existing index /// </summary> /// <param name="name"></param> /// <returns></returns> public void DeleteIndex(string name) { if (IndexSpace != null) { IndexSpace.DeleteIndex(DEFS.PrepareFullIndexName(this.Name, name)); } else { VSIndex x = this.get_index(name); if (x == null) { throw new VSException(DEFS.E0052_DELETE_INDEX_ERROR_CODE, "- index is not found - '" + name + "'"); } // Remove all references VSIndex ref_x = get_index(DEFS.PrepareFullIndexName(DEFS.ParseIndexSpace(name), DEFS.INDEX_CROSS_REFERENCES)); x.Reset(); while (x.Next()) { long[] refs = x.CurrentRefs; for (int i = 0; i < refs.Length; i++) { byte[] key = VSLib.ConvertLongToByte(refs[i]); ref_x.delete_node(key, x.CurrentAvlNode.ID); } } index_list.Remove(x); index_list_full.Remove(x); x.purge(); } }
/// <summary> /// Gey index names by space prefix /// </summary> /// <param name="space_name"></param> /// <returns></returns> private string[] get_indexes_for_space(string space_name) { List <string> lx = new List <string>(); string nm = space_name.Trim().ToLower(); for (int i = 0; i < index_list.Count; i++) { string[] parsed_name = new string[2]; parsed_name[0] = DEFS.ParseIndexSpace(index_list[i].Name); parsed_name[1] = DEFS.ParseIndexName(index_list[i].Name); if (nm == "") { if (parsed_name[0] == "") { lx.Add(parsed_name[1]); } } else { if (VSLib.Compare(nm, parsed_name[0])) { lx.Add(parsed_name[1]); } } } return(lx.ToArray()); }
// Reader/Writer with encryption /// <summary> /// File Stream /// </summary> /// <param name="filename">File name for Read/Write</param> /// <param name="mode">'c' - create; 'o' - open, 'a' - append</param> /// <param name="key">key for encrypt/decrypt ("" - no encryption)</param> public VSIO(string filename, string mode, string key) { string md = mode.Trim().ToLower(); //fs = stream; xkey_b = VSLib.ConvertStringToByte(key); _encrypt = (key != ""); IMO = false; if (md == FILE_MODE_CREATE) { fs = new FileStream(filename, FileMode.Create); } else if (md == FILE_MODE_APPEND) { fs = new FileStream(filename, FileMode.Append); } else if (md == FILE_MODE_OPEN) { fs = new FileStream(filename, FileMode.OpenOrCreate); } else { throw new VSException(DEFS.E0034_IO_ERROR_CODE, "Invalid open mode = '" + md + "'"); } }
/// <summary> /// Find key (string) /// </summary> /// <param name="key"></param> /// <param name="op">0 - equal; -1 - nearest left (less than); 1 - nearest right (more than) </param> /// <returns>Value</returns> public BTResult Find(string key, int op) { int i = find(VSLib.ConvertStringToByte(key), op); BTResult ret = new BTResult(); ret.KeyString = (i < 0) ? "" : VSLib.ConvertByteToString(BTree[i].Key); ret.Value = (i < 0) ? -1 : BTree[i].Value[0]; return(ret); }
/// <summary> /// Find key (long) /// </summary> /// <param name="key"></param> /// <param name="op">0 - equal; -1 - nearest left (less than); 1 - nearest right (more than) </param> /// <returns>Value</returns> public BTResult Find(long key, int op) { int i = find(VSLib.ConvertLongToByteReverse(key), op); BTResult ret = new BTResult(); ret.Key = (i < 0) ? -1 : VSLib.ConvertByteToLongReverse(BTree[i].Key); ret.Value = (i < 0) ? -1 : BTree[i].Value[0]; return(ret); }
/// <summary> /// Find all keys (non-unique), string /// </summary> /// <param name="key"></param> /// <param name="op">0 - equal; -1 - nearest left (less than); 1 - nearest right (more than) </param> /// <returns></returns> public BTResultList FindAll(string key, int op) { int i = find(VSLib.ConvertStringToByte(key), op); BTResultList ret = new BTResultList(); ret.KeyString = (i < 0) ? "" : VSLib.ConvertByteToString(BTree[i].Key); ret.Value = (i < 0) ? new long[0] : BTree[i].Value.ToArray(); return(ret); }
/// <summary> /// Find all keys (non-unique), long /// </summary> /// <param name="key"></param> /// <param name="op">0 - equal; -1 - nearest left (less than); 1 - nearest right (more than) </param> /// <returns></returns> public BTResultList FindAll(long key, int op) { int i = find(VSLib.ConvertLongToByteReverse(key), op); BTResultList ret = new BTResultList(); ret.Key = (i < 0) ? -1 : VSLib.ConvertByteToLongReverse(BTree[i].Key); ret.Value = (i < 0) ? new long[0] : BTree[i].Value.ToArray(); return(ret); }
/// <summary> /// Write FBQE /// </summary> /// <param name="f"></param> private void SerializeFBQE(FBQE f) { VSLib.CopyBytes(buffer, VSLib.ConvertStringToByte(DEFS.FBQE_SIGNATURE), f.address + SG_POS, SG_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_START), f.address + ADDRESS_START_POS, ADDRESS_START_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_END), f.address + ADDRESS_END_POS, ADDRESS_END_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.LENGTH), f.address + LENGTH_POS, LENGTH_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.PREV), f.address + PREV_POS, PREV_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.NEXT), f.address + NEXT_POS, NEXT_LEN); F_Object.Write(f.address, VSLib.GetByteArray(buffer, f.address, FBQE_LENGTH), FBQE_LENGTH); }
/// <summary> /// Delete reference /// </summary> /// <param name="rf"></param> /// <returns></returns> internal bool delete_ref(long rf) { int x = -1; List <long> refs = REFS.ToList <long>(); int count = refs.Count; for (int i = 0; i < count; i++) { int i2 = count - 1 - i; if (i > i2) { break; } if (refs[i] == rf) { x = i; } else if (refs[i2] == rf) { x = i2; } if (x > 0) { break; } } if (x < 0) { return(false); } else { refs.RemoveAt(x); } byte[] refs_new = new byte[refs.Count * 8]; for (int i = 0; i < refs.Count; i++) { VSLib.CopyBytes(refs_new, VSLib.ConvertLongToByte(refs[i]), (i * 8), 8); } ALLOCATION.Write(this.REF_POS, refs_new, refs_new.Length); // Write REF_COUNT = refs.Count; return(true); }
/// <summary> /// Lock current directory(all spaces) /// </summary> /// <returns></returns> private bool Lock() { if (IMO) { return(true); } byte[] shared_code = { 0x0F, 0, 0, 0, 0, 0, 0, 0 }; byte[] exclusive_code = { 0xFF, 0, 0, 0, 0, 0, 0, 0 }; long exclusive_lock_offset = 0; string lock_fn = root_path + "\\" + DEFS.LOCK_FILE_NAME; if (fslck == null) { lock_number = -1; if (!File.Exists(lock_fn)) { byte[] b = new byte[8192]; fslck = File.Create(lock_fn); fslck.Write(b, 0, b.Length); fslck.Close(); fslck = null; } fslck = File.Open(lock_fn, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); long number = fslck.Length / lock_length; try { fslck.Lock(exclusive_lock_offset, fslck.Length); // Lock for both read/write exclusively lock_number = 0; fslck.Seek(lock_number, SeekOrigin.Begin); fslck.Write(exclusive_code, 0, exclusive_code.Length); fslck.Write(VSLib.ConvertLongToByte(DateTime.Now.ToBinary()), 0, 8); } catch (IOException e) { this.Error = e.Message; fslck.Close(); fslck = null; } return(lock_number >= 0); } else { return(true); } }
/// <summary> /// Memory Stream /// </summary> /// <param name="data">byte array - existing stream (read-only); null or empty - new stream</param> /// <param name="key">key for encrypt/decrypt ("" - no encryption)</param> public VSIO(byte[] data, string key) { //fs = stream; xkey_b = VSLib.ConvertStringToByte(key); _encrypt = (key != ""); IMO = true; if (data == null) { fs = new MemoryStream(); } else { fs = new MemoryStream(data); } }
/// <summary> /// Delete index (byte key) /// </summary> /// <param name="key"></param> /// <param name="id">For non-unique index. 0 - delete a </param> /// <returns></returns> public bool Delete(byte[] key, long id) { if (this.index_name == DEFS.INDEX_CROSS_REFERENCES) { throw new VSException(DEFS.E0055_INDEX_INVALID_OP_CODE, " - 'Delete' for '" + DEFS.INDEX_CROSS_REFERENCES + "'"); } long av_id = this.delete_node(key, id); if (av_id > 0) { byte[] obj_key = VSLib.ConvertLongToByteReverse(id); XRefs.delete_node(obj_key, av_id); return(true); } return(false); }
/// <summary> /// Remove all related indexes for object by ID /// ONLY for objects and indexes located in THIS space /// </summary> /// <param name="a"></param> private void remove_all_indexes(string space_name, long id) { VSIndex ref_index = this.get_index(DEFS.PrepareFullIndexName(space_name, DEFS.INDEX_CROSS_REFERENCES)); if (ref_index != null) { byte[] key = VSLib.ConvertLongToByteReverse(id); long[] ref_nodes = ref_index.FindAll(key, false); // Get all avl node ids for obj id ref_index.delete_node(key, -1); // Remove reference record for (int i = 0; i < ref_nodes.Length; i++) { this.get_index(this.GetAllocation(ref_nodes[i]).ReadLong(VSAvlNode.INDEX_POS)).delete_avl_node(ref_nodes[i], id); } } }
/// <summary> /// Convert long to byte array /// </summary> /// <param name="value"></param> /// <returns></returns> private static string GetAddressSignature(long value) { //string s = VSLib.ConvertLongToHexString(value); byte[] b = VSLib.ConvertLongToByte(value); int n = 0; for (int i = 0; i < b.Length; i++) { n += b[i] + (i * 8); if (n > 9999) { n -= 9999; } } return(n.ToString("D4")); }
/// <summary> /// Array of the field names by pattern /// </summary> public string[] GetFields(string pattern = "*") { sync_cache(); if (FCache == null) { return(new string[0]); } List <string> ls = new List <string>(); for (int i = 0; i < FCache.Count; i++) { if (VSLib.Compare(pattern, FCache[i].NAME)) { ls.Add(FCache[i].NAME); } } return(ls.ToArray()); }
/// <summary> /// Calculate new signature /// </summary> /// <returns></returns> public string CalculateSignature() { ulong chs = (ulong)((Id * 123456789) - space_size_pg * 3 + extension_pg * 5 - page_size_kb * 7 + partitions * 9 - VSLib.ConvertStringToByte(CONFIG.ste)[0]); byte[] x = VSLib.ConvertStringToByte(indexspace.Trim().ToLower()); for (int i = 0; i < x.Length; i++) { chs += (ulong)(x[i] * 3); } x = VSLib.ConvertStringToByte(name.Trim().ToLower()); for (int i = 0; i < x.Length; i++) { chs += (ulong)(x[i] * 5); } signature = VSLib.ConvertULongToHexString(chs); return(signature); }
/// <summary> /// Empty path - In Memory Option /// </summary> /// <param name="path"></param> public VSCatalog(string path) { this.dl = new List <VSCatalogDescriptor>(); if (path == "") { catalog_file_name = ""; backup_file_name = ""; CATALOG_DIR = "~IMO~"; } else { catalog_file_name = path + "\\" + DEFS.CTLG_FILE_NAME; backup_file_name = catalog_file_name + ".bak"; string[] s = VSLib.Parse(path, "\\"); CATALOG_DIR = s[s.Length - 1]; Load(); } }
internal const long FBQE_HEADER_LENGTH = LAST_Q_POS + LAST_Q_LEN + 4; // 4-reserve /////////////////////////////////////////////////// ///////////////////// METHODS ///////////////////// /////////////////////////////////////////////////// /// <summary> /// Get by index /// </summary> /// <param name="idx"></param> /// <returns></returns> public FBQE GetFBQE(int idx) { FBQE f = new FBQE(); f.index = idx; f.address = idx * FBQE_LENGTH; f.SG = VSLib.ConvertByteToString(VSLib.GetByteArray(buffer, f.address + SG_POS, SG_LEN)); f.ADDRESS_START = VSLib.ConvertByteToLong(VSLib.GetByteArray(buffer, f.address + ADDRESS_START_POS, ADDRESS_START_LEN)); f.ADDRESS_END = VSLib.ConvertByteToLong(VSLib.GetByteArray(buffer, f.address + ADDRESS_END_POS, ADDRESS_END_LEN)); f.LENGTH = VSLib.ConvertByteToLong(VSLib.GetByteArray(buffer, f.address + LENGTH_POS, LENGTH_LEN)); f.PREV = VSLib.ConvertByteToInt(VSLib.GetByteArray(buffer, f.address + PREV_POS, PREV_LEN)); f.NEXT = VSLib.ConvertByteToInt(VSLib.GetByteArray(buffer, f.address + NEXT_POS, NEXT_LEN)); if (f.SG != DEFS.FBQE_SIGNATURE) { throw new VSException(DEFS.E0006_INVALID_SIGNATURE_CODE, "(FBQE)"); } return(f); }
/// <summary> /// Reset by key /// </summary> /// <param name="key"></param> public void Reset(long key, bool partial = false) { _current = -1; if (ROOT >= 0) { int id = find(VSLib.ConvertLongToByteReverse(key), (partial? 1 : 0)); if (id >= 0) { _action = Action.Current; _current = _right = id; } else { _action = Action.End; } } else { _action = Action.End; } }
/// <summary> /// Display space/storage name /// </summary> /// <param name="name"></param> /// <returns></returns> public string[] List(string name = "*") { List <string> l = new List <string>(); string[] sp_list = GetSpaceNameList(); bool nf = false; long sz = GetStorageSize(); if (name == "*") { l.Add("Storage size: " + sz.ToString("#,#;(#,#)") + " bytes (" + (sz / 1048576).ToString("#,#;(#,#)") + " Mb)"); } for (int i = 0; i < sp_list.Length; i++) { if (l.Count > 0) { l.Add(" "); } if (VSLib.Compare(name.Trim().ToLower(), sp_list[i])) { nf = true; string[] info = GetSpaceHeaderInfo(sp_list[i]); for (int j = 0; j < info.Length; j++) { l.Add(info[j]); } } } if (!nf) { l.Add("No space found matching search criteria '" + name + "'"); } return(l.ToArray()); }
/// <summary> /// Remove space: name: space name /// </summary> /// <param name="name"></param> /// <returns></returns> public void Remove(string name) { if (state != DEFS.STATE_DEFINED) { throw new VSException(DEFS.E0025_STORAGE_UNABLE_TO_COMPLETE_CODE, "- 'Remove' (storage is opened or undefined)"); } if (!this.Lock()) { throw new VSException(DEFS.E0001_UNABLE_TO_LOCK_CODE, "(Remove space)"); } for (int n = (CATALOG.Count - 1); n >= 0; n--) { if (VSLib.Compare(name, CATALOG[n].Name)) { if (!IMO) { for (int i = 0; i < CATALOG[n].Partitions; i++) { System.IO.File.Delete(GetSpaceFileName(CATALOG[n].Name, CATALOG[n].Path, i)); } FileStream fp = new FileStream(TransactionFileName, FileMode.Create); fp.Close(); CATALOG.Delete(CATALOG[n].Name); CATALOG.Save(); } else { CATALOG.Delete(CATALOG[n].Name); } } } Release(); }
/// <summary> /// Delete index (string key) /// </summary> /// <param name="key"></param> /// <param name="id">For non-unique index. 0 - delete a </param> /// <returns></returns> public bool Delete(string key, long id) { byte[] k = VSLib.ConvertStringToByte(key); return(this.Delete(k, id)); }
/// <summary> /// Check if node exists (string key) /// </summary> /// <param name="key"></param> /// <param name="partial"></param> /// <returns>true/false</returns> public bool Exists(string key, bool partial = false) { return(Exists(VSLib.ConvertStringToByte(key), partial)); }
/// <summary> /// Get ID by full or partial string key (first if if non-unique index) /// </summary> /// <param name="k"></param> /// <returns></returns> public long Find(string key, bool partial = false) { byte[] k = VSLib.ConvertStringToByte(key); return(Find(k, partial)); }
/// <summary> /// Read u=short /// </summary> /// <param name="address"></param> /// <returns></returns> public ushort ReadUShort(long address) { return(VSLib.ConvertByteToUShort(ReadBytes(address, 2))); }
/// <summary> /// Read long /// </summary> /// <param name="address"></param> /// <returns></returns> public long ReadLong(long address) { return(VSLib.ConvertByteToLong(ReadBytes(address, 8))); }