/// <summary> Returns sequence of bookmarks </summary> internal override IEnumerable<Bookmark> GetBookmarksGenerator(Table table, bool doNotRewind = false) { // retrieve all subcursors var allSubcursors = Subpredicates .Select(s => s.GetBookmarksGenerator(table, true)) .ToArray(); // can we oprimize it natively? if(allSubcursors.Count() > 0 && allSubcursors.All(t => t is INativeCursor)) { // Optimized searching by index intersection var cursors = allSubcursors.OfType<INativeCursor>(); try { return Api.IntersectIndexes( table.Database.CurrentSession, cursors.Select(s => s.CursorHandle).ToArray()) .Select(k => new Bookmark(k)).ToList(); } catch(EsentNoCurrentRecordException) { return Enumerable.Empty<Bookmark>(); } finally { foreach (var cursor in cursors.OfType<IDisposable>()) cursor.Dispose(); } } // can't optimize by intersection, so do intersection of all // in memory return allSubcursors.Aggregate((acc, left) => acc.Intersect(left)).ToList(); }
/// <summary> Before seek </summary> internal override IEnumerable<Bookmark> GetBookmarksGenerator(Table table, bool doNotRewind) { var cursor = table.OpenNativeCursor(SearchIndex); var session = cursor.Table.Database.CurrentSession; // seek to value var key = Converters.Convert(Val); Api.JetMakeKey(session, cursor, key, key.Length, MakeKeyGrbit.NewKey); Api.TrySeek(session, cursor, SeekGrbit.SeekGE); Api.JetMakeKey(session, cursor, key, key.Length, MakeKeyGrbit.NewKey | MakeKeyGrbit.SubStrLimit); Api.TrySetIndexRange(session, cursor, SetIndexRangeGrbit.RangeUpperLimit | SetIndexRangeGrbit.RangeInclusive); // step back if(!doNotRewind) cursor.StepBack(); return cursor; }
/// <summary> Generates bookmarks </summary> internal abstract IEnumerable<Bookmark> GetBookmarksGenerator(TTable table, bool notRewind = false);