| 1254 | } |
| 1255 | |
| 1256 | void GenericClusterImpl::ApplyRemovals(TxGraphImpl& graph, int level, std::span<GraphIndex>& to_remove) noexcept |
| 1257 | { |
| 1258 | // Iterate over the prefix of to_remove that applies to this cluster. |
| 1259 | Assume(!to_remove.empty()); |
| 1260 | SetType todo; |
| 1261 | graph.GetClusterSet(level).m_cluster_usage -= TotalMemoryUsage(); |
| 1262 | do { |
| 1263 | GraphIndex idx = to_remove.front(); |
| 1264 | Assume(idx < graph.m_entries.size()); |
| 1265 | auto& entry = graph.m_entries[idx]; |
| 1266 | auto& locator = entry.m_locator[level]; |
| 1267 | // Stop once we hit an entry that applies to another Cluster. |
| 1268 | if (locator.cluster != this) break; |
| 1269 | // - Remember it in a set of to-remove DepGraphIndexes. |
| 1270 | todo.Set(locator.index); |
| 1271 | // - Remove from m_mapping. This isn't strictly necessary as unused positions in m_mapping |
| 1272 | // are just never accessed, but set it to -1 here to increase the ability to detect a bug |
| 1273 | // that causes it to be accessed regardless. |
| 1274 | m_mapping[locator.index] = GraphIndex(-1); |
| 1275 | // - Remove its linearization index from the Entry (if in main). |
| 1276 | if (level == 0) { |
| 1277 | entry.m_main_lin_index = LinearizationIndex(-1); |
| 1278 | } |
| 1279 | // - Mark it as missing/removed in the Entry's locator. |
| 1280 | graph.ClearLocator(level, idx, m_quality == QualityLevel::OVERSIZED_SINGLETON); |
| 1281 | to_remove = to_remove.subspan(1); |
| 1282 | } while(!to_remove.empty()); |
| 1283 | |
| 1284 | Assume(todo.Any()); |
| 1285 | // Wipe from the Cluster's DepGraph (this is O(n) regardless of the number of entries |
| 1286 | // removed, so we benefit from batching all the removals). |
| 1287 | m_depgraph.RemoveTransactions(todo); |
| 1288 | m_mapping.resize(m_depgraph.PositionRange()); |
| 1289 | |
| 1290 | // Filter removed transactions out of m_linearization. |
| 1291 | m_linearization.erase(std::remove_if(m_linearization.begin(), m_linearization.end(), |
| 1292 | [&](auto pos) { return todo[pos]; }), |
| 1293 | m_linearization.end()); |
| 1294 | |
| 1295 | Compact(); |
| 1296 | graph.GetClusterSet(level).m_cluster_usage += TotalMemoryUsage(); |
| 1297 | auto new_quality = IsTopological() ? QualityLevel::NEEDS_SPLIT : QualityLevel::NEEDS_SPLIT_FIX; |
| 1298 | graph.SetClusterQuality(level, m_quality, m_setindex, new_quality); |
| 1299 | Updated(graph, /*level=*/level, /*rename=*/false); |
| 1300 | } |
| 1301 | |
| 1302 | void SingletonClusterImpl::ApplyRemovals(TxGraphImpl& graph, int level, std::span<GraphIndex>& to_remove) noexcept |
| 1303 | { |
nothing calls this directly
no test coverage detected