/// <summary> /// Create a new index and returns head page address (skip list) /// </summary> public CollectionIndex CreateIndex(string name, string expr, bool unique) { // get how many butes needed fore each head/tail (both has same size) var bytesLength = IndexNode.GetNodeLength(MAX_LEVEL_LENGTH, BsonValue.MinValue, out var keyLength); // get a new empty page (each index contains your own linked nodes) var indexPage = _snapshot.NewPage <IndexPage>(); // create index ref var index = _snapshot.CollectionPage.InsertCollectionIndex(name, expr, unique); // insert head/tail nodes var head = indexPage.InsertIndexNode(index.Slot, MAX_LEVEL_LENGTH, BsonValue.MinValue, PageAddress.Empty, bytesLength); var tail = indexPage.InsertIndexNode(index.Slot, MAX_LEVEL_LENGTH, BsonValue.MaxValue, PageAddress.Empty, bytesLength); // link head-to-tail with double link list in first level head.SetNext(0, tail.Position); tail.SetPrev(0, head.Position); // add this new page in free list (slot 0) index.FreeIndexPageList = indexPage.PageID; indexPage.PageListSlot = 0; index.Head = head.Position; index.Tail = tail.Position; return(index); }
/// <summary> /// Add a new collection. Check if name the not exists. Create only in transaction page - will update header only in commit /// </summary> private void Add(string name, ref CollectionPage collectionPage) { if (Encoding.UTF8.GetByteCount(name) > _header.GetAvaiableCollectionSpace()) { throw LiteException.InvalidCollectionName(name, "There is no space in header for more collections"); } if (!name.IsWord()) { throw LiteException.InvalidCollectionName(name, "Use only [a-Z$_]"); } if (name.StartsWith("$")) { throw LiteException.InvalidCollectionName(name, "Collection can't starts with `$` (reserved for system collections)"); } // create new collection page collectionPage = _snapshot.NewPage <CollectionPage>(); var pageID = collectionPage.PageID; // insert collection name/pageID in header only in commit operation _transPages.Commit += (h) => h.InsertCollection(name, pageID); // create first index (_id pk) (must pass collectionPage because snapshot contains null in CollectionPage prop) var indexer = new IndexService(_snapshot); indexer.CreateIndex("_id", "$._id", true); }
/// <summary> /// Add a new collection. Check if name the not exists. Create only in transaction page - will update header only in commit /// </summary> private void Add(string name, ref CollectionPage collectionPage) { // checks for collection name/size CheckName(name, _header); // create new collection page collectionPage = _snapshot.NewPage <CollectionPage>(); var pageID = collectionPage.PageID; // insert collection name/pageID in header only in commit operation _transPages.Commit += (h) => h.InsertCollection(name, pageID); // create first index (_id pk) (must pass collectionPage because snapshot contains null in CollectionPage prop) var indexer = new IndexService(_snapshot); indexer.CreateIndex("_id", "$._id", true); }
/// <summary> /// Add a new collection. Check if name the not exists. Create only in transaction page - will update header only in commit /// </summary> private async Task <CollectionPage> Add(string name) { // checks for collection name/size CheckName(name, _header); // create new collection page var collectionPage = await _snapshot.NewPage <CollectionPage>(); _snapshot.CollectionPage = collectionPage; var pageID = collectionPage.PageID; // insert collection name/pageID in header only in commit operation _transPages.Commit += (h) => h.InsertCollection(name, pageID); // create first index (_id pk) (must pass collectionPage because snapshot contains null in CollectionPage prop) var indexer = new IndexService(_snapshot, _header.Pragmas.Collation); await indexer.CreateIndex("_id", "$._id", true); return(collectionPage); }