Changeset: bf619e8d406d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/bf619e8d406d Modified Files: ChangeLog.Mar2025 sql/storage/bat/bat_storage.c sql/storage/bat/bat_storage.h Branch: Mar2025 Log Message:
make sure we don't search (linearly) for empty slots too often, fixed issue #7655 diffs (142 lines): diff --git a/ChangeLog.Mar2025 b/ChangeLog.Mar2025 --- a/ChangeLog.Mar2025 +++ b/ChangeLog.Mar2025 @@ -1,3 +1,7 @@ # ChangeLog file for devel # This file is updated with Maddlog +* Tue Jul 8 2025 Niels Nes <[email protected]> +- Fixed issue #7655, now the segments keep the number of deleted + rows. Only search for reuse when deleted rows are available. + diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c --- a/sql/storage/bat/bat_storage.c +++ b/sql/storage/bat/bat_storage.c @@ -264,6 +264,11 @@ rollback_segments(segments *segs, sql_tr segment *cur = segs->h, *seg = NULL; for (; cur; cur = ATOMIC_PTR_GET(&cur->next)) { if (cur->ts == tr->tid) { /* revert */ + if (!cur->deleted || cur->ts == cur->oldts) + ATOMIC_ADD(&segs->deleted, cur->end - cur->start); + else + ATOMIC_SUB(&segs->deleted, cur->end - cur->start); + cur->deleted = !cur->deleted || (cur->ts == cur->oldts); cur->ts = cur->oldts==tr->tid?0:cur->oldts; /* need old ts */ cur->oldts = 0; @@ -509,6 +514,7 @@ new_segments(sql_trans *tr, size_t cnt) if (n) { n->nr_reused = 0; + n->deleted = 0; n->h = n->t = new_segment(NULL, tr, cnt); if (!n->h) { GDKfree(n); @@ -2412,6 +2418,7 @@ storage_delete_val(sql_trans *tr, sql_ta unlock_table(tr->store, t->base.id); return LOG_ERR; } + ATOMIC_ADD(&s->segs->deleted, 1); break; } } @@ -2433,6 +2440,7 @@ seg_delete_range(sql_trans *tr, sql_tabl if (SEG_IS_DELETED(seg, tr)) { start += lcnt; cnt -= lcnt; + ATOMIC_ADD(&s->segs->deleted, lcnt); continue; } else if (!SEG_VALID_4_DELETE(seg, tr)) return LOG_CONFLICT; @@ -2443,6 +2451,7 @@ seg_delete_range(sql_trans *tr, sql_tabl return LOG_ERR; start += lcnt; cnt -= lcnt; + ATOMIC_ADD(&s->segs->deleted, lcnt); } if (start+cnt <= seg->end) break; @@ -3952,8 +3961,10 @@ clear_table(sql_trans *tr, sql_table *t) return clear_ok; } } - if (clear) + if (clear) { d->segs->nr_reused = 0; + d->segs->deleted = 0; + } return sz; } @@ -4693,6 +4704,7 @@ claim_segmentsV2(sql_trans *tr, sql_tabl lock_table(tr->store, t->base.id); int in_transaction = segments_in_transaction(tr, t), ok = LOG_OK; /* naive vacuum approach, iterator through segments, use deleted segments or create new segment at the end */ + if (s->segs->deleted) for (segment *seg = s->segs->h, *p = NULL; seg && cnt && ok == LOG_OK; p = seg, seg = ATOMIC_PTR_GET(&seg->next)) { if (seg->deleted && seg->ts < oldest && seg->end > seg->start) { /* reuse old deleted or rolled back append */ if ((seg->end - seg->start) >= cnt) { @@ -4706,6 +4718,7 @@ claim_segmentsV2(sql_trans *tr, sql_tabl break; } s->segs->nr_reused += cnt; + ATOMIC_SUB(&s->segs->deleted, cnt); cnt = 0; break; } @@ -4725,8 +4738,10 @@ claim_segmentsV2(sql_trans *tr, sql_tabl ok = LOG_ERR; break; } - s->segs->nr_reused += (seg->end - seg->start); - cnt -= (seg->end - seg->start); + size_t rcnt = seg->end - seg->start; + s->segs->nr_reused += rcnt; + cnt -= rcnt; + ATOMIC_SUB(&s->segs->deleted, rcnt); } } if (ok == LOG_OK && cnt) { @@ -4785,6 +4800,7 @@ claim_segments(sql_trans *tr, sql_table int in_transaction = segments_in_transaction(tr, t), ok = LOG_OK; /* naive vacuum approach, iterator through segments, check for large enough deleted segments * or create new segment at the end */ + if (s->segs->deleted) for (segment *seg = s->segs->h, *p = NULL; seg && ok == LOG_OK; p = seg, seg = ATOMIC_PTR_GET(&seg->next)) { if (seg->deleted && seg->ts < oldest && (seg->end-seg->start) >= cnt) { /* reuse old deleted or rolled back append */ @@ -4796,6 +4812,7 @@ claim_segments(sql_trans *tr, sql_table p->end += cnt; seg->start += cnt; s->segs->nr_reused += cnt; + ATOMIC_SUB(&s->segs->deleted, cnt); reused = 1; break; } @@ -4809,6 +4826,7 @@ claim_segments(sql_trans *tr, sql_table seg->deleted = false; slot = seg->start; s->segs->nr_reused += cnt; + ATOMIC_SUB(&s->segs->deleted, cnt); reused = 1; break; } @@ -5104,6 +5122,7 @@ vacuum_tab(sql_trans *tr, sql_table *t, return res; } s->segs->nr_reused = 0; + s->segs->deleted = 0; return LOG_OK; } diff --git a/sql/storage/bat/bat_storage.h b/sql/storage/bat/bat_storage.h --- a/sql/storage/bat/bat_storage.h +++ b/sql/storage/bat/bat_storage.h @@ -51,6 +51,7 @@ typedef struct segment { typedef struct segments { sql_ref r; ulng nr_reused; + ATOMIC_TYPE deleted; struct segment *h; struct segment *t; } segments; _______________________________________________ checkin-list mailing list -- [email protected] To unsubscribe send an email to [email protected]
