Aerospike_batch_get returns only last record


#1

Hi all! There is the problem with batch operations i can’t solve.

I have a keywords namespace consists of two sets: words and phrases. The phrases set’s records look like ‘prs’ => 'Hello world!' The words set’s records have an original record with primary key without index (“Hello”), which have only one bin (‘i’ => (integer)count_batches) - count of batches for this word Also the words set’s records have additional records for each word with primary keys like Hello1, Hello2 … Hello(cout_batches). Each additional record includes bin “prs” with phrases indexes list.

The problem: If i’m using as_batch operations, and then trying in callback function collect result data, i’m getting all batches (Hello1, Hello2, Hello3.), but with data only for the LAST batch (Hello(count_batches)). If i just init key for each batch there is no problem.

For example, i dumped count of “prs” bin (phrases indexes list) for each batch using batch operations: WORD - HELLO, bin “i” is 5 (it means that this word have 5 batches with indexes)

Result with batch cllback function (INCORRECT): batch_number 1 - 15 phrases batch_number 2 - 15 phrases batch_number 3 - 15 phrases batch_number 4 - 15 phrases batch_number 5 - 15 phrases

CODE:

       for (k = 0; k < 5; k++)
        {
            snprintf(batch_name, 130, "%s%d", normalized_splitted_phrases[i][j], k); в строку
            as_key_init_str(as_batch_keyat(&batch, k), "namespace", "words_batch", batch_name);
        }
        if (aerospike_batch_get(&as, &err, NULL, &batch, batchReadCallback, &word_phrases_indexes) != AEROSPIKE_OK)
        {
            goto next_phrase;
        }

bool batchReadCallback (const as_batch_read* results, uint32_t n, void* word_phrases_indexes)
{
uint32_t i, j, phrases_count = 0;
int *phrases_indexes;
as_list *batch_phrases_indexes;
for (i = 0; i < n; i++)
{
    if (results[i].result == AEROSPIKE_OK) индексами фраз
    {
        batch_phrases_indexes = as_record_get_list(&results[i].record, "prs");
        uint32_t count = as_list_size(batch_phrases_indexes);
        printf("batch number %d :%" PRIu32 " phrases<br>", i, count);
    }
    else if (results[i].result == AEROSPIKE_ERR_RECORD_NOT_FOUND)
    {
        printf("BATCH CALLBACK  - AEROSPIKE_ERR_RECORD_NOT_FOUND");
    }
    else
    {
        printf("  error %d", results[i].result);
    }
}

return true;
}

</code>



Result with initiating key for each batch without batch operations:
batch_number 1 - 3 phrases
batch_number 2 - 2 phrases
batch_number 3 - 11 phrases
batch_number 4 - 16 phrases
batch_number 5 - 15 phrases

CODE (CORRECT VARIANT):
<code>
   for (k = 0; k < 5; k++)
    {
        as_key_init_str(&key, "ppchelp", "words_batch", batch_name);
        aerospike_key_select(&as, &err, NULL, &key, batch_bins, &record);
        as_list *batch_phrases_indexes = as_record_get_list(record, "prs");
        uint32_t count = as_list_size(batch_phrases_indexes);
        printf("batches number %d: phrases: %" PRIu32 " key was ititiated manually<br>", k, count);
    }

I hope someone can help me with this, thanks.


#2

as_key_init_str() references the string, but it does not copy the string. Each batch key references the exact same “batch_name” string, so the last “batch_name” write is used for all batch keys.

One way to copy “batch_name”:

for (k = 0; k < 5; k++)
{
    snprintf(batch_name, 130, "%s%d", normalized_splitted_phrases[i][j], k); в строку
    as_key_init_strp(as_batch_keyat(&batch, k), "namespace", "words_batch", strdup(batch_name), true);
}

#3

Thanks a lot, man! I’m new in C, so that was my fail!:slight_smile: