@@ -3,10 +3,12 @@ local errors = require('errors')
3
3
4
4
local BucketIDError = errors .new_class (" BucketIDError" , {capture_stack = false })
5
5
local GetReplicasetsError = errors .new_class (' GetReplicasetsError' , {capture_stack = false })
6
+ local ShardingHashMismatchError = errors .new_class (" ShardingHashMismatchError" , {capture_stack = false })
6
7
7
8
local utils = require (' crud.common.utils' )
8
9
local dev_checks = require (' crud.common.dev_checks' )
9
10
local sharding_metadata_module = require (' crud.common.sharding.sharding_metadata' )
11
+ local storage_metadata_cache = require (' crud.common.sharding.storage_metadata_cache' )
10
12
11
13
local sharding = {}
12
14
@@ -25,37 +27,49 @@ function sharding.key_get_bucket_id(space_name, key, specified_bucket_id)
25
27
dev_checks (' string' , ' ?' , ' ?number|cdata' )
26
28
27
29
if specified_bucket_id ~= nil then
28
- return specified_bucket_id
30
+ return { bucket_id = specified_bucket_id }
29
31
end
30
32
31
- local sharding_func , err = sharding_metadata_module .fetch_sharding_func_on_router (space_name )
33
+ local sharding_func_data , err = sharding_metadata_module .fetch_sharding_func_on_router (space_name )
32
34
if err ~= nil then
33
35
return nil , err
34
36
end
35
37
36
- if sharding_func ~= nil then
37
- return sharding_func (key )
38
+ if sharding_func_data .value ~= nil then
39
+ return {
40
+ bucket_id = sharding_func_data .value (key ),
41
+ sharding_func_hash = sharding_func_data .hash ,
42
+ }
38
43
end
39
44
40
- return vshard .router .bucket_id_strcrc32 (key )
45
+ return { bucket_id = vshard .router .bucket_id_strcrc32 (key ) }
41
46
end
42
47
43
48
function sharding .tuple_get_bucket_id (tuple , space , specified_bucket_id )
44
49
if specified_bucket_id ~= nil then
45
- return specified_bucket_id
50
+ return { bucket_id = specified_bucket_id }
46
51
end
47
52
48
53
local sharding_index_parts = space .index [0 ].parts
49
- local sharding_key_as_index_obj , err = sharding_metadata_module .fetch_sharding_key_on_router (space .name )
54
+ local sharding_key_data , err = sharding_metadata_module .fetch_sharding_key_on_router (space .name )
50
55
if err ~= nil then
51
56
return nil , err
52
57
end
53
- if sharding_key_as_index_obj ~= nil then
54
- sharding_index_parts = sharding_key_as_index_obj .parts
58
+ if sharding_key_data . value ~= nil then
59
+ sharding_index_parts = sharding_key_data . value .parts
55
60
end
56
61
local key = utils .extract_key (tuple , sharding_index_parts )
57
62
58
- return sharding .key_get_bucket_id (space .name , key )
63
+ local bucket_id_data , err = sharding .key_get_bucket_id (space .name , key , nil )
64
+ if err ~= nil then
65
+ return nil , err
66
+ end
67
+
68
+ return {
69
+ bucket_id = bucket_id_data .bucket_id ,
70
+ sharding_func_hash = bucket_id_data .sharding_func_hash ,
71
+ sharding_key_hash = sharding_key_data .hash
72
+ }
59
73
end
60
74
61
75
function sharding .tuple_set_and_return_bucket_id (tuple , space , specified_bucket_id )
@@ -77,16 +91,35 @@ function sharding.tuple_set_and_return_bucket_id(tuple, space, specified_bucket_
77
91
end
78
92
end
79
93
80
- local bucket_id = tuple [bucket_id_fieldno ]
81
- if bucket_id == nil then
82
- bucket_id , err = sharding .tuple_get_bucket_id (tuple , space )
94
+ local sharding_data = { bucket_id = tuple [bucket_id_fieldno ] }
95
+
96
+ if sharding_data .bucket_id == nil then
97
+ sharding_data , err = sharding .tuple_get_bucket_id (tuple , space )
83
98
if err ~= nil then
84
99
return nil , err
85
100
end
86
- tuple [bucket_id_fieldno ] = bucket_id
101
+ tuple [bucket_id_fieldno ] = sharding_data .bucket_id
102
+ end
103
+
104
+ return sharding_data
105
+ end
106
+
107
+ function sharding .check_sharding_hash (space_name , sharding_func_hash , sharding_key_hash , skip_sharding_hash_check )
108
+ if skip_sharding_hash_check == true then
109
+ return true
110
+ end
111
+
112
+ local storage_func_hash = storage_metadata_cache .get_sharding_func_hash (space_name )
113
+ local storage_key_hash = storage_metadata_cache .get_sharding_key_hash (space_name )
114
+
115
+ if storage_func_hash ~= sharding_func_hash or storage_key_hash ~= sharding_key_hash then
116
+ local err_msg = (' crud: Sharding hash mismatch for space %s. ' ..
117
+ ' Sharding data will be reloaded after receiving this error. ' ..
118
+ ' Please retry your request.' ):format (space_name )
119
+ return nil , ShardingHashMismatchError :new (err_msg )
87
120
end
88
121
89
- return bucket_id
122
+ return true
90
123
end
91
124
92
125
return sharding
0 commit comments