index nodes in an asynchronous manner nodes are being indexed in batchs while the graph's read lock is held to avoid interfering with the DB ongoing operation after each batch of nodes is indexed the graph read lock is released alowing for write queries to be processed it is safe to run a write query which effects the index by either: adding/removing/updating an entity while the index is being po
| 20 | // adding/removing/updating an entity while the index is being populated |
| 21 | // in the "worst" case we will index that entity twice which is perfectly OK |
| 22 | static void _Index_PopulateNodeIndex |
| 23 | ( |
| 24 | Index idx, |
| 25 | Graph *g |
| 26 | ) { |
| 27 | ASSERT(g != NULL); |
| 28 | ASSERT(idx != NULL); |
| 29 | |
| 30 | GrB_Index rowIdx = 0; |
| 31 | int indexed = 0; // #entities in current batch |
| 32 | int batch_size = 10000; // max #entities to index in one go |
| 33 | RG_MatrixTupleIter it = {0}; |
| 34 | |
| 35 | while(true) { |
| 36 | // lock graph for reading |
| 37 | Graph_AcquireReadLock(g); |
| 38 | |
| 39 | // index state changed, abort indexing |
| 40 | // this can happen if for example the following sequance is issued: |
| 41 | // 1. CREATE INDEX FOR (n:Person) ON (n.age) |
| 42 | // 2. CREATE INDEX FOR (n:Person) ON (n.height) |
| 43 | if(Index_PendingChanges(idx) > 1) { |
| 44 | break; |
| 45 | } |
| 46 | |
| 47 | // reset number of indexed nodes in batch |
| 48 | indexed = 0; |
| 49 | |
| 50 | // fetch label matrix |
| 51 | const RG_Matrix m = Graph_GetLabelMatrix(g, Index_GetLabelID(idx)); |
| 52 | ASSERT(m != NULL); |
| 53 | |
| 54 | //---------------------------------------------------------------------- |
| 55 | // resume scanning from rowIdx |
| 56 | //---------------------------------------------------------------------- |
| 57 | |
| 58 | GrB_Info info; |
| 59 | info = RG_MatrixTupleIter_attach(&it, m); |
| 60 | ASSERT(info == GrB_SUCCESS); |
| 61 | info = RG_MatrixTupleIter_iterate_range(&it, rowIdx, UINT64_MAX); |
| 62 | ASSERT(info == GrB_SUCCESS); |
| 63 | |
| 64 | //---------------------------------------------------------------------- |
| 65 | // batch index nodes |
| 66 | //---------------------------------------------------------------------- |
| 67 | |
| 68 | EntityID id; |
| 69 | while(indexed < batch_size && |
| 70 | RG_MatrixTupleIter_next_BOOL(&it, &id, NULL, NULL) == GrB_SUCCESS) |
| 71 | { |
| 72 | Node n; |
| 73 | Graph_GetNode(g, id, &n); |
| 74 | Index_IndexNode(idx, &n); |
| 75 | indexed++; |
| 76 | } |
| 77 | |
| 78 | //---------------------------------------------------------------------- |
| 79 | // done with current batch |
no test coverage detected