public IEnumerable <int> All(int offset) { MetaItemsPage <T> page = this[offset]; if (page == null) { yield break; } else { foreach (var ofs in page.Items.SelectMany(i => i.Value)) { yield return(ofs); } } }
/// <summary> /// Used to search by comparison operators inside a given item page /// </summary> /// <param name="offset">offset (ID) of the item page</param> /// <param name="key">key to compare</param> /// <param name="oper">comparison operator</param> /// <returns></returns> public IEnumerable <KeyValuePair <T, List <int> > > FindByOper(int offset, T key, TokenType oper) { MetaItemsPage <T> page = this[offset]; if (page == null) { yield break; } else { var collection = Enumerable.Empty <KeyValuePair <T, List <int> > >(); switch (oper) { case TokenType.Equal: collection = page.Items.Where(i => i.Key.Equals(key)); break; case TokenType.NotEqual: collection = page.Items.Where(i => i.Key.CompareTo(key) != 0); break; case TokenType.Less: collection = page.Items.Where(i => i.Key.CompareTo(key) < 0); break; case TokenType.LessOrEqual: collection = page.Items.Where(i => i.Key.CompareTo(key) <= 0); break; case TokenType.Greater: collection = page.Items.Where(i => i.Key.CompareTo(key) > 0); break; case TokenType.GreaterOrEqual: collection = page.Items.Where(i => i.Key.CompareTo(key) >= 0); break; default: throw new ArgumentException($"invalid operator: {oper}"); } foreach (var ofs in collection) { yield return(ofs); } } }
/// <summary> /// Finds an key in a page according to its offset /// </summary> /// <param name="offset">offset (ID) of page</param> /// <param name="key">key</param> /// <returns></returns> public DbKeyValues <T> Find(int offset, T key) { MetaItemsPage <T> page = this[offset]; if (page == null) { return(null); } var pair = page.Items.FirstOrDefault(i => i.Key.Equals(key)); return((pair.Key == null) ? null : new DbKeyValues <T>() { Key = pair.Key, Values = pair.Value }); }
public DbIndexItems(CsvDb db, string tableName, string columnName) { if ((Database = db) == null) { throw new ArgumentException("Database is undefined"); } Index = Database.Index(tableName, columnName); if (Index == null) { throw new ArgumentException($"Column [{columnName}] does not exists in table [{tableName}]."); } //load structure PathToItems = io.Path.Combine(Database.BinaryPath, $"{Index.Indexer}.bin"); if (!io.File.Exists(PathToItems)) { throw new ArgumentException($"Could not find indexer in database"); } Hash = new Dictionary <int, MetaItemsPage <T> >(); //read main structure of item pages using (reader = new io.BinaryReader(io.File.OpenRead(PathToItems))) { //Header PageCount = reader.ReadInt32(); Int32 keyTypeValue = reader.ReadInt32(); KeyType = (DbColumnType)keyTypeValue; //read all pages main info for (var pi = 0; pi < PageCount; pi++) { var flags = reader.ReadInt32(); var pageType = flags & 0b011; if (pageType != Consts.BTreePageItemsFlag) { throw new ArgumentException("Invalid indexer"); } var uniqueKeyValue = (flags & Consts.BTreeUniqueKeyValueFlag) != 0; var offset = reader.ReadInt32(); var pageSize = reader.ReadInt32(); var itemsCount = reader.ReadInt32(); //skip keys and values //sizeof: flags, offset, pageSize, itemsCount var sizeOfInt32 = sizeof(Int32); var dataStart = 4 * sizeOfInt32; var skip = pageSize - dataStart; reader.BaseStream.Seek(skip, io.SeekOrigin.Current); var page = new MetaItemsPage <T>() { Flags = flags, UniqueKeyValue = uniqueKeyValue, Offset = offset, PageSize = pageSize, ItemsCount = itemsCount, DataStart = dataStart, Parent = this, Frequency = 0.0, Number = pi }; //add to hash dictionary for fast retrieval Hash.Add(page.Offset, page); } } //update item page count Index.ItemPages = Hash.Count; }