void MTnode::InsertBefore(const GiSTentry& entry, int index) { int n=NumEntries(); BOOL ordered=TRUE; if(index>0) ordered=((*this)[index-1]->Compare(entry)<=0); if(index<n) ordered=ordered&&((*this)[index]->Compare(entry)>=0); if(ordered) { // yes, the position is right for this entry assert(index<=n); GiSTentry *e=(GiSTentry *)entry.Copy(); e->SetLevel(Level()); e->SetPosition(index); e->SetNode(this); // Move everything else over for(int i=n; i>index; i--) { GiSTentry *e=(*this)[i-1]; e->SetPosition(i); (*this)[i]=e; } // Stick the entry in (*this)[index]=e; // Bump up the count SetNumEntries(n+1); } else Insert(entry); // find the right place }
void GiSTnode::Unpack(const char *page) { const GiSTheader *h = (const GiSTheader *) page; Reset(); SetLevel(h->level); SetSibling(h->sibling); if (!packedNode) packedNode = new char[tree->Store()->PageSize()]; memcpy(packedNode, page, tree->Store()->PageSize()); Expand(h->numEntries); SetNumEntries(h->numEntries); for (int i=0; i<h->numEntries; i++) { GiSTcompressedEntry tmpentry = Entry(i); GiSTentry *e = CreateEntry(); e->SetLevel(Level()); e->SetPosition(i); e->SetNode(this); e->Decompress(tmpentry); // be tidy if (tmpentry.key) delete tmpentry.key; // Append the body with the entry entries[i] = e; } }
// insert before the original number according to the sequence instead of index void MTnode::InsertBefore (const GiSTentry& newEntry, int index) { int n = NumEntries (); assert (index>=0 && index<=n); BOOL bOrder = TRUE; if (index > 0) { bOrder = (*this)[index-1]->Compare(newEntry) <= 0; } if (index < n) { bOrder = bOrder && (*this)[index]->Compare(newEntry) >= 0; } if (bOrder) { // yes, the position is right for this entry GiSTentry *entry = (GiSTentry *) newEntry.Copy (); entry->SetLevel(Level()); entry->SetPosition(index); entry->SetNode(this); // Move everything else over for (int i=n; i>index; i--) { GiSTentry *e = (*this)[i-1]; e->SetPosition(i); (*this)[i] = e; } // Stick the entry in (*this)[index] = entry; // Bump up the count SetNumEntries (n+1); } else { Insert (newEntry); // find the right place } }
TRI_fulltext_list_t* TRI_ExcludeListFulltextIndex( TRI_fulltext_list_t* list, TRI_fulltext_list_t* exclude) { TRI_fulltext_list_entry_t* listEntries; TRI_fulltext_list_entry_t* excludeEntries; uint32_t numEntries; uint32_t numExclude; uint32_t i, j, listPos; if (list == nullptr) { TRI_FreeListFulltextIndex(exclude); return list; } if (exclude == nullptr) { return list; } numEntries = GetNumEntries(list); numExclude = GetNumEntries(exclude); if (numEntries == 0 || numExclude == 0) { // original list or exclusion list are empty TRI_FreeListFulltextIndex(exclude); return list; } SortList(list); listEntries = GetStart(list); excludeEntries = GetStart(exclude); j = 0; listPos = 0; for (i = 0; i < numEntries; ++i) { TRI_fulltext_list_entry_t entry; entry = listEntries[i]; while (j < numExclude && excludeEntries[j] < entry) { ++j; } if (j < numExclude && excludeEntries[j] == entry) { // entry is contained in exclusion list continue; } if (listPos != i) { listEntries[listPos] = listEntries[i]; } ++listPos; } // we may have less results in the list of exclusion SetNumEntries(list, listPos); TRI_FreeListFulltextIndex(exclude); return list; }
uint32_t TRI_RewriteListFulltextIndex(TRI_fulltext_list_t* list, void const* data) { TRI_fulltext_list_entry_t* listEntries; TRI_fulltext_list_entry_t* map; uint32_t numEntries; uint32_t i, j; numEntries = GetNumEntries(list); if (numEntries == 0) { return 0; } map = (TRI_fulltext_list_entry_t*)data; listEntries = GetStart(list); j = 0; for (i = 0; i < numEntries; ++i) { TRI_fulltext_list_entry_t entry; TRI_fulltext_list_entry_t mapped; entry = listEntries[i]; if (entry == 0) { continue; } mapped = map[entry]; if (mapped == 0) { // original value has been deleted continue; } listEntries[j++] = mapped; } if (j != numEntries) { SetNumEntries(list, j); } return j; }
TRI_fulltext_list_t* TRI_CloneListFulltextIndex( TRI_fulltext_list_t const* source) { uint32_t numEntries; if (source == nullptr) { numEntries = 0; } else { numEntries = GetNumEntries(source); } TRI_fulltext_list_t* list = TRI_CreateListFulltextIndex(numEntries); if (list != nullptr) { if (numEntries > 0) { memcpy(GetStart(list), GetStart(source), numEntries * sizeof(TRI_fulltext_list_entry_t)); SetNumEntries(list, numEntries); } } return list; }
TRI_fulltext_list_t* TRI_CloneListFulltextIndex (const TRI_fulltext_list_t* const source) { TRI_fulltext_list_t* list; uint32_t numEntries; if (source == NULL) { numEntries = 0; } else { numEntries = GetNumEntries(source); } list = TRI_CreateListFulltextIndex(numEntries); if (list == NULL) { return NULL; } if (numEntries > 0) { memcpy(GetStart(list), GetStart(source), numEntries * sizeof(TRI_fulltext_list_entry_t)); SetNumEntries(list, numEntries); } return list; }
TRI_fulltext_list_t* TRI_InsertListFulltextIndex( TRI_fulltext_list_t* list, const TRI_fulltext_list_entry_t entry) { TRI_fulltext_list_entry_t* listEntries; uint32_t numAllocated; uint32_t numEntries; bool unsort; numAllocated = GetNumAllocated(list); numEntries = GetNumEntries(list); listEntries = GetStart(list); unsort = false; if (numEntries > 0) { TRI_fulltext_list_entry_t lastEntry; // check whether the entry is already contained in the list lastEntry = listEntries[numEntries - 1]; if (entry == lastEntry) { // entry is already contained. no need to insert the same value again return list; } if (entry < lastEntry) { // we're adding at the end. we must update the sorted property if // the list is not sorted anymore unsort = true; } } if (numEntries + 1 >= numAllocated) { // must allocate more memory TRI_fulltext_list_t* clone; uint32_t newSize; newSize = (uint32_t)(numEntries * GROWTH_FACTOR); if (newSize == numEntries) { // 0 * something might not be enough... newSize = numEntries + 1; } // increase the existing list clone = IncreaseList(list, newSize); if (clone == nullptr) { return nullptr; } // switch over if (list != clone) { list = clone; listEntries = GetStart(list); } } if (unsort) { SetIsSorted(list, false); } // insert at the end listEntries[numEntries] = entry; SetNumEntries(list, numEntries + 1); return list; }
TRI_fulltext_list_t* TRI_IntersectListFulltextIndex(TRI_fulltext_list_t* lhs, TRI_fulltext_list_t* rhs) { TRI_fulltext_list_t* list; TRI_fulltext_list_entry_t last; TRI_fulltext_list_entry_t* lhsEntries; TRI_fulltext_list_entry_t* rhsEntries; TRI_fulltext_list_entry_t* listEntries; uint32_t l, r; uint32_t numLhs, numRhs; uint32_t listPos; // check if one of the pointers is NULL if (lhs == nullptr) { return rhs; } if (rhs == nullptr) { return lhs; } numLhs = GetNumEntries(lhs); numRhs = GetNumEntries(rhs); // printf("list intersection lhs: %lu rhs: %lu\n\n", (unsigned long) numLhs, // (unsigned long) numRhs); // check the easy cases when one of the lists is empty if (numLhs == 0 || numRhs == 0) { if (lhs != nullptr) { TRI_FreeListFulltextIndex(lhs); } if (rhs != nullptr) { TRI_FreeListFulltextIndex(rhs); } return TRI_CreateListFulltextIndex(0); } // we have at least one entry in each list list = TRI_CreateListFulltextIndex(numLhs < numRhs ? numLhs : numRhs); if (list == nullptr) { TRI_FreeListFulltextIndex(lhs); TRI_FreeListFulltextIndex(rhs); return nullptr; } SortList(lhs); lhsEntries = GetStart(lhs); l = 0; SortList(rhs); rhsEntries = GetStart(rhs); r = 0; listPos = 0; listEntries = GetStart(list); last = 0; while (true) { while (l < numLhs && lhsEntries[l] <= last) { ++l; } while (r < numRhs && rhsEntries[r] <= last) { ++r; } again: if (l >= numLhs || r >= numRhs) { break; } if (lhsEntries[l] < rhsEntries[r]) { ++l; goto again; } else if (lhsEntries[l] > rhsEntries[r]) { ++r; goto again; } // match listEntries[listPos++] = last = lhsEntries[l]; ++l; ++r; } SetNumEntries(list, listPos); SetIsSorted(list, true); TRI_FreeListFulltextIndex(lhs); TRI_FreeListFulltextIndex(rhs); // printf("result list has %lu\n\n", (unsigned long) listPos); return list; }
TRI_fulltext_list_t* TRI_UnioniseListFulltextIndex(TRI_fulltext_list_t* lhs, TRI_fulltext_list_t* rhs) { TRI_fulltext_list_t* list; TRI_fulltext_list_entry_t last; TRI_fulltext_list_entry_t* lhsEntries; TRI_fulltext_list_entry_t* rhsEntries; TRI_fulltext_list_entry_t* listEntries; uint32_t l, r; uint32_t numLhs, numRhs; uint32_t listPos; if (lhs == nullptr) { return rhs; } if (rhs == nullptr) { return lhs; } numLhs = GetNumEntries(lhs); numRhs = GetNumEntries(rhs); // check the easy cases when one of the lists is empty if (numLhs == 0) { TRI_FreeListFulltextIndex(lhs); return rhs; } if (numRhs == 0) { TRI_FreeListFulltextIndex(rhs); return lhs; } list = TRI_CreateListFulltextIndex(numLhs + numRhs); if (list == nullptr) { TRI_FreeListFulltextIndex(lhs); TRI_FreeListFulltextIndex(rhs); return nullptr; } SortList(lhs); lhsEntries = GetStart(lhs); l = 0; SortList(rhs); rhsEntries = GetStart(rhs); r = 0; listPos = 0; listEntries = GetStart(list); last = 0; while (true) { while (l < numLhs && lhsEntries[l] <= last) { ++l; } while (r < numRhs && rhsEntries[r] <= last) { ++r; } if (l >= numLhs && r >= numRhs) { break; } if (l >= numLhs && r < numRhs) { listEntries[listPos++] = last = rhsEntries[r++]; } else if (l < numLhs && r >= numRhs) { listEntries[listPos++] = last = lhsEntries[l++]; } else if (lhsEntries[l] < rhsEntries[r]) { listEntries[listPos++] = last = lhsEntries[l++]; } else { listEntries[listPos++] = last = rhsEntries[r++]; } } SetNumEntries(list, listPos); SetIsSorted(list, true); TRI_FreeListFulltextIndex(lhs); TRI_FreeListFulltextIndex(rhs); return list; }