sstore_batch_alloc, sstore_batch_call, sstore_batch_data_read, sstore_batch_free, sstore_batch_info_read, sstore_batch_iter_next, sstore_batch_namespace_list - TBD
cc [ flag... ] file... -lsstore [ library... ] #include <libsstore.h> sstore_batch_t sstore_batch_alloc(void); void sstore_batch_free(sstore_batch_t b_hdl); sstore_err_t sstore_batch_data_read(sstore_handle_t hdl, sstore_batch_t b_hdl, void *cookie, const char **ids, uint32_t id_count, sstore_range_t range, sstore_walk_t walk); sstore_err_t sstore_batch_info_read(sstore_handle_t hdl, sstore_batch_t b_hdl, void *cookie, const char **ids, uint32_t id_count, sstore_range_t range); sstore_err_t sstore_batch_namespace_list(sstore_handle_t hdl, sstore_batch_t b_hdl, void *cookie, const char **ids, uint32_t id_count, sstore_range_t range); sstore_err_t sstore_batch_call(sstore_handle_t hdl, sstore_batch_t b_hdl, sstore_iter_t *b_iterp); sstore_err_t sstore_batch_iter_next(sstore_handle_t hdl, sstore_iter_t b_iter, void **cookiep, sstore_iter_t *iterp, sstore_result_type_t *typep);
Handle to a batch object
Handle to libsstore
Cookie to associate the result with the request
Array of ssids
Total number of statistics store identifiers
Time range or data range.
Passing NULL for range implies:
start-time = SS_TIME_NOW
end-time = SS_TIME_NOW
step = (None - raw data)
Format of the iteration. The following formats are supported:
Walks the data records by identifier
Walks the data records by timestamps
Statistics store identifier
Address to store the starting address of the batch iterator
Batch iterator
Address to store the cookie associated with the batch request
Address to store the starting address of the iterator returned from batch request execution
Address to store the result type of the batch request. Address can be one of the following values:
Request executed successfully and the result is an iterator
Request executed successfully and there is no data to be returned
Request execution resulted in an error
The batch interface provides a way to get a single iterator for the results of multiple requests. To do this, all the individual requests are queued up in a batch object using the interfaces for batching different types of request. A cookie can be provided while batching a request in order to associate the result of that request with the cookie. That batch object is then passed to sstore_batch_call(3SSTORE), which executes all the requests and generates an iterator that contains the result for all the requests in that batch object.
sstore_batch_alloc() allocates a batch handle.
sstore_batch_free() frees the batch handle.
The sstore_batch_data_read(), sstore_batch_info_read(), and sstore_batch_namespace_list() functions batch sstore_data_read(3SSTORE), sstore_info_read(3SSTORE), and sstore_namespace_list(3SSTORE) respectively to the batch object. These batch functions defer the execution of the corresponding non-batch functions until sstore_batch_call() is called with the given batch handle. Each of these batch functions takes a cookie that will be returned while iterating the result for the corresponding request. The caller is responsible for the memory management of this cookie. The remaining arguments are similar to the same arguments for the corresponding non-batch functions except that the batch functions do not return an iterator because they just add the request to the batch handle and defer the execution.
sstore_batch_call() executes all the requests added to the batch handle and returns an iterator that can be used to iterate over the results. The caller is responsible for freeing the returned iterator by using sstore_iter_free().
sstore_batch_iter_next() retrieves the result from the execution of the next batch request. It populates cookiep with the cookie that is passed when the batch request was added to the batch handle. It also populates typep with the appropriate enumerated value based on the result of the execution of the corresponding request. If no error occurs during the request execution, and if typep is set to SSTORE_RESULT_TYPE_ITER, then it populates iterp with the iterator. The caller should not free this iterator because the iterator will be freed when sstore_batch_iter_next() is called again or when the batch iterator itself is freed.
sstore_batch_iter_next() also caches any warnings set during the request execution in the given libsstore handle. If the request execution results in an error, then the error code, description, and action are cached in the given libsstore handle.
sstore_batch_data_read(), sstore_batch_info_read(), and sstore_batch_namespace_list() require the same authorizations as their non-batch counterparts.
Upon successful completion, sstore_batch_alloc() returns an sstore_batch_t. Otherwise it returns NULL.
Upon successful completion, sstore_batch_data_read(), sstore_batch_info_read(), sstore_batch_namespace_list(), sstore_batch_call(), and sstore_batch_iter_next() return ESSTORE_OK. Otherwise they return an error code.
Except for sstore_batch_iter_next(), all of the batch APIs returning an sstore_err_t cache the error code and the corresponding description and action strings in the given libsstore handle.
The sstore_batch_alloc() function fails if:
There is insufficient memory.
The sstore_batch_data_read(), sstore_batch_info_read() and sstore_batch_namespace_list() functions fail if:
The batch handle is invalid.
The libsstore handle is invalid.
There is insufficient memory.
The sstore_batch_call() function fails if:
Some arguments are invalid.
The libsstore handle is invalid.
Failed to connect to the sstored(8).
No memory is available.
The sstore_batch_iter_next() function fails if:
Some arguments are invalid.
The libsstore handle is invalid.
No more records remain.
#include <libsstore.h> #include <stdio.h> #include <unistd.h> #define FLOOR(ts) (((ts) / 1000000) * 1000000) #define HFMT "%-53s %-16s %s\n" #define IFMTU "%-53s %16llu\n" #define IFMTS "%-53s %-16s" /* List of ssids */ const char *ids[] = { "//:class.cpu//:stat.xcalls//:part.cpu(1,2)" }; uint32_t id_count = 1; sstore_handle_t hdl = NULL; void print_iter(sstore_iter_t); void print_error(void) { if (sstore_err_code(hdl) != ESSTORE_OK && sstore_err_code(hdl) != ESSTORE_ITER_DONE) { fprintf(stderr, "%s. Error: %s\n", sstore_err_action(hdl), sstore_err_description(hdl)); } } /* * Prints the value in the value handle. */ sstore_err_t print_value(sstore_value_t val) { uint64_t val_u64; char *val_str, **val_strarr, *dict_key; sstore_value_t dict_val; uint32_t count, i; if (val == NULL) { return (ESSTORE_OK); } switch(sstore_value_type(val)) { case SSTORE_VALUE_NUMBER: if (sstore_value_number(hdl, val, &val_u64) != ESSTORE_OK) { break; } printf("%lu\n", val_u64); break; case SSTORE_VALUE_STRING: if (sstore_value_string(hdl, val, &val_str) != ESSTORE_OK) { break; } printf("%s\n", val_str); break; case SSTORE_VALUE_STRING_ARRAY: if (sstore_value_string_array(hdl, val, &val_strarr, &count) != ESSTORE_OK) { break; } for (i = 0; i < count; i++) { printf("%s ", val_strarr[i]); } printf("\n"); break; case SSTORE_VALUE_DICTIONARY: printf("\n"); while (sstore_value_dictionary_next(hdl, val, &dict_key, &dict_val) == ESSTORE_OK) { printf("%12s: ", dict_key); print_value(dict_val); } printf("\n"); break; case SSTORE_VALUE_NODATA: printf("NO_DATA\n"); break; default: printf("Unexpected value type %d\n", sstore_value_type(val)); } return (sstore_err_code(hdl)); } void print_data_iter(sstore_iter_t iter) { sstore_value_t val; sstore_err_t err; char *id; uint64_t ts; printf(HFMT, "IDENTIFIER", "TIMESTAMP", "VALUE"); while (sstore_data_iter_next(hdl, iter, &id, &ts, &val) == ESSTORE_OK) { /* Round down the time stamp */ ts = FLOOR(ts); printf(IFMTU, id, ts); err = print_value(val); if (err != ESSTORE_OK && err != ESSTORE_ITER_DONE) { break; } } return; } void print_info_iter(sstore_iter_t iter) { sstore_value_t val; sstore_err_t err; char *id; uint64_t ts; printf(HFMT, "IDENTIFIER", "TIMESTAMP", "VALUE"); while (sstore_info_iter_next(hdl, iter, &id, &ts, &val) == ESSTORE_OK) { /* Round out the times */ ts = FLOOR(ts); printf(IFMTU, id, ts); err = print_value(val); if (err != ESSTORE_OK && err != ESSTORE_ITER_DONE) { break; } } return; } void print_ns_iter(sstore_iter_t iter) { char *id; uint64_t start_ts, end_ts; char ts[16]; printf(HFMT, "IDENTIFIER", "START", "END"); while (sstore_namespace_iter_next(hdl, iter, &id, &start_ts, &end_ts) == ESSTORE_OK) { /* Round out the times */ start_ts = FLOOR(start_ts); end_ts = FLOOR(end_ts); if (start_ts == 0) { (void) snprintf(ts, sizeof (ts), "UNKNOWN"); } else { (void) snprintf(ts, sizeof (ts), "%llu", start_ts); } printf(IFMTS, id, ts); if (end_ts == 0) { printf(" ACTIVE\n"); } else { printf(" %lu\n", end_ts); } } return; } void print_batch_iter(sstore_iter_t b_iter) { char *cookie; sstore_iter_t iter; sstore_result_type_t type; /* Iterate through all the batch requests and print results */ while (sstore_batch_iter_next(hdl, b_iter, (void **)&cookie, &iter, &type) == ESSTORE_OK) { printf("\nCOOKIE: %s\n", cookie); switch (type) { case SSTORE_RESULT_TYPE_ITER: print_iter(iter); break; case SSTORE_RESULT_TYPE_ERROR: print_error(); break; } } } void print_iter(sstore_iter_t iter) { switch (sstore_iter_type(iter)) { case SSTORE_ITER_TYPE_DATA: print_data_iter(iter); break; case SSTORE_ITER_TYPE_INFO: print_info_iter(iter); break; case SSTORE_ITER_TYPE_NAMESPACE: print_ns_iter(iter); break; case SSTORE_ITER_TYPE_BATCH: print_batch_iter(iter); break; default: fprintf(stderr, "Invalid iterator type\n"); return; } if (sstore_err_code(hdl) != ESSTORE_ITER_DONE) { print_error(); } } int main() { sstore_batch_t b_hdl = NULL; sstore_iter_t b_iter = NULL; int ret = -1; /* Allocate a libsstore handle */ if ((hdl = sstore_alloc()) == NULL || (b_hdl = sstore_batch_alloc()) == NULL) { fprintf(stderr, "Failed to allocate handle or batch\n"); goto end; } /* batch a data read request */ if (sstore_batch_data_read(hdl, b_hdl, (void *)"Data Read", ids, id_count, NULL, SSTORE_WALK_ID) != ESSTORE_OK) { goto end; } /* batch an info read request */ if (sstore_batch_info_read(hdl, b_hdl, (void *)"Info Read", ids, id_count, NULL) != ESSTORE_OK) { goto end; } /* batch a namespace list request */ if (sstore_batch_namespace_list(hdl, b_hdl, (void *)"Namespace List", ids, id_count, NULL) != ESSTORE_OK) { goto end; } /* Make the batch call */ if (sstore_batch_call(hdl, b_hdl, &b_iter) != ESSTORE_OK) { goto end; } /* Print the results from the batch call */ print_iter(b_iter); /* Free the batch iterator */ sstore_iter_free(b_iter); ret = 0; end: if (hdl != NULL) { print_error(); } /* Free the libsstore handle */ sstore_free(hdl); /* Free the batch handle */ sstore_batch_free(b_hdl); return (ret); } Output: COOKIE: Data Read IDENTIFIER TIMESTAMP VALUE //:class.cpu//:stat.xcalls//:part.cpu(1,2) 1424815727000000 1: 269287.0 2: 419032.0 COOKIE: Info Read IDENTIFIER TIMESTAMP VALUE //:class.cpu//:stat.xcalls//:part.cpu(1,2) 1424815728000000 $schema: //:stat copyright: Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. description: number of cross calls stability: stable id: //:class.cpu//:stat.xcalls localize: description partitions: core partitions: chip partitions: pg partitions: lgroup type: counter multiplier: 1000000 units: calls COOKIE: Namespace List IDENTIFIER START END //:class.cpu//:stat.xcalls//:part.cpu(1,2) UNKNOWN ACTIVE
See attributes(7) for descriptions of the following attributes:
|
libsstore(3LIB), sstore_alloc(3SSTORE), sstore_data_read(3SSTORE), sstore_err_action(3SSTORE), sstore_info_read(3SSTORE), sstore_namespace_list(3SSTORE), sstore_range_alloc(3SSTORE), attributes(7), ssid(7)