@@ -390,6 +390,45 @@ LoadElementsForInsert(HnswNeighborArray * neighbors, Datum q, int *idx, Relation
390
390
}
391
391
}
392
392
393
+ /*
394
+ * Get update index
395
+ */
396
+ static int
397
+ GetUpdateIndex (HnswElement element , HnswElement newElement , float distance , int m , int lm , int lc , Relation index , FmgrInfo * procinfo , Oid collation )
398
+ {
399
+ char * base = NULL ;
400
+ int idx = -1 ;
401
+ HnswNeighborArray * neighbors ;
402
+
403
+ /*
404
+ * Get latest neighbors since they may have changed. Do not lock yet since
405
+ * selecting neighbors can take time. Could use optimistic locking to
406
+ * retry if another update occurs before getting exclusive lock.
407
+ */
408
+ neighbors = HnswLoadNeighbors (element , index , m , lm , lc );
409
+
410
+ /*
411
+ * Could improve performance for vacuuming by checking neighbors against
412
+ * list of elements being deleted to find index. It's important to exclude
413
+ * already deleted elements for this since they can be replaced at any
414
+ * time.
415
+ */
416
+
417
+ if (neighbors -> length < lm )
418
+ idx = -2 ;
419
+ else
420
+ {
421
+ Datum q = HnswGetValue (base , element );
422
+
423
+ LoadElementsForInsert (neighbors , q , & idx , index , procinfo , collation );
424
+
425
+ if (idx == -1 )
426
+ HnswUpdateConnection (base , neighbors , newElement , distance , lm , & idx , index , procinfo , collation );
427
+ }
428
+
429
+ return idx ;
430
+ }
431
+
393
432
/*
394
433
* Check if connection already exists
395
434
*/
@@ -430,39 +469,12 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns
430
469
Page page ;
431
470
GenericXLogState * state ;
432
471
HnswNeighborTuple ntup ;
433
- int idx = -1 ;
472
+ int idx ;
434
473
int startIdx ;
435
474
HnswElement neighborElement = HnswPtrAccess (base , hc -> element );
436
475
OffsetNumber offno = neighborElement -> neighborOffno ;
437
- HnswNeighborArray * neighborNeighbors ;
438
476
439
- /*
440
- * Get latest neighbors since they may have changed. Do not lock
441
- * yet since selecting neighbors can take time. Could use
442
- * optimistic locking to retry if another update occurs before
443
- * getting exclusive lock.
444
- */
445
- neighborNeighbors = HnswLoadNeighbors (neighborElement , index , m , lm , lc );
446
-
447
- /*
448
- * Could improve performance for vacuuming by checking neighbors
449
- * against list of elements being deleted to find index. It's
450
- * important to exclude already deleted elements for this since
451
- * they can be replaced at any time.
452
- */
453
-
454
- /* Select neighbors */
455
- if (neighborNeighbors -> length < lm )
456
- idx = -2 ;
457
- else
458
- {
459
- Datum q = HnswGetValue (base , neighborElement );
460
-
461
- LoadElementsForInsert (neighborNeighbors , q , & idx , index , procinfo , collation );
462
-
463
- if (idx == -1 )
464
- HnswUpdateConnection (base , neighborNeighbors , e , hc -> distance , lm , & idx , index , procinfo , collation );
465
- }
477
+ idx = GetUpdateIndex (neighborElement , e , hc -> distance , m , lm , lc , index , procinfo , collation );
466
478
467
479
/* New element was not selected as a neighbor */
468
480
if (idx == -1 )
0 commit comments