MCPcopy Create free account
hub / github.com/FoundationDB/fdb-document-layer / CompoundIndexPlugin

Class CompoundIndexPlugin

src/QLContext.actor.cpp:312–450  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

310};
311
312struct CompoundIndexPlugin : IndexPlugin, ReferenceCounted<CompoundIndexPlugin>, FastAllocated<CompoundIndexPlugin> {
313 void addref() override { ReferenceCounted<CompoundIndexPlugin>::addref(); }
314 void delref() override { ReferenceCounted<CompoundIndexPlugin>::delref(); }
315
316 ACTOR static Future<Void> doIndexUpdateActor(Reference<CompoundIndexPlugin> self,
317 Reference<DocTransaction> tr,
318 Reference<DocumentDeferred> dd,
319 DataKey documentPath) {
320 state Reference<QueryContext> doc(new QueryContext(self->next, tr, documentPath));
321 state Future<Void> writes_finished = dd->writes_finished.getFuture();
322
323 try {
324 dd->snapshotLock.use();
325
326 std::vector<Future<std::vector<DataValue>>> f_old_values;
327 for (const auto& expr : self->exprs) {
328 f_old_values.push_back(
329 consumeAll(mapAsync(expr.first->evaluate(doc), [](Reference<IReadContext> valcx) {
330 return getMaybeRecursive(valcx, StringRef());
331 })));
332 }
333
334 state std::vector<std::vector<DataValue>> old_values = wait(getAll(f_old_values));
335
336 dd->snapshotLock.unuse();
337
338 wait(writes_finished);
339
340 std::vector<Future<std::vector<DataValue>>> f_new_values;
341 for (const auto& expr : self->exprs) {
342 f_new_values.push_back(
343 consumeAll(mapAsync(expr.first->evaluate(doc), [](Reference<IReadContext> valcx) {
344 return getMaybeRecursive(valcx, StringRef());
345 })));
346 }
347
348 state std::vector<std::vector<DataValue>> new_values = wait(getAll(f_new_values));
349
350 int num_new_values = 1;
351 for (const auto& v : new_values) {
352 num_new_values *= v.size();
353 }
354
355 if (num_new_values > DOCLAYER_KNOBS->MULTI_MULTIKEY_INDEX_MAX) {
356 throw multikey_index_cartesian_explosion();
357 }
358
359 state cartesian_product_iterator<DataValue, std::vector<DataValue>::iterator> nvv(new_values);
360 if (self->isUniqueIndex) {
361 // for all new entries going to be written, before we clear the potentially existing old index entries,
362 // we need to make sure there is no existing unique index for that new value under path
363 // dbName+collectionName+"metadata"+"indices"+encodedIndexName+encodedValue
364
365 // When building the unique index, each record out of the table scan needs to wait for the previous
366 // one finished duplication detecting and index record writing. And thus the following section
367 // before the `lock.release()` call, needs to be protected using a mutex lock.
368 ASSERT(self->flowControlLock.present());
369 wait(self->flowControlLock.get()->take());

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected