Changeset: 83738f70abe8 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/83738f70abe8
Modified Files:
sql/storage/bat/bat_storage.c
Branch: default
Log Message:
store_functions.append_col forgot to handle the case where *offsets is not NULL
Append_col takes BUN offset and BAT *offsets to indicate where to store the
data, and a void pointer to the data itself.
The void pointer can either be a BAT or a pointer to an array.
In the latter case, the offsets BAT was ignored.
The code is a little tricky because we have to figure out which offsets
are updates of existing values and which offsets denote newly appended values.
I hope I got it right.
diffs (77 lines):
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
@@ -2257,8 +2257,35 @@ delta_append_bat(sql_trans *tr, sql_delt
return (err)?LOG_ERR:LOG_OK;
}
+// Look at the offsets and find where the replacements end and the appends
begin.
+static BUN
+start_of_appends(BAT *offsets, BUN bcnt)
+{
+ BUN ocnt = BATcount(offsets);
+ if (ocnt == 0)
+ return 0;
+
+ BUN highest = *(oid*)Tloc(offsets, ocnt - 1);
+ if (highest < bcnt)
+ // all are replacements
+ return ocnt;
+
+ // reason backward to find the first append.
+ // Suppose offsets has 15 entries, bcnt == 100
+ // and the highest offset in offsets is 109.
+ BUN new_bcnt = highest + 1; // 110
+ BUN nappends = new_bcnt - bcnt; // 10
+ BUN nreplacements = ocnt - nappends; // 5
+
+ // The first append should be to position bcnt
+ assert(bcnt == *(oid*)Tloc(offsets, nreplacements));
+
+ return nreplacements;
+}
+
+
static int
-delta_append_val(sql_trans *tr, sql_delta **batp, sqlid id, BUN offset, void
*i, BUN cnt, char *storage_type, int tt)
+delta_append_val(sql_trans *tr, sql_delta **batp, sqlid id, BUN offset, BAT
*offsets, void *i, BUN cnt, char *storage_type, int tt)
{
void *oi = i;
BAT *b;
@@ -2292,6 +2319,27 @@ delta_append_val(sql_trans *tr, sql_delt
return LOG_ERR;
}
BUN bcnt = BATcount(b);
+
+ if (offsets) {
+ // The first few might be replacements while later items might
be appends.
+ // Handle the replacements here while leaving the appends to
the code below.
+ BUN nreplacements = start_of_appends(offsets, bcnt);
+
+ oid *start = Tloc(offsets, 0);
+ if (BUNreplacemulti(b, start, i, nreplacements, true) !=
GDK_SUCCEED) {
+ bat_destroy(b);
+ if (i != oi)
+ GDKfree(i);
+ unlock_column(tr->store, id);
+ return LOG_ERR;
+ }
+
+ // Replacements have been handled. The rest are appends.
+ assert(offset == oid_nil);
+ offset = bcnt;
+ cnt -= nreplacements;
+ }
+
if (bcnt > offset){
size_t ccnt = ((offset+cnt) > bcnt)? (bcnt - offset):cnt;
if (BUNreplacemultiincr(b, offset, i, ccnt, true) !=
GDK_SUCCEED) {
@@ -2354,7 +2402,7 @@ append_col_execute(sql_trans *tr, sql_de
if (BATcount(bat))
ok = delta_append_bat(tr, delta, id, offset, offsets,
bat, storage_type);
} else {
- ok = delta_append_val(tr, delta, id, offset, incoming_data,
cnt, storage_type, tt);
+ ok = delta_append_val(tr, delta, id, offset, offsets,
incoming_data, cnt, storage_type, tt);
}
return ok;
}
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]