22#include <strings.h>
33#include <errno.h>
44#include <stdlib.h>
5+ #include <string.h>
6+
7+ #define UNUSED (V ) ((void) V)
8+
9+ int shared_sds_cnt = 0 ;
10+ ValkeyModuleSharedSDS * shared_sds_arr [4 ];
11+
12+ void * shared_sds_alloc (size_t len , size_t * alloc ) {
13+ * alloc = 2 * len ;
14+ return malloc (* alloc * sizeof (char ));
15+ }
16+
17+ void shared_sds_free_cb (void * ptr , size_t size ) {
18+ UNUSED (size );
19+ UNUSED (ptr );
20+ }
21+
22+ void check_hash_get_shared_sds (ValkeyModuleCtx * ctx , ValkeyModuleString * * argv , int result ) {
23+ if (result == 0 ) return ;
24+ ValkeyModuleKey * key = ValkeyModule_OpenKey (ctx , argv [1 ], VALKEYMODULE_READ );
25+ for (int i = 0 ; i < shared_sds_cnt ; ++ i ) {
26+ ValkeyModuleSharedSDS * get_value = NULL ;
27+ ValkeyModule_HashGet (key , VALKEYMODULE_HASH_SHAREBLE_VALUES ,
28+ argv [i * 2 + 3 ], & get_value , NULL );
29+ if (get_value ) {
30+ ValkeyModule_Assert (shared_sds_arr [i ] == get_value );
31+ }
32+ }
33+ }
534
635/* If a string is ":deleted:", the special value for deleted hash fields is
736 * returned; otherwise the input string is returned. */
8- static ValkeyModuleString * value_or_delete (ValkeyModuleString * s ) {
9- if (!strcasecmp (ValkeyModule_StringPtrLen (s , NULL ), ":delete:" ))
37+ static void * value_or_delete (ValkeyModuleCtx * ctx , ValkeyModuleString * s , int flags ) {
38+ size_t str_len ;
39+ const char * str = ValkeyModule_StringPtrLen (s , & str_len );
40+ if (flags & VALKEYMODULE_HASH_SHAREBLE_VALUES ) {
41+ ValkeyModuleSharedSDS * shared_sds = ValkeyModule_CreateSharedSDS (ctx , str_len , shared_sds_alloc , shared_sds_free_cb );
42+ size_t sds_len ;
43+ char * sds_str = ValkeyModule_SharedSDSPtrLen (shared_sds , & sds_len );
44+ ValkeyModule_Assert (sds_len == str_len );
45+ memcpy (sds_str , str , str_len );
46+ shared_sds_arr [shared_sds_cnt ++ ] = shared_sds ;
47+ return shared_sds ;
48+ }
49+ shared_sds_arr [shared_sds_cnt ++ ] = NULL ;
50+ if (!strcasecmp (str , ":delete:" ))
1051 return VALKEYMODULE_HASH_DELETE ;
1152 else
1253 return s ;
@@ -22,6 +63,7 @@ int hash_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
2263 if (argc < 5 || argc % 2 == 0 || argc > 11 )
2364 return ValkeyModule_WrongArity (ctx );
2465
66+ shared_sds_cnt = 0 ;
2567 ValkeyModule_AutoMemory (ctx );
2668 ValkeyModuleKey * key = ValkeyModule_OpenKey (ctx , argv [1 ], VALKEYMODULE_WRITE );
2769
@@ -33,6 +75,7 @@ int hash_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
3375 case 'n' : flags |= VALKEYMODULE_HASH_NX ; break ;
3476 case 'x' : flags |= VALKEYMODULE_HASH_XX ; break ;
3577 case 'a' : flags |= VALKEYMODULE_HASH_COUNT_ALL ; break ;
78+ case 's' : flags |= VALKEYMODULE_HASH_SHAREBLE_VALUES ; break ;
3679 }
3780 }
3881
@@ -41,38 +84,37 @@ int hash_set(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) {
4184 errno = 0 ;
4285 if (argc == 5 ) {
4386 result = ValkeyModule_HashSet (key , flags ,
44- argv [3 ], value_or_delete (argv [4 ]),
87+ argv [3 ], value_or_delete (ctx , argv [4 ], flags ),
4588 NULL );
4689 } else if (argc == 7 ) {
4790 result = ValkeyModule_HashSet (key , flags ,
48- argv [3 ], value_or_delete (argv [4 ]),
49- argv [5 ], value_or_delete (argv [6 ]),
91+ argv [3 ], value_or_delete (ctx , argv [4 ], flags ),
92+ argv [5 ], value_or_delete (ctx , argv [6 ], flags ),
5093 NULL );
5194 } else if (argc == 9 ) {
5295 result = ValkeyModule_HashSet (key , flags ,
53- argv [3 ], value_or_delete (argv [4 ]),
54- argv [5 ], value_or_delete (argv [6 ]),
55- argv [7 ], value_or_delete (argv [8 ]),
96+ argv [3 ], value_or_delete (ctx , argv [4 ], flags ),
97+ argv [5 ], value_or_delete (ctx , argv [6 ], flags ),
98+ argv [7 ], value_or_delete (ctx , argv [8 ], flags ),
5699 NULL );
57100 } else if (argc == 11 ) {
58101 result = ValkeyModule_HashSet (key , flags ,
59- argv [3 ], value_or_delete (argv [4 ]),
60- argv [5 ], value_or_delete (argv [6 ]),
61- argv [7 ], value_or_delete (argv [8 ]),
62- argv [9 ], value_or_delete (argv [10 ]),
102+ argv [3 ], value_or_delete (ctx , argv [4 ], flags ),
103+ argv [5 ], value_or_delete (ctx , argv [6 ], flags ),
104+ argv [7 ], value_or_delete (ctx , argv [8 ], flags ),
105+ argv [9 ], value_or_delete (ctx , argv [10 ], flags ),
63106 NULL );
64107 } else {
65108 return ValkeyModule_ReplyWithError (ctx , "ERR too many fields" );
66109 }
67-
68110 /* Check errno */
69111 if (result == 0 ) {
70112 if (errno == ENOTSUP )
71113 return ValkeyModule_ReplyWithError (ctx , VALKEYMODULE_ERRORMSG_WRONGTYPE );
72114 else
73115 ValkeyModule_Assert (errno == ENOENT );
74116 }
75-
117+ check_hash_get_shared_sds ( ctx , argv , result );
76118 return ValkeyModule_ReplyWithLongLong (ctx , result );
77119}
78120
0 commit comments