@@ -1301,7 +1301,7 @@ aqo_data_store(uint64 fs, int fss, OkNNrdata *data, List *reloids)
13011301bool tblOverflow ;
13021302HASHACTION action ;
13031303bool result ;
1304- NeighboursEntry * prev_fs ;
1304+ NeighboursEntry * prev ;
13051305
13061306Assert (!LWLockHeldByMe (& aqo_state -> data_lock ));
13071307
@@ -1389,28 +1389,25 @@ aqo_data_store(uint64 fs, int fss, OkNNrdata *data, List *reloids)
13891389* Find prev fs with the same fss
13901390*/
13911391
1392- LWLockAcquire (& aqo_state -> neighbours_lock ,LW_EXCLUSIVE );
1392+ if (!found ) {
1393+ LWLockAcquire (& aqo_state -> neighbours_lock ,LW_EXCLUSIVE );
13931394
1394- prev_fs = (NeighboursEntry * )hash_search (fss_neighbours ,& fss ,HASH_ENTER ,& found );
1395- if (!found )
1396- {
1397- entry -> list .prev_fs = fs ;
1398- entry -> list .next_fs = fs ;
1399- }
1400- else
1401- {
1402- data_key prev_key = {.fs = prev_fs -> fs , .fss = fss };
1403- DataEntry * prev ;
1395+ prev = (NeighboursEntry * )hash_search (fss_neighbours ,& fss ,HASH_ENTER ,& found );
1396+ if (!found )
1397+ {
1398+ entry -> list .prev = NULL ;
1399+ entry -> list .next = NULL ;
1400+ }
1401+ else
1402+ {
1403+ prev -> data -> list .next = entry ;
1404+ entry -> list .next = NULL ;
1405+ entry -> list .prev = prev -> data ;
1406+ }
1407+ prev -> data = entry ;
14041408
1405- prev = (DataEntry * )hash_search (data_htab ,& prev_key ,HASH_FIND ,NULL );
1406- prev -> list .next_fs = fs ;
1407- entry -> list .next_fs = fs ;
1408- entry -> list .prev_fs = prev -> key .fs ;
1409+ LWLockRelease (& aqo_state -> neighbours_lock );
14091410}
1410- prev_fs -> fs = entry -> key .fs ;
1411-
1412- LWLockRelease (& aqo_state -> neighbours_lock );
1413-
14141411
14151412/*
14161413 * Copy AQO data into allocated DSA segment
@@ -1587,6 +1584,7 @@ load_aqo_data(uint64 fs, int fss, OkNNrdata *data, List **reloids,
15871584int noids = -1 ;
15881585
15891586found = false;
1587+ // TODO replace with hash
15901588hash_seq_init (& hash_seq ,data_htab );
15911589while ((entry = hash_seq_search (& hash_seq ))!= NULL )
15921590{
@@ -1681,8 +1679,8 @@ aqo_data(PG_FUNCTION_ARGS)
16811679values [AD_FS ]= Int64GetDatum (entry -> key .fs );
16821680values [AD_FSS ]= Int32GetDatum ((int )entry -> key .fss );
16831681values [AD_NFEATURES ]= Int32GetDatum (entry -> cols );
1684- values [AD_PREV_FS ]= Int64GetDatum (entry -> list .prev_fs );
1685- values [AD_NEXT_FS ]= Int64GetDatum (entry -> list .next_fs );
1682+ values [AD_PREV_FS ]= Int64GetDatum (entry -> list .prev );
1683+ values [AD_NEXT_FS ]= Int64GetDatum (entry -> list .next );
16861684
16871685/* Fill values from the DSA data chunk */
16881686Assert (DsaPointerIsValid (entry -> data_dp ));
@@ -2167,44 +2165,33 @@ cleanup_aqo_database(bool gentle, int *fs_num, int *fss_num)
21672165{
21682166data_key key = {.fs = entry -> fs , .fss = lfirst_int (lc )};
21692167bool found ;
2170- bool has_prev_fs = false;
2171- bool has_next_fs = false;
2172- DataEntry * current_entry ;
2173- DataEntry * prev_entry ;
2174- DataEntry * next_entry ;
2168+ bool has_prev = false;
2169+ bool has_next = false;
2170+ DataEntry * entry ;
21752171NeighboursEntry * fss_htab_entry ;
21762172
21772173/* fix fs list */
2178- current_entry = (DataEntry * )hash_search (data_htab ,& key ,HASH_FIND ,& found );
2174+ entry = (DataEntry * )hash_search (data_htab ,& key ,HASH_FIND ,& found );
21792175if (found )
21802176{
2181- data_key neighbour_key = {.fs = current_entry -> list .prev_fs , .fss = key .fss };
2182-
2183- if (key .fs != current_entry -> list .prev_fs )
2184- {
2185- prev_entry = (DataEntry * )hash_search (data_htab ,& neighbour_key ,HASH_FIND ,& has_prev_fs );
2186- }
2187-
2188- neighbour_key .fs = current_entry -> list .next_fs ;
2189- if (key .fs != current_entry -> list .next_fs )
2190- {
2191- next_entry = (DataEntry * )hash_search (data_htab ,& neighbour_key ,HASH_FIND ,& has_next_fs );
2192- }
2193-
2194- if (has_prev_fs )
2195- prev_entry -> list .next_fs = has_next_fs ?current_entry -> list .next_fs :prev_entry -> key .fs ;
2196- if (has_next_fs )
2197- next_entry -> list .prev_fs = has_prev_fs ?current_entry -> list .prev_fs :next_entry -> key .fs ;
2198-
2177+ if (entry -> list .next )
2178+ has_next = true;
2179+ if (entry -> list .prev )
2180+ has_prev = true;
2181+
2182+ if (has_prev )
2183+ entry -> list .prev -> list .next = has_next ?entry -> list .next :NULL ;
2184+ if (has_next )
2185+ entry -> list .next -> list .prev = has_prev ?entry -> list .prev :NULL ;
21992186}
22002187
22012188/* Fix or remove neighbours htab entry*/
22022189fss_htab_entry = (NeighboursEntry * )hash_search (fss_neighbours ,& key .fss ,HASH_FIND ,& found );
2203- if (found && fss_htab_entry -> fs == key .fs )
2190+ if (found && fss_htab_entry -> data -> key . fs == key .fs )
22042191{
2205- if (has_prev_fs )
2192+ if (has_prev )
22062193{
2207- fss_htab_entry -> fs = prev_entry -> key . fs ;
2194+ fss_htab_entry -> data = entry -> list . prev ;
22082195}
22092196else
22102197{