@@ -40,7 +40,8 @@ local ngx_lua_ffi_shdict_set_expire
40
40
local ngx_lua_ffi_shdict_capacity
41
41
local ngx_lua_ffi_shdict_free_space
42
42
local ngx_lua_ffi_shdict_udata_to_zone
43
-
43
+ local ngx_lua_ffi_shdict_cas
44
+ local ngx_lua_ffi_shdict_cog
44
45
45
46
if subsystem == ' http' then
46
47
ffi .cdef [[
@@ -70,6 +71,20 @@ int ngx_http_lua_ffi_shdict_set_expire(void *zone,
70
71
size_t ngx_http_lua_ffi_shdict_capacity (void * zone );
71
72
72
73
void *ngx_http_lua_ffi_shdict_udata_to_zone (void * zone_udata );
74
+
75
+ int ngx_http_lua_ffi_shdict_cas (void * zone , const unsigned char * key ,
76
+ size_t key_len , int old_value_type , const unsigned char * old_str_value_buf ,
77
+ size_t old_str_value_len , double old_num_value , int old_user_flags ,
78
+ int value_type , const unsigned char * str_value_buf , size_t str_value_len ,
79
+ double num_value , int user_flags , long exptime ,int match_flags ,
80
+ int * match , char ** errmsg , int * forcible );
81
+ int
82
+ ngx_http_lua_ffi_shdict_cog (void * zone ,
83
+ const unsigned char * key , size_t key_len , int old_value_type ,
84
+ const unsigned char * old_str_value_buf , size_t old_str_value_len ,
85
+ double old_num_value , int old_user_flags , int * value_type ,
86
+ unsigned char ** str_value_buf , size_t * str_value_len , double * num_value ,
87
+ int * user_flags , int match_flags , int * match , char ** errmsg );
73
88
]]
74
89
75
90
ngx_lua_ffi_shdict_get = C .ngx_http_lua_ffi_shdict_get
@@ -81,7 +96,8 @@ void *ngx_http_lua_ffi_shdict_udata_to_zone(void *zone_udata);
81
96
ngx_lua_ffi_shdict_capacity = C .ngx_http_lua_ffi_shdict_capacity
82
97
ngx_lua_ffi_shdict_udata_to_zone =
83
98
C .ngx_http_lua_ffi_shdict_udata_to_zone
84
-
99
+ ngx_lua_ffi_shdict_cas = C .ngx_http_lua_ffi_shdict_cas
100
+ ngx_lua_ffi_shdict_cog = C .ngx_http_lua_ffi_shdict_cog
85
101
if not pcall (function ()
86
102
return C .ngx_http_lua_ffi_shdict_free_space
87
103
end )
@@ -124,6 +140,20 @@ int ngx_stream_lua_ffi_shdict_set_expire(void *zone,
124
140
size_t ngx_stream_lua_ffi_shdict_capacity (void * zone );
125
141
126
142
void *ngx_stream_lua_ffi_shdict_udata_to_zone (void * zone_udata );
143
+
144
+ int ngx_stream_lua_ffi_shdict_cas (void * zone , const unsigned char * key ,
145
+ size_t key_len , int old_value_type , const unsigned char * old_str_value_buf ,
146
+ size_t old_str_value_len , double old_num_value , int old_user_flags ,
147
+ int value_type , const unsigned char * str_value_buf , size_t str_value_len ,
148
+ double num_value , int user_flags , long exptime ,int match_flags ,
149
+ int * match , char ** errmsg , int * forcible );
150
+ int
151
+ ngx_stream_lua_ffi_shdict_cog (void * zone ,
152
+ const unsigned char * key , size_t key_len , int old_value_type ,
153
+ const unsigned char * old_str_value_buf , size_t old_str_value_len ,
154
+ double old_num_value , int old_user_flags , int * value_type ,
155
+ unsigned char ** str_value_buf , size_t * str_value_len , double * num_value ,
156
+ int * user_flags , int match_flags , int * match , char ** errmsg );
127
157
]]
128
158
129
159
ngx_lua_ffi_shdict_get = C .ngx_stream_lua_ffi_shdict_get
@@ -135,6 +165,8 @@ void *ngx_stream_lua_ffi_shdict_udata_to_zone(void *zone_udata);
135
165
ngx_lua_ffi_shdict_capacity = C .ngx_stream_lua_ffi_shdict_capacity
136
166
ngx_lua_ffi_shdict_udata_to_zone =
137
167
C .ngx_stream_lua_ffi_shdict_udata_to_zone
168
+ ngx_lua_ffi_shdict_cas = C .ngx_stream_lua_ffi_shdict_cas
169
+ ngx_lua_ffi_shdict_cog = C .ngx_stream_lua_ffi_shdict_cog
138
170
139
171
if not pcall (function ()
140
172
return C .ngx_stream_lua_ffi_shdict_free_space
@@ -164,6 +196,7 @@ local value_type = ffi_new("int[1]")
164
196
local user_flags = ffi_new (" int[1]" )
165
197
local num_value = ffi_new (" double[1]" )
166
198
local is_stale = ffi_new (" int[1]" )
199
+ local match = ffi_new (" int[1]" )
167
200
local forcible = ffi_new (" int[1]" )
168
201
local str_value_buf = ffi_new (" unsigned char *[1]" )
169
202
local errmsg = base .get_errmsg_ptr ()
@@ -291,6 +324,225 @@ local function shdict_delete(zone, key)
291
324
return shdict_set (zone , key , nil )
292
325
end
293
326
327
+ local function shdict_cas (zone , key , old_value , old_flags ,
328
+ value , flags , exptime )
329
+ zone = check_zone (zone )
330
+
331
+ if not exptime then
332
+ exptime = 0
333
+ elseif exptime < 0 then
334
+ error (' bad "exptime" argument' ,2 )
335
+ end
336
+
337
+ if key == nil then
338
+ return nil , " nil key"
339
+ end
340
+
341
+ if type (key ) ~= " string" then
342
+ key = tostring (key )
343
+ end
344
+
345
+ local key_len = # key
346
+ if key_len == 0 then
347
+ return nil , " empty key"
348
+ end
349
+ if key_len > 65535 then
350
+ return nil , " key to long"
351
+ end
352
+
353
+ if not flags then
354
+ flags = 0
355
+ end
356
+
357
+ local match_flags = 1
358
+ if not old_flags then
359
+ old_flags = 0
360
+ match_flags = 0
361
+ end
362
+
363
+ local str_val_buf
364
+ local str_val_len = 0
365
+ local num_val = 0
366
+ local valtyp = type (value )
367
+
368
+ if valtyp == " string" then
369
+ valtyp = 4 -- LUA_TSTRING
370
+ str_val_buf = value
371
+ str_val_len = # value
372
+
373
+ elseif valtyp == " number" then
374
+ valtyp = 3 -- LUA_TNUMBER
375
+ num_val = value
376
+
377
+ elseif value == nil then
378
+ valtyp = 0 -- LUA_TNIL
379
+
380
+ elseif valtyp == " boolean" then
381
+ valtyp = 1 -- LUA_TBOOLEAN
382
+ num_val = value and 1 or 0
383
+
384
+ else
385
+ return nil , " bad value type"
386
+ end
387
+
388
+ local old_str_val_buf
389
+ local old_str_val_len = 0
390
+ local old_num_val = 0
391
+ local old_valtyp = type (old_value )
392
+
393
+ if old_valtyp == " string" then
394
+ old_valtyp = 4 -- LUA_TSTRING
395
+ old_str_val_buf = old_value
396
+ old_str_val_len = # old_value
397
+
398
+ elseif old_valtyp == " number" then
399
+ old_valtyp = 3 -- LUA_TNUMBER
400
+ old_num_val = old_value
401
+
402
+ elseif old_value == nil then
403
+ old_valtyp = 0 -- LUA_TNIL
404
+
405
+ elseif old_valtyp == " boolean" then
406
+ old_valtyp = 1 -- LUA_TBOOLEAN
407
+ old_num_val = old_value and 1 or 0
408
+
409
+ else
410
+ return nil , " bad old_value type"
411
+ end
412
+ local rc = ngx_lua_ffi_shdict_cas (zone , key , key_len ,
413
+ old_valtyp , old_str_val_buf ,
414
+ old_str_val_len , old_num_val ,
415
+ old_flags ,
416
+ valtyp , str_val_buf ,
417
+ str_val_len , num_val , flags ,
418
+ exptime * 1000 ,
419
+ match_flags , match ,
420
+ errmsg , forcible )
421
+ if rc == 0 then -- NGX_OK
422
+ return true , nil , forcible [0 ] == 1
423
+ end
424
+
425
+ -- NGX_DECLINED or NGX_ERROR
426
+ if match [0 ] == 1 then
427
+ return false , false , forcible [0 ] == 1
428
+ end
429
+ if errmsg [0 ] ~= nil then
430
+ return false , ffi_str (errmsg [0 ]), forcible [0 ] == 1
431
+ end
432
+ error (" errmsg not specified" )
433
+
434
+ end
435
+ local function shdict_cog (zone , key , old_value , old_flags )
436
+ zone = check_zone (zone )
437
+
438
+ if key == nil then
439
+ return nil , " nil key"
440
+ end
441
+
442
+ if type (key ) ~= " string" then
443
+ key = tostring (key )
444
+ end
445
+
446
+ local match_flags = 1
447
+ if not old_flags then
448
+ old_flags = 0
449
+ match_flags = 0
450
+ end
451
+
452
+ local key_len = # key
453
+ if key_len == 0 then
454
+ return nil , " empty key"
455
+ end
456
+ if key_len > 65535 then
457
+ return nil , " key too long"
458
+ end
459
+
460
+ local old_str_val_buf
461
+ local old_str_val_len = 0
462
+ local old_num_val = 0
463
+ local old_valtyp = type (old_value )
464
+
465
+ if old_valtyp == " string" then
466
+ old_valtyp = 4 -- LUA_TSTRING
467
+ old_str_val_buf = old_value
468
+ old_str_val_len = # old_value
469
+
470
+ elseif old_valtyp == " number" then
471
+ old_valtyp = 3 -- LUA_TNUMBER
472
+ old_num_val = old_value
473
+
474
+ elseif old_value == nil then
475
+ old_valtyp = 0 -- LUA_TNIL
476
+
477
+ elseif old_valtyp == " boolean" then
478
+ old_valtyp = 1 -- LUA_TBOOLEAN
479
+ old_num_val = old_value and 1 or 0
480
+
481
+ else
482
+ return nil , " bad old_value type"
483
+ end
484
+
485
+ local size = get_string_buf_size ()
486
+ local buf = get_string_buf (size )
487
+ str_value_buf [0 ] = buf
488
+ local value_len = get_size_ptr ()
489
+ value_len [0 ] = size
490
+
491
+ local rc = ngx_lua_ffi_shdict_cog (zone , key , key_len ,
492
+ old_valtyp , old_str_val_buf ,
493
+ old_str_val_len ,
494
+ old_num_val , old_flags ,
495
+ value_type ,
496
+ str_value_buf , value_len ,
497
+ num_value , user_flags ,
498
+ match_flags , match , errmsg )
499
+ if rc ~= 0 then
500
+ if match [0 ] == 1 then
501
+ return nil , false
502
+ elseif errmsg [0 ] ~= nil then
503
+ return nil , ffi_str (errmsg [0 ])
504
+ end
505
+
506
+ error (" failed to get the key" )
507
+ end
508
+
509
+ local typ = value_type [0 ]
510
+
511
+ if typ == 0 then -- LUA_TNIL
512
+ return nil
513
+ end
514
+
515
+ local flags = tonumber (user_flags [0 ])
516
+
517
+ local val
518
+
519
+ if typ == 4 then -- LUA_TSTRING
520
+ if str_value_buf [0 ] ~= buf then
521
+ -- ngx.say("len: ", tonumber(value_len[0]))
522
+ buf = str_value_buf [0 ]
523
+ val = ffi_str (buf , value_len [0 ])
524
+ C .free (buf )
525
+ else
526
+ val = ffi_str (buf , value_len [0 ])
527
+ end
528
+
529
+ elseif typ == 3 then -- LUA_TNUMBER
530
+ val = tonumber (num_value [0 ])
531
+
532
+ elseif typ == 1 then -- LUA_TBOOLEAN
533
+ val = (tonumber (buf [0 ]) ~= 0 )
534
+
535
+ else
536
+ error (" unknown value type: " .. typ )
537
+ end
538
+
539
+ if flags ~= 0 then
540
+ return val , flags
541
+ end
542
+
543
+ return val
544
+ end
545
+
294
546
295
547
local function shdict_get (zone , key )
296
548
zone = check_zone (zone )
@@ -630,6 +882,8 @@ if dict then
630
882
mt .expire = shdict_expire
631
883
mt .capacity = shdict_capacity
632
884
mt .free_space = shdict_free_space
885
+ mt .cas = shdict_cas
886
+ mt .cog = shdict_cog
633
887
end
634
888
end
635
889
end
0 commit comments