@@ -791,14 +791,65 @@ static void hashTypeRandomElement(robj *hashobj, unsigned long hashsize, listpac
791
791
}
792
792
}
793
793
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
+ }
794
834
795
835
/*-----------------------------------------------------------------------------
796
836
* Hash type commands
797
837
*----------------------------------------------------------------------------*/
798
838
799
839
void hsetnxCommand (client * c ) {
800
840
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
+ }
802
853
803
854
if (hashTypeExists (o , c -> argv [2 ]-> ptr )) {
804
855
addReply (c , shared .czero );
@@ -809,23 +860,39 @@ void hsetnxCommand(client *c) {
809
860
signalModifiedKey (c , c -> db , c -> argv [1 ]);
810
861
notifyKeyspaceEvent (NOTIFY_HASH , "hset" , c -> argv [1 ], c -> db -> id );
811
862
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 );
812
866
}
813
867
}
814
868
815
869
void hsetCommand (client * c ) {
816
870
int i , created = 0 ;
817
871
robj * o ;
872
+ long previous_element_number ;
873
+ long current_element_number ;
818
874
819
875
if ((c -> argc % 2 ) == 1 ) {
820
876
addReplyErrorArity (c );
821
877
return ;
822
878
}
823
879
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
+ }
825
890
hashTypeTryConversion (o , c -> argv , 2 , c -> argc - 1 );
826
891
827
892
for (i = 2 ; i < c -> argc ; i += 2 ) created += !hashTypeSet (o , c -> argv [i ]-> ptr , c -> argv [i + 1 ]-> ptr , HASH_SET_COPY );
828
893
894
+ current_element_number = previous_element_number + created ;
895
+ updateHashKeySizeArray (c , previous_element_number , current_element_number );
829
896
/* HMSET (deprecated) and HSET return value is different. */
830
897
char * cmdname = c -> argv [0 ]-> ptr ;
831
898
if (cmdname [1 ] == 's' || cmdname [1 ] == 'S' ) {
@@ -846,9 +913,19 @@ void hincrbyCommand(client *c) {
846
913
sds new ;
847
914
unsigned char * vstr ;
848
915
unsigned int vlen ;
916
+ // long previous_element_number;
917
+ // long current_element_number;
849
918
850
919
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
+ }
852
929
if (hashTypeGetValue (o , c -> argv [2 ]-> ptr , & vstr , & vlen , & value ) == C_OK ) {
853
930
if (vstr ) {
854
931
if (string2ll ((char * )vstr , vlen , & value ) == 0 ) {
@@ -873,6 +950,9 @@ void hincrbyCommand(client *c) {
873
950
signalModifiedKey (c , c -> db , c -> argv [1 ]);
874
951
notifyKeyspaceEvent (NOTIFY_HASH , "hincrby" , c -> argv [1 ], c -> db -> id );
875
952
server .dirty ++ ;
953
+ // current_element_number = hashTypeLength(o);
954
+ /* TO DO: update INFO KEYSIZES */
955
+ // updateHashKeySizeArray(c, previous_element_number, current_element_number);
876
956
}
877
957
878
958
void hincrbyfloatCommand (client * c ) {
@@ -882,13 +962,24 @@ void hincrbyfloatCommand(client *c) {
882
962
sds new ;
883
963
unsigned char * vstr ;
884
964
unsigned int vlen ;
965
+ // long previous_element_number;
966
+ // long current_element_number;
885
967
886
968
if (getLongDoubleFromObjectOrReply (c , c -> argv [3 ], & incr , NULL ) != C_OK ) return ;
887
969
if (isnan (incr ) || isinf (incr )) {
888
970
addReplyError (c , "value is NaN or Infinity" );
889
971
return ;
890
972
}
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
+ }
892
983
if (hashTypeGetValue (o , c -> argv [2 ]-> ptr , & vstr , & vlen , & ll ) == C_OK ) {
893
984
if (vstr ) {
894
985
if (string2ld ((char * )vstr , vlen , & value ) == 0 ) {
@@ -916,6 +1007,9 @@ void hincrbyfloatCommand(client *c) {
916
1007
signalModifiedKey (c , c -> db , c -> argv [1 ]);
917
1008
notifyKeyspaceEvent (NOTIFY_HASH , "hincrbyfloat" , c -> argv [1 ], c -> db -> id );
918
1009
server .dirty ++ ;
1010
+ // current_element_number = hashTypeLength(o);
1011
+ /* TO DO: update INFO KEYSIZES */
1012
+ // updateHashKeySizeArray(c, previous_element_number, current_element_number);
919
1013
920
1014
/* Always replicate HINCRBYFLOAT as an HSET command with the final value
921
1015
* in order to make sure that differences in float precision or formatting
@@ -974,9 +1068,12 @@ void hmgetCommand(client *c) {
974
1068
void hdelCommand (client * c ) {
975
1069
robj * o ;
976
1070
int j , deleted = 0 , keyremoved = 0 ;
1071
+ // long previous_element_number;
1072
+ // long current_element_number;
977
1073
978
1074
if ((o = lookupKeyWriteOrReply (c , c -> argv [1 ], shared .czero )) == NULL || checkType (c , o , OBJ_HASH )) return ;
979
1075
1076
+ // previous_element_number = hashTypeLength(o);
980
1077
for (j = 2 ; j < c -> argc ; j ++ ) {
981
1078
if (hashTypeDelete (o , c -> argv [j ]-> ptr )) {
982
1079
deleted ++ ;
@@ -991,6 +1088,9 @@ void hdelCommand(client *c) {
991
1088
signalModifiedKey (c , c -> db , c -> argv [1 ]);
992
1089
notifyKeyspaceEvent (NOTIFY_HASH , "hdel" , c -> argv [1 ], c -> db -> id );
993
1090
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);
994
1094
server .dirty += deleted ;
995
1095
}
996
1096
addReplyLongLong (c , deleted );
0 commit comments