Skip to content

[POC] INFO KEYSIZES section added #1967

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: unstable
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
326 changes: 326 additions & 0 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,266 @@ void trackInstantaneousMetric(int metric, long long current_value, long long cur
server.inst_metric[metric].last_sample_value = current_value;
}

void displayUpdate(int pre_value, int current_value) {
serverLog(LL_WARNING, "This is for testing, previous item number is %d, and current item number is %d", pre_value, current_value);
}

void displayDataTypeArray(keysizeInfo *keysize_array, int length) {
serverLog(LL_WARNING, "Current array length is %d", length);
for (int i = 0; i < length; i++) {
serverLog(LL_WARNING, "Item %ld and value is %ld", keysize_array[i].element_size, keysize_array[i].num);
}
}

void decreaseDataTypeArrayPreviousValue(keysizeInfo *keysize_array, int low, int high, int value) {
if (keysize_array[low].element_size == value) {
keysize_array[low].num--;
} else if (keysize_array[high].element_size == value) {
keysize_array[high].num--;
} else {
while (low + 1 < high) {
int mid = low + (high - low) / 2;
if (value > keysize_array[mid].element_size) {
low = mid;
} else {
high = mid;
}
}
if (value == keysize_array[high].element_size) {
keysize_array[high].num--;
} else {
keysize_array[low].num--;
}
}
}

void increaseDataTypeArrayCurrentValue(keysizeInfo *keysize_array, int low, int high, int value) {
if (keysize_array[low].element_size == value) {
keysize_array[low].num++;
} else if (keysize_array[high].element_size == value) {
keysize_array[high].num++;
} else {
while (low + 1 < high) {
int mid = low + (high - low) / 2;
if (value > keysize_array[mid].element_size) {
low = mid;
} else {
high = mid;
}
}
if (value == keysize_array[high].element_size) {
keysize_array[high].num++;
} else {
keysize_array[low].num++;
}
}
}

void scaleHashKeySizeArray(client *c, long value) {
int length = c->db->hashes_array_length;
int high_bound = c->db->hashes_array[length - 1].element_size;
int base = high_bound;
int count = 0;
while (high_bound < value) {
count++;
high_bound = high_bound * 2;
}
keysizeInfo *new_array = zmalloc(sizeof(keysizeInfo) * (count + length));
for (int i = 0; i < length; i++) {
new_array[i].element_size = c->db->hashes_array[i].element_size;
new_array[i].num = c->db->hashes_array[i].num;
}
for (int i = length; i < (count + length); i++) {
base *= 2;
new_array[i].element_size = base;
new_array[i].num = 0;
}
keysizeInfo *old_array = c->db->hashes_array;
zfree(old_array);
c->db->hashes_array = new_array;
c->db->hashes_array_length = count + length;
}

void updateHashKeySizeArray(client *c, long previous, long curr) {
int low = 0;
int high = c->db->hashes_array_length - 1;
if (curr > c->db->hashes_array[high].element_size) {
scaleHashKeySizeArray(c, curr);
}

high = c->db->hashes_array_length - 1;
if (previous != 0) {
decreaseDataTypeArrayPreviousValue(c->db->hashes_array, low, high, previous);
}
if (curr != 0) {
increaseDataTypeArrayCurrentValue(c->db->hashes_array, low, high, curr);
}
}

void scaleListKeySizeArray(client *c, long value) {
int length = c->db->lists_array_length;
int high_bound = c->db->lists_array[length - 1].element_size;
int base = high_bound;
int count = 0;
while (high_bound < value) {
count++;
high_bound = high_bound * 2;
}
keysizeInfo *new_array = zmalloc(sizeof(keysizeInfo) * (count + length));
for (int i = 0; i < length; i++) {
new_array[i].element_size = c->db->lists_array[i].element_size;
new_array[i].num = c->db->lists_array[i].num;
}
for (int i = length; i < (count + length); i++) {
base *= 2;
new_array[i].element_size = base;
new_array[i].num = 0;
}
keysizeInfo *old_array = c->db->lists_array;
zfree(old_array);
c->db->lists_array = new_array;
c->db->lists_array_length = count + length;
}

void updateListKeySizeArray(client *c, long previous, long curr) {
int low = 0;
int high = c->db->lists_array_length - 1;
if (curr > c->db->lists_array[high].element_size) {
scaleListKeySizeArray(c, curr);
}

high = c->db->lists_array_length - 1;
if (previous != 0) {
decreaseDataTypeArrayPreviousValue(c->db->lists_array, low, high, previous);
}
if (curr != 0) {
increaseDataTypeArrayCurrentValue(c->db->lists_array, low, high, curr);
}
}

void scaleSetKeySizeArray(client *c, long value) {
int length = c->db->sets_array_length;
int high_bound = c->db->sets_array[length - 1].element_size;
int base = high_bound;
int count = 0;
while (high_bound < value) {
count++;
high_bound = high_bound * 2;
}
keysizeInfo *new_array = zmalloc(sizeof(keysizeInfo) * (count + length));
for (int i = 0; i < length; i++) {
new_array[i].element_size = c->db->sets_array[i].element_size;
new_array[i].num = c->db->sets_array[i].num;
}
for (int i = length; i < (count + length); i++) {
base *= 2;
new_array[i].element_size = base;
new_array[i].num = 0;
}
keysizeInfo *old_array = c->db->sets_array;
zfree(old_array);
c->db->sets_array = new_array;
c->db->sets_array_length = count + length;
}

void updateSetKeySizeArray(client *c, long previous, long curr) {
int low = 0;
int high = c->db->sets_array_length - 1;
if (curr > c->db->sets_array[high].element_size) {
scaleSetKeySizeArray(c, curr);
}

high = c->db->sets_array_length - 1;
if (previous != 0) {
decreaseDataTypeArrayPreviousValue(c->db->sets_array, low, high, previous);
}
if (curr != 0) {
increaseDataTypeArrayCurrentValue(c->db->sets_array, low, high, curr);
}
}

void scaleStringKeySizeArray(client *c, long value) {
int length = c->db->strings_array_length;
int high_bound = c->db->strings_array[length - 1].element_size;
int base = high_bound;
int count = 0;
while (high_bound < value) {
count++;
high_bound = high_bound * 2;
}
keysizeInfo *new_array = zmalloc(sizeof(keysizeInfo) * (count + length));
for (int i = 0; i < length; i++) {
new_array[i].element_size = c->db->strings_array[i].element_size;
new_array[i].num = c->db->strings_array[i].num;
}
for (int i = length; i < (count + length); i++) {
base *= 2;
new_array[i].element_size = base;
new_array[i].num = 0;
}
keysizeInfo *old_array = c->db->strings_array;
zfree(old_array);
c->db->strings_array = new_array;
c->db->strings_array_length = count + length;
}

void updateStringKeySizeArray(client *c, long previous, long curr) {
int low = 0;
int high = c->db->strings_array_length - 1;
if (curr > c->db->strings_array[high].element_size) {
scaleStringKeySizeArray(c, curr);
}

high = c->db->strings_array_length - 1;
if (previous != 0) {
decreaseDataTypeArrayPreviousValue(c->db->strings_array, low, high, previous);
}
if (curr != 0) {
increaseDataTypeArrayCurrentValue(c->db->strings_array, low, high, curr);
}
}

void scaleZsetKeySizeArray(client *c, long value) {
int length = c->db->zsets_array_length;
int high_bound = c->db->zsets_array[length - 1].element_size;
int base = high_bound;
int count = 0;
while (high_bound < value) {
count++;
high_bound = high_bound * 2;
}
keysizeInfo *new_array = zmalloc(sizeof(keysizeInfo) * (count + length));
for (int i = 0; i < length; i++) {
new_array[i].element_size = c->db->zsets_array[i].element_size;
new_array[i].num = c->db->zsets_array[i].num;
}
for (int i = length; i < (count + length); i++) {
base *= 2;
new_array[i].element_size = base;
new_array[i].num = 0;
}
keysizeInfo *old_array = c->db->zsets_array;
zfree(old_array);
c->db->zsets_array = new_array;
c->db->zsets_array_length = count + length;
}

void updateZsetKeySizeArray(client *c, long previous, long curr) {
int low = 0;
int high = c->db->zsets_array_length - 1;
if (curr > c->db->zsets_array[high].element_size) {
scaleZsetKeySizeArray(c, curr);
}

high = c->db->lists_array_length - 1;
if (previous != 0) {
decreaseDataTypeArrayPreviousValue(c->db->zsets_array, low, high, previous);
}
if (curr != 0) {
increaseDataTypeArrayCurrentValue(c->db->zsets_array, low, high, curr);
}
}

/* Return the mean of all the samples. */
long long getInstantaneousMetric(int metric) {
int j;
Expand Down Expand Up @@ -2740,6 +3000,7 @@ void makeThreadKillable(void) {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}

#define INIT_ARRAY_SIZE 5
void initServer(void) {
int j;

Expand Down Expand Up @@ -2834,6 +3095,35 @@ void initServer(void) {
server.db[j].watched_keys = dictCreate(&keylistDictType);
server.db[j].id = j;
server.db[j].avg_ttl = 0;
server.db[j].lists_array_length = INIT_ARRAY_SIZE;
server.db[j].lists_number_of_elements = 0;
server.db[j].lists_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
server.db[j].sets_array_length = INIT_ARRAY_SIZE;
server.db[j].sets_number_of_elements = 0;
server.db[j].sets_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
server.db[j].hashes_array_length = INIT_ARRAY_SIZE;
server.db[j].hashes_number_of_elements = 0;
server.db[j].hashes_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
server.db[j].zsets_array_length = INIT_ARRAY_SIZE;
server.db[j].zsets_number_of_elements = 0;
server.db[j].zsets_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
server.db[j].strings_array_length = INIT_ARRAY_SIZE;
server.db[j].strings_number_of_elements = 0;
server.db[j].strings_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
int i = 1;
for (int count = 0; count < INIT_ARRAY_SIZE; count++) {
server.db[j].lists_array[count].element_size = i;
server.db[j].lists_array[count].num = 0;
server.db[j].sets_array[count].element_size = i;
server.db[j].sets_array[count].num = 0;
server.db[j].hashes_array[count].element_size = i;
server.db[j].hashes_array[count].num = 0;
server.db[j].zsets_array[count].element_size = i;
server.db[j].zsets_array[count].num = 0;
server.db[j].strings_array[count].element_size = i;
server.db[j].strings_array[count].num = 0;
i *= 2;
}
}
evictionPoolAlloc(); /* Initialize the LRU keys pool. */
/* Note that server.pubsub_channels was chosen to be a kvstore (with only one dict, which
Expand Down Expand Up @@ -5568,6 +5858,7 @@ dict *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, i
"errorstats",
"cluster",
"keyspace",
"keysizes",
NULL,
};
if (!defaults) defaults = default_sections;
Expand Down Expand Up @@ -6222,6 +6513,41 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) {
}
}

/* Key size distribution*/
if (all_sections || (dictFind(section_dict, "keysizes") != NULL)) {
if (sections++) info = sdscat(info, "\r\n");
info = sdscatprintf(info, "# Keysizes\r\n");
for (j = 0; j < server.dbnum; j++) {
if (server.db[j].lists_number_of_elements != 0) {
info = sdscatprintf(info, "db%d_distrib_strings_sizes:", j);
for (int l = 0; l < server.db[j].strings_array_length; l++) {
info = sdscatprintf(info, "%ld=%ld,", server.db[j].strings_array[l].element_size, server.db[j].strings_array[l].num);
}
info = sdscatprintf(info, "\r\n");
info = sdscatprintf(info, "db%d_distrib_lists_items:", j);
for (int l = 0; l < server.db[j].lists_array_length; l++) {
info = sdscatprintf(info, "%ld=%ld,", server.db[j].lists_array[l].element_size, server.db[j].lists_array[l].num);
}
info = sdscatprintf(info, "\r\n");
info = sdscatprintf(info, "db%d_distrib_sets_items:", j);
for (int l = 0; l < server.db[j].sets_array_length; l++) {
info = sdscatprintf(info, "%ld=%ld,", server.db[j].sets_array[l].element_size, server.db[j].sets_array[l].num);
}
info = sdscatprintf(info, "\r\n");
info = sdscatprintf(info, "db%d_distrib_hashes_items:", j);
for (int l = 0; l < server.db[j].hashes_array_length; l++) {
info = sdscatprintf(info, "%ld=%ld,", server.db[j].hashes_array[l].element_size, server.db[j].hashes_array[l].num);
}
info = sdscatprintf(info, "\r\n");
info = sdscatprintf(info, "db%d_distrib_zsets_items:", j);
for (int l = 0; l < server.db[j].zsets_array_length; l++) {
info = sdscatprintf(info, "%ld=%ld,", server.db[j].zsets_array[l].element_size, server.db[j].zsets_array[l].num);
}
info = sdscatprintf(info, "\r\n");
}
}
}

/* Get info from modules.
* Returned when the user asked for "everything", "modules", or a specific module section.
* We're not aware of the module section names here, and we rather avoid the search when we can.
Expand Down
Loading
Loading