Skip to content

Commit ff7d474

Browse files
committed
Another iteration based on b2nd_resize
1 parent 7fd4dbf commit ff7d474

File tree

1 file changed

+39
-65
lines changed

1 file changed

+39
-65
lines changed

blosc/b2nd.c

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,91 +1336,65 @@ int b2nd_concatenate(b2nd_context_t *ctx, b2nd_array_t **array, const b2nd_array
13361336
BLOSC_ERROR_NULL(src2, BLOSC2_ERROR_NULL_POINTER);
13371337
BLOSC_ERROR_NULL(array, BLOSC2_ERROR_NULL_POINTER);
13381338

1339-
ctx->ndim = src1->ndim;
1340-
// Compute the new shape while checking that the shapes are compatible with the other axes
1339+
// For starters, create a copy of src1 array
1340+
BLOSC_ERROR(b2nd_copy(ctx, src1, array));
1341+
1342+
// Check that the shapes are compatible for concatenation
1343+
if (src1->ndim != src2->ndim) {
1344+
BLOSC_TRACE_ERROR("The two arrays must have the same number of dimensions");
1345+
BLOSC_ERROR(BLOSC2_ERROR_INVALID_PARAM);
1346+
}
1347+
// Compute the new shape
1348+
int64_t newshape[B2ND_MAX_DIM];
13411349
for (int i = 0; i < src1->ndim; ++i) {
13421350
if (i == axis) {
1343-
ctx->shape[i] = src1->shape[i] + src2->shape[i];
1351+
newshape[i] = src1->shape[i] + src2->shape[i];
13441352
} else {
13451353
if (src1->shape[i] != src2->shape[i]) {
1346-
BLOSC_TRACE_ERROR("The shapes of the arrays are not compatible in axis %d", i);
1354+
BLOSC_TRACE_ERROR("The two arrays must have the same shape in all dimensions except the concatenation axis");
13471355
BLOSC_ERROR(BLOSC2_ERROR_INVALID_PARAM);
13481356
}
1349-
ctx->shape[i] = src1->shape[i];
1357+
newshape[i] = src1->shape[i];
13501358
}
13511359
}
13521360

1353-
// Use the same chunkshape and blockshape as src1
1354-
for (int i = 0; i < src1->ndim; ++i) {
1355-
ctx->chunkshape[i] = src1->chunkshape[i];
1356-
ctx->blockshape[i] = src1->blockshape[i];
1357-
}
1358-
1359-
// Create a container for the new array
1360-
BLOSC_ERROR(b2nd_empty(ctx, array));
1361+
// Extend the array, we don't need to specify the start in resize, as we are extending the shape from the end
1362+
BLOSC_ERROR(b2nd_resize(*array, newshape, NULL));
13611363

1362-
// Copy the data from the first array
1364+
// Copy the data from the second array
13631365
int64_t start[B2ND_MAX_DIM] = {0};
13641366
int64_t stop[B2ND_MAX_DIM];
1365-
for (int i = 0; i < src1->ndim; ++i) {
1366-
stop[i] = src1->shape[i];
1367-
}
1368-
// Copy src1 data chunk by chunk
1369-
void *buffer = malloc(src1->sc->typesize * src1->extchunknitems);
1370-
BLOSC_ERROR_NULL(buffer, BLOSC2_ERROR_MEMORY_ALLOC);
1371-
for (int64_t nchunk = 0; nchunk < src1->sc->nchunks; ++nchunk) {
1372-
BLOSC_ERROR(blosc2_schunk_decompress_chunk(src1->sc, nchunk, buffer,
1373-
src1->sc->typesize * src1->extchunknitems));
1374-
BLOSC_ERROR(b2nd_set_slice_cbuffer(buffer, src1->chunkshape, src1->sc->typesize * src1->extchunknitems,
1375-
start, stop, *array));
1376-
}
1377-
free(buffer);
1378-
1379-
// Copy the data from the second array
1380-
for (int i = 0; i < src2->ndim; ++i) {
1381-
if (i == axis) {
1382-
start[i] = src1->shape[i];
1383-
stop[i] = start[i] + src2->shape[i];
1384-
} else {
1385-
start[i] = 0;
1386-
stop[i] = src2->shape[i];
1387-
}
1388-
}
1389-
// Copy src2 data chunk by chunk
1390-
buffer = malloc(src2->sc->typesize * src2->extchunknitems);
1367+
// Copy chunk by chunk
1368+
void *buffer = malloc(src2->sc->typesize * src2->extchunknitems);
13911369
BLOSC_ERROR_NULL(buffer, BLOSC2_ERROR_MEMORY_ALLOC);
13921370
for (int64_t nchunk = 0; nchunk < src2->sc->nchunks; ++nchunk) {
13931371
BLOSC_ERROR(blosc2_schunk_decompress_chunk(src2->sc, nchunk, buffer,
13941372
src2->sc->typesize * src2->extchunknitems));
1395-
BLOSC_ERROR(b2nd_set_slice_cbuffer(buffer, src2->chunkshape, src2->sc->typesize * src2->extchunknitems,
1396-
start, stop, *array));
1397-
}
1398-
free(buffer);
1373+
// Get multidimensional chunk position
1374+
int64_t nchunk_ndim[B2ND_MAX_DIM] = {0};
1375+
blosc2_unidim_to_multidim(src2->ndim, src2->chunkshape, nchunk, nchunk_ndim);
1376+
1377+
// Set positions for each dimension
1378+
for (int i = 0; i < src2->ndim; ++i) {
1379+
start[i] = nchunk_ndim[i] * src2->chunkshape[i];
1380+
stop[i] = start[i] + src2->chunkshape[i];
1381+
if (stop[i] > src2->shape[i]) {
1382+
stop[i] = src2->shape[i]; // Handle boundary chunks
1383+
}
13991384

1400-
// Copy the metalayers from src1
1401-
blosc2_storage *b2_storage = ctx->b2_storage;
1402-
blosc2_schunk *schunk = src1->sc;
1403-
blosc2_schunk *new_schunk = (*array)->sc;
1404-
for (int nmeta = 0; nmeta < schunk->nmetalayers; ++nmeta) {
1405-
blosc2_metalayer *meta = schunk->metalayers[nmeta];
1406-
if (blosc2_meta_add(new_schunk, meta->name, meta->content, meta->content_len) < 0) {
1407-
BLOSC_TRACE_ERROR("Can not add %s `metalayer`.", meta->name);
1408-
return BLOSC2_ERROR_FAILURE;
1385+
// Apply offset only for concatenation axis
1386+
if (i == axis) {
1387+
start[i] += src1->shape[i];
1388+
stop[i] += src1->shape[i];
1389+
}
14091390
}
1410-
}
14111391

1412-
// Copy the vlmetalayers from src1
1413-
for (int nvlmeta = 0; nvlmeta < schunk->nvlmetalayers; ++nvlmeta) {
1414-
uint8_t *content;
1415-
int32_t content_len;
1416-
if (blosc2_vlmeta_get(schunk, schunk->vlmetalayers[nvlmeta]->name, &content,
1417-
&content_len) < 0) {
1418-
BLOSC_ERROR(BLOSC2_ERROR_FAILURE);
1419-
}
1420-
BLOSC_ERROR(blosc2_vlmeta_add(new_schunk, schunk->vlmetalayers[nvlmeta]->name, content,
1421-
content_len, b2_storage->cparams));
1422-
free(content);
1392+
// Copy the chunk to the correct position
1393+
BLOSC_ERROR(b2nd_set_slice_cbuffer(buffer, src2->chunkshape,
1394+
src2->sc->typesize * src2->extchunknitems,
1395+
start, stop, *array));
14231396
}
1397+
free(buffer);
14241398

14251399
return BLOSC2_ERROR_SUCCESS;
14261400
}

0 commit comments

Comments
 (0)