Skip to content

Commit 81a35d5

Browse files
committed
poc commit
Signed-off-by: hwware <wen.hui.ware@gmail.com>
1 parent 89d4577 commit 81a35d5

File tree

7 files changed

+492
-7
lines changed

7 files changed

+492
-7
lines changed

src/server.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,61 @@ void trackInstantaneousMetric(int metric, long long current_value, long long cur
880880
server.inst_metric[metric].last_sample_value = current_value;
881881
}
882882

883+
void displayUpdate(int pre_value, int current_value) {
884+
serverLog(LL_WARNING, "This is for testing, previous item number is %d, and current item number is %d", pre_value, current_value);
885+
}
886+
887+
void displayDataTypeArray(keysizeInfo *keysize_array, int length) {
888+
serverLog(LL_WARNING, "Current array length is %d", length);
889+
for (int i = 0; i < length; i++) {
890+
serverLog(LL_WARNING, "Item %ld and value is %ld", keysize_array[i].element_size, keysize_array[i].num);
891+
}
892+
}
893+
894+
void decreaseDataTypeArrayPreviousValue(keysizeInfo *keysize_array, int low, int high, int value) {
895+
if (keysize_array[low].element_size == value) {
896+
keysize_array[low].num--;
897+
} else if (keysize_array[high].element_size == value) {
898+
keysize_array[high].num--;
899+
} else {
900+
while (low + 1 < high) {
901+
int mid = low + (high - low) / 2;
902+
if (value > keysize_array[mid].element_size) {
903+
low = mid;
904+
} else {
905+
high = mid;
906+
}
907+
}
908+
if (value == keysize_array[high].element_size) {
909+
keysize_array[high].num--;
910+
} else {
911+
keysize_array[low].num--;
912+
}
913+
}
914+
}
915+
916+
void increaseDataTypeArrayCurrentValue(keysizeInfo *keysize_array, int low, int high, int value) {
917+
if (keysize_array[low].element_size == value) {
918+
keysize_array[low].num++;
919+
} else if (keysize_array[high].element_size == value) {
920+
keysize_array[high].num++;
921+
} else {
922+
while (low + 1 < high) {
923+
int mid = low + (high - low) / 2;
924+
if (value > keysize_array[mid].element_size) {
925+
low = mid;
926+
} else {
927+
high = mid;
928+
}
929+
}
930+
if (value == keysize_array[high].element_size) {
931+
keysize_array[high].num++;
932+
} else {
933+
keysize_array[low].num++;
934+
}
935+
}
936+
}
937+
883938
/* Return the mean of all the samples. */
884939
long long getInstantaneousMetric(int metric) {
885940
int j;
@@ -2731,6 +2786,7 @@ void makeThreadKillable(void) {
27312786
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
27322787
}
27332788

2789+
#define INIT_ARRAY_SIZE 5
27342790
void initServer(void) {
27352791
int j;
27362792

@@ -2822,6 +2878,35 @@ void initServer(void) {
28222878
server.db[j].watched_keys = dictCreate(&keylistDictType);
28232879
server.db[j].id = j;
28242880
server.db[j].avg_ttl = 0;
2881+
server.db[j].lists_array_length = INIT_ARRAY_SIZE;
2882+
server.db[j].lists_number_of_elements = 0;
2883+
server.db[j].lists_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
2884+
server.db[j].sets_array_length = INIT_ARRAY_SIZE;
2885+
server.db[j].sets_number_of_elements = 0;
2886+
server.db[j].sets_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
2887+
server.db[j].hashes_array_length = INIT_ARRAY_SIZE;
2888+
server.db[j].hashes_number_of_elements = 0;
2889+
server.db[j].hashes_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
2890+
server.db[j].zsets_array_length = INIT_ARRAY_SIZE;
2891+
server.db[j].zsets_number_of_elements = 0;
2892+
server.db[j].zsets_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
2893+
server.db[j].strings_array_length = INIT_ARRAY_SIZE;
2894+
server.db[j].strings_number_of_elements = 0;
2895+
server.db[j].strings_array = zmalloc(sizeof(keysizeInfo) * INIT_ARRAY_SIZE);
2896+
int i = 1;
2897+
for (int count = 0; count < INIT_ARRAY_SIZE; count++) {
2898+
server.db[j].lists_array[count].element_size = i;
2899+
server.db[j].lists_array[count].num = 0;
2900+
server.db[j].sets_array[count].element_size = i;
2901+
server.db[j].sets_array[count].num = 0;
2902+
server.db[j].hashes_array[count].element_size = i;
2903+
server.db[j].hashes_array[count].num = 0;
2904+
server.db[j].zsets_array[count].element_size = i;
2905+
server.db[j].zsets_array[count].num = 0;
2906+
server.db[j].strings_array[count].element_size = i;
2907+
server.db[j].strings_array[count].num = 0;
2908+
i *= 2;
2909+
}
28252910
}
28262911
evictionPoolAlloc(); /* Initialize the LRU keys pool. */
28272912
/* Note that server.pubsub_channels was chosen to be a kvstore (with only one dict, which
@@ -5553,6 +5638,7 @@ dict *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, i
55535638
"errorstats",
55545639
"cluster",
55555640
"keyspace",
5641+
"keysizes",
55565642
NULL,
55575643
};
55585644
if (!defaults) defaults = default_sections;
@@ -6207,6 +6293,41 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) {
62076293
}
62086294
}
62096295

6296+
/* Key size distribution*/
6297+
if (all_sections || (dictFind(section_dict, "keysizes") != NULL)) {
6298+
if (sections++) info = sdscat(info, "\r\n");
6299+
info = sdscatprintf(info, "# Keysizes\r\n");
6300+
for (j = 0; j < server.dbnum; j++) {
6301+
if (server.db[j].lists_number_of_elements != 0) {
6302+
info = sdscatprintf(info, "db%d_distrib_strings_sizes:", j);
6303+
for (int l = 0; l < server.db[j].strings_array_length; l++) {
6304+
info = sdscatprintf(info, "%ld=%ld,", server.db[j].strings_array[l].element_size, server.db[j].strings_array[l].num);
6305+
}
6306+
info = sdscatprintf(info, "\r\n");
6307+
info = sdscatprintf(info, "db%d_distrib_lists_items:", j);
6308+
for (int l = 0; l < server.db[j].lists_array_length; l++) {
6309+
info = sdscatprintf(info, "%ld=%ld,", server.db[j].lists_array[l].element_size, server.db[j].lists_array[l].num);
6310+
}
6311+
info = sdscatprintf(info, "\r\n");
6312+
info = sdscatprintf(info, "db%d_distrib_sets_items:", j);
6313+
for (int l = 0; l < server.db[j].sets_array_length; l++) {
6314+
info = sdscatprintf(info, "%ld=%ld,", server.db[j].sets_array[l].element_size, server.db[j].sets_array[l].num);
6315+
}
6316+
info = sdscatprintf(info, "\r\n");
6317+
info = sdscatprintf(info, "db%d_distrib_hashes_items:", j);
6318+
for (int l = 0; l < server.db[j].hashes_array_length; l++) {
6319+
info = sdscatprintf(info, "%ld=%ld,", server.db[j].hashes_array[l].element_size, server.db[j].hashes_array[l].num);
6320+
}
6321+
info = sdscatprintf(info, "\r\n");
6322+
info = sdscatprintf(info, "db%d_distrib_zsets_items:", j);
6323+
for (int l = 0; l < server.db[j].zsets_array_length; l++) {
6324+
info = sdscatprintf(info, "%ld=%ld,", server.db[j].zsets_array[l].element_size, server.db[j].zsets_array[l].num);
6325+
}
6326+
info = sdscatprintf(info, "\r\n");
6327+
}
6328+
}
6329+
}
6330+
62106331
/* Get info from modules.
62116332
* Returned when the user asked for "everything", "modules", or a specific module section.
62126333
* We're not aware of the module section names here, and we rather avoid the search when we can.

src/server.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,11 @@ typedef struct replBufBlock {
818818
char buf[];
819819
} replBufBlock;
820820

821+
typedef struct keysizeInfo {
822+
long element_size;
823+
long num;
824+
} keysizeInfo;
825+
821826
/* Database representation. There are multiple databases identified
822827
* by integers from 0 (the default database) up to the max configured
823828
* database. The database number is the 'id' field in the structure. */
@@ -833,6 +838,21 @@ typedef struct serverDb {
833838
int id; /* Database ID */
834839
long long avg_ttl; /* Average TTL, just for stats */
835840
unsigned long expires_cursor; /* Cursor of the active expire cycle. */
841+
keysizeInfo *lists_array;
842+
int lists_array_length;
843+
unsigned long long lists_number_of_elements;
844+
keysizeInfo *sets_array;
845+
int sets_array_length;
846+
unsigned long long sets_number_of_elements;
847+
keysizeInfo *hashes_array;
848+
int hashes_array_length;
849+
unsigned long long hashes_number_of_elements;
850+
keysizeInfo *zsets_array;
851+
int zsets_array_length;
852+
unsigned long long zsets_number_of_elements;
853+
keysizeInfo *strings_array;
854+
int strings_array_length;
855+
unsigned long long strings_number_of_elements;
836856
} serverDb;
837857

838858
/* forward declaration for functions ctx */
@@ -3212,6 +3232,10 @@ void *activeDefragAlloc(void *ptr);
32123232
robj *activeDefragStringOb(robj *ob);
32133233
void dismissSds(sds s);
32143234
void dismissMemoryInChild(void);
3235+
void displayUpdate(int pre_value, int current_value);
3236+
void displayDataTypeArray(keysizeInfo *keysize_array, int length);
3237+
void decreaseDataTypeArrayPreviousValue(keysizeInfo *keysize_array, int low, int high, int value);
3238+
void increaseDataTypeArrayCurrentValue(keysizeInfo *keysize_array, int low, int high, int value);
32153239

32163240
#define RESTART_SERVER_NONE 0
32173241
#define RESTART_SERVER_GRACEFULLY (1 << 0) /* Do proper shutdown. */

src/t_hash.c

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -791,14 +791,65 @@ static void hashTypeRandomElement(robj *hashobj, unsigned long hashsize, listpac
791791
}
792792
}
793793

794+
void scaleHashKeySizeArray(client *c, long value) {
795+
int length = c->db->hashes_array_length;
796+
int high_bound = c->db->hashes_array[length - 1].element_size;
797+
int base = high_bound;
798+
int count = 0;
799+
while (high_bound < value) {
800+
count++;
801+
high_bound = high_bound * 2;
802+
}
803+
keysizeInfo *new_array = zmalloc(sizeof(keysizeInfo) * (count + length));
804+
for (int i = 0; i < length; i++) {
805+
new_array[i].element_size = c->db->hashes_array[i].element_size;
806+
new_array[i].num = c->db->hashes_array[i].num;
807+
}
808+
for (int i = length; i < (count + length); i++) {
809+
base *= 2;
810+
new_array[i].element_size = base;
811+
new_array[i].num = 0;
812+
}
813+
keysizeInfo *old_array = c->db->hashes_array;
814+
zfree(old_array);
815+
c->db->hashes_array = new_array;
816+
c->db->hashes_array_length = count + length;
817+
}
818+
819+
void updateHashKeySizeArray(client *c, long previous, long curr) {
820+
int low = 0;
821+
int high = c->db->hashes_array_length - 1;
822+
if (curr > c->db->hashes_array[high].element_size) {
823+
scaleHashKeySizeArray(c, curr);
824+
}
825+
826+
high = c->db->hashes_array_length - 1;
827+
if (previous != 0) {
828+
decreaseDataTypeArrayPreviousValue(c->db->hashes_array, low, high, previous);
829+
}
830+
if (curr != 0) {
831+
increaseDataTypeArrayCurrentValue(c->db->hashes_array, low, high, curr);
832+
}
833+
}
794834

795835
/*-----------------------------------------------------------------------------
796836
* Hash type commands
797837
*----------------------------------------------------------------------------*/
798838

799839
void hsetnxCommand(client *c) {
800840
robj *o;
801-
if ((o = hashTypeLookupWriteOrCreate(c, c->argv[1])) == NULL) return;
841+
long previous_element_number;
842+
long current_element_number;
843+
844+
o = lookupKeyWrite(c->db, c->argv[1]);
845+
if (checkType(c, o, OBJ_HASH)) return;
846+
if (o == NULL) {
847+
o = createHashObject();
848+
dbAdd(c->db, c->argv[1], &o);
849+
previous_element_number = 0;
850+
} else {
851+
previous_element_number = hashTypeLength(o);
852+
}
802853

803854
if (hashTypeExists(o, c->argv[2]->ptr)) {
804855
addReply(c, shared.czero);
@@ -809,23 +860,39 @@ void hsetnxCommand(client *c) {
809860
signalModifiedKey(c, c->db, c->argv[1]);
810861
notifyKeyspaceEvent(NOTIFY_HASH, "hset", c->argv[1], c->db->id);
811862
server.dirty++;
863+
current_element_number = previous_element_number + 1;
864+
/* TO DO: update INFO KEYSIZES */
865+
updateHashKeySizeArray(c, previous_element_number, current_element_number);
812866
}
813867
}
814868

815869
void hsetCommand(client *c) {
816870
int i, created = 0;
817871
robj *o;
872+
long previous_element_number;
873+
long current_element_number;
818874

819875
if ((c->argc % 2) == 1) {
820876
addReplyErrorArity(c);
821877
return;
822878
}
823879

824-
if ((o = hashTypeLookupWriteOrCreate(c, c->argv[1])) == NULL) return;
880+
o = lookupKeyWrite(c->db, c->argv[1]);
881+
if (checkType(c, o, OBJ_HASH)) return;
882+
if (o == NULL) {
883+
o = createHashObject();
884+
dbAdd(c->db, c->argv[1], &o);
885+
previous_element_number = 0;
886+
c->db->hashes_number_of_elements++;
887+
} else {
888+
previous_element_number = hashTypeLength(o);
889+
}
825890
hashTypeTryConversion(o, c->argv, 2, c->argc - 1);
826891

827892
for (i = 2; i < c->argc; i += 2) created += !hashTypeSet(o, c->argv[i]->ptr, c->argv[i + 1]->ptr, HASH_SET_COPY);
828893

894+
current_element_number = previous_element_number + created;
895+
updateHashKeySizeArray(c, previous_element_number, current_element_number);
829896
/* HMSET (deprecated) and HSET return value is different. */
830897
char *cmdname = c->argv[0]->ptr;
831898
if (cmdname[1] == 's' || cmdname[1] == 'S') {
@@ -846,9 +913,19 @@ void hincrbyCommand(client *c) {
846913
sds new;
847914
unsigned char *vstr;
848915
unsigned int vlen;
916+
// long previous_element_number;
917+
// long current_element_number;
849918

850919
if (getLongLongFromObjectOrReply(c, c->argv[3], &incr, NULL) != C_OK) return;
851-
if ((o = hashTypeLookupWriteOrCreate(c, c->argv[1])) == NULL) return;
920+
o = lookupKeyWrite(c->db, c->argv[1]);
921+
if (checkType(c, o, OBJ_HASH)) return;
922+
if (o == NULL) {
923+
o = createHashObject();
924+
dbAdd(c->db, c->argv[1], &o);
925+
// previous_element_number = 0;
926+
} else {
927+
// previous_element_number = hashTypeLength(o);
928+
}
852929
if (hashTypeGetValue(o, c->argv[2]->ptr, &vstr, &vlen, &value) == C_OK) {
853930
if (vstr) {
854931
if (string2ll((char *)vstr, vlen, &value) == 0) {
@@ -873,6 +950,9 @@ void hincrbyCommand(client *c) {
873950
signalModifiedKey(c, c->db, c->argv[1]);
874951
notifyKeyspaceEvent(NOTIFY_HASH, "hincrby", c->argv[1], c->db->id);
875952
server.dirty++;
953+
// current_element_number = hashTypeLength(o);
954+
/* TO DO: update INFO KEYSIZES */
955+
// updateHashKeySizeArray(c, previous_element_number, current_element_number);
876956
}
877957

878958
void hincrbyfloatCommand(client *c) {
@@ -882,13 +962,24 @@ void hincrbyfloatCommand(client *c) {
882962
sds new;
883963
unsigned char *vstr;
884964
unsigned int vlen;
965+
// long previous_element_number;
966+
// long current_element_number;
885967

886968
if (getLongDoubleFromObjectOrReply(c, c->argv[3], &incr, NULL) != C_OK) return;
887969
if (isnan(incr) || isinf(incr)) {
888970
addReplyError(c, "value is NaN or Infinity");
889971
return;
890972
}
891-
if ((o = hashTypeLookupWriteOrCreate(c, c->argv[1])) == NULL) return;
973+
974+
o = lookupKeyWrite(c->db, c->argv[1]);
975+
if (checkType(c, o, OBJ_HASH)) return;
976+
if (o == NULL) {
977+
o = createHashObject();
978+
dbAdd(c->db, c->argv[1], &o);
979+
// previous_element_number = 0;
980+
} else {
981+
// previous_element_number = hashTypeLength(o);
982+
}
892983
if (hashTypeGetValue(o, c->argv[2]->ptr, &vstr, &vlen, &ll) == C_OK) {
893984
if (vstr) {
894985
if (string2ld((char *)vstr, vlen, &value) == 0) {
@@ -916,6 +1007,9 @@ void hincrbyfloatCommand(client *c) {
9161007
signalModifiedKey(c, c->db, c->argv[1]);
9171008
notifyKeyspaceEvent(NOTIFY_HASH, "hincrbyfloat", c->argv[1], c->db->id);
9181009
server.dirty++;
1010+
// current_element_number = hashTypeLength(o);
1011+
/* TO DO: update INFO KEYSIZES */
1012+
// updateHashKeySizeArray(c, previous_element_number, current_element_number);
9191013

9201014
/* Always replicate HINCRBYFLOAT as an HSET command with the final value
9211015
* in order to make sure that differences in float precision or formatting
@@ -974,9 +1068,12 @@ void hmgetCommand(client *c) {
9741068
void hdelCommand(client *c) {
9751069
robj *o;
9761070
int j, deleted = 0, keyremoved = 0;
1071+
// long previous_element_number;
1072+
// long current_element_number;
9771073

9781074
if ((o = lookupKeyWriteOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, o, OBJ_HASH)) return;
9791075

1076+
// previous_element_number = hashTypeLength(o);
9801077
for (j = 2; j < c->argc; j++) {
9811078
if (hashTypeDelete(o, c->argv[j]->ptr)) {
9821079
deleted++;
@@ -991,6 +1088,9 @@ void hdelCommand(client *c) {
9911088
signalModifiedKey(c, c->db, c->argv[1]);
9921089
notifyKeyspaceEvent(NOTIFY_HASH, "hdel", c->argv[1], c->db->id);
9931090
if (keyremoved) notifyKeyspaceEvent(NOTIFY_GENERIC, "del", c->argv[1], c->db->id);
1091+
// current_element_number = previous_element_number - deleted;
1092+
/* TO DO: update INFO KEYSIZES */
1093+
// updateHashKeySizeArray(c, previous_element_number, current_element_number);
9941094
server.dirty += deleted;
9951095
}
9961096
addReplyLongLong(c, deleted);

0 commit comments

Comments
 (0)