18
18
19
19
#define MAX_WITNESS_REQUEST_SIZE 2048
20
20
// static const int NUM_ENTRIES_PER_TABLE = 512; // Must be power of 2.
21
- #define WITNESS_NUM_ENTRIES_PER_TABLE 4096 // Must be power of 2.
22
- #define HASH_BITMASK 4095
21
+ //#define WITNESS_NUM_ENTRIES_PER_TABLE 4096 // Must be power of 2.
22
+ //#define HASH_BITMASK 4095
23
+ #define WITNESS_NUM_ENTRIES_PER_TABLE 1024 // Must be power of 2.
24
+ #define HASH_BITMASK 1023
25
+ #define WITNESS_ASSOCIATIVITY 4
23
26
24
27
/**
25
28
* Holds information to recover an RPC request in case of the master's crash
26
29
*/
27
30
struct Entry {
28
- bool occupied ; // TODO(seojin): check padding to 64-bit improves perf?
29
- int16_t requestSize ;
30
- int64_t clientId ;
31
- int64_t requestId ;
32
- char request [MAX_WITNESS_REQUEST_SIZE ];
31
+ bool occupied [WITNESS_ASSOCIATIVITY ]; // TODO(seojin): check padding to 64-bit improves perf?
32
+ int16_t requestSize [WITNESS_ASSOCIATIVITY ];
33
+ uint32_t keyHash [WITNESS_ASSOCIATIVITY ];
34
+ int64_t clientId [WITNESS_ASSOCIATIVITY ];
35
+ int64_t requestId [WITNESS_ASSOCIATIVITY ];
36
+ char request [WITNESS_ASSOCIATIVITY ][MAX_WITNESS_REQUEST_SIZE ];
33
37
};
34
38
35
39
/**
@@ -55,13 +59,14 @@ void witnessInit() {
55
59
56
60
void wrecordCommand (client * c ) {
57
61
long masterIdx , hashIndex ;
58
- long long clientId , requestId ;
62
+ long long keyHash , clientId , requestId ;
59
63
if (getLongFromObjectOrReply (c , c -> argv [1 ], & masterIdx , NULL ) != C_OK ) return ;
60
64
if (getLongFromObjectOrReply (c , c -> argv [2 ], & hashIndex , NULL ) != C_OK ) return ;
61
- if (getLongLongFromObjectOrReply (c , c -> argv [3 ], & clientId , NULL ) != C_OK ) return ;
62
- if (getLongLongFromObjectOrReply (c , c -> argv [4 ], & requestId , NULL ) != C_OK ) return ;
63
- size_t requestSize = sdslen (c -> argv [5 ]-> ptr );
64
- void * data = c -> argv [5 ]-> ptr ;
65
+ if (getLongLongFromObjectOrReply (c , c -> argv [3 ], & keyHash , NULL ) != C_OK ) return ;
66
+ if (getLongLongFromObjectOrReply (c , c -> argv [4 ], & clientId , NULL ) != C_OK ) return ;
67
+ if (getLongLongFromObjectOrReply (c , c -> argv [5 ], & requestId , NULL ) != C_OK ) return ;
68
+ size_t requestSize = sdslen (c -> argv [6 ]-> ptr );
69
+ void * data = c -> argv [6 ]-> ptr ;
65
70
66
71
struct Master * buffer = & masters [masterIdx ];
67
72
assert (requestSize <= MAX_WITNESS_REQUEST_SIZE );
@@ -73,12 +78,25 @@ void wrecordCommand(client *c) {
73
78
return ;
74
79
}
75
80
76
- if (!buffer -> table [hashIndex ].occupied ) {
77
- buffer -> table [hashIndex ].occupied = true;
78
- buffer -> table [hashIndex ].requestSize = requestSize ;
79
- buffer -> table [hashIndex ].clientId = clientId ;
80
- buffer -> table [hashIndex ].requestId = requestId ;
81
- memcpy (buffer -> table [hashIndex ].request , data , requestSize );
81
+ int slot = WITNESS_ASSOCIATIVITY ; // This means not available.
82
+ for (int i = 0 ; i < WITNESS_ASSOCIATIVITY ; ++ i ) {
83
+ if (buffer -> table [hashIndex ].occupied [i ]) {
84
+ if (buffer -> table [hashIndex ].keyHash [i ] == (uint32_t )keyHash ) {
85
+ // KeyHash collision with existing request.
86
+ slot = WITNESS_ASSOCIATIVITY ;
87
+ break ;
88
+ }
89
+ } else {
90
+ slot = i ;
91
+ }
92
+ }
93
+ if (slot < WITNESS_ASSOCIATIVITY ) {
94
+ buffer -> table [hashIndex ].occupied [slot ] = true;
95
+ buffer -> table [hashIndex ].keyHash [slot ] = (uint32_t )keyHash ;
96
+ buffer -> table [hashIndex ].requestSize [slot ] = requestSize ;
97
+ buffer -> table [hashIndex ].clientId [slot ] = clientId ;
98
+ buffer -> table [hashIndex ].requestId [slot ] = requestId ;
99
+ memcpy (buffer -> table [hashIndex ].request [slot ], data , requestSize );
82
100
addReply (c , shared .witnessAccept );
83
101
++ buffer -> occupiedCount ;
84
102
} else {
@@ -111,20 +129,23 @@ witnessGcCommand(client *c) {
111
129
if (getLongLongFromObjectOrReply (c , c -> argv [i + 1 ], & clientId , NULL ) != C_OK ) return ;
112
130
if (getLongLongFromObjectOrReply (c , c -> argv [i + 2 ], & requestId , NULL ) != C_OK ) return ;
113
131
114
- if (buffer -> table [hashIndex ].occupied &&
115
- buffer -> table [hashIndex ].clientId == clientId &&
116
- buffer -> table [hashIndex ].requestId == requestId ) {
117
- buffer -> table [hashIndex ].occupied = false;
118
- -- buffer -> occupiedCount ;
119
- // succeeded++;
120
- } else {
121
- // serverLog(LL_NOTICE,"Witness GC failed. hashIndex: %ld, occupied: %d"
122
- // " clientId: %"PRId64" (given %lld) requestId: %"PRId64" (given %lld)",
123
- // hashIndex,
124
- // buffer->table[hashIndex].occupied,
125
- // buffer->table[hashIndex].clientId, clientId,
126
- // buffer->table[hashIndex].requestId, requestId);
127
- // failed++;
132
+ for (int slot = 0 ; slot < WITNESS_ASSOCIATIVITY ; ++ slot ) {
133
+ if (buffer -> table [hashIndex ].occupied [slot ] &&
134
+ buffer -> table [hashIndex ].clientId [slot ] == clientId &&
135
+ buffer -> table [hashIndex ].requestId [slot ] == requestId ) {
136
+ buffer -> table [hashIndex ].occupied [slot ] = false;
137
+ -- buffer -> occupiedCount ;
138
+ // succeeded++;
139
+ break ;
140
+ } else {
141
+ // serverLog(LL_NOTICE,"Witness GC failed. hashIndex: %ld, occupied: %d"
142
+ // " clientId: %"PRId64" (given %lld) requestId: %"PRId64" (given %lld)",
143
+ // hashIndex,
144
+ // buffer->table[hashIndex].occupied,
145
+ // buffer->table[hashIndex].clientId, clientId,
146
+ // buffer->table[hashIndex].requestId, requestId);
147
+ // failed++;
148
+ }
128
149
}
129
150
}
130
151
addReply (c , shared .ok );
@@ -145,17 +166,21 @@ void witnessGetRecoveryDataCommand(client *c) {
145
166
int count = 0 ;
146
167
// int totalSize = 0;
147
168
for (int i = 0 ; i < WITNESS_NUM_ENTRIES_PER_TABLE ; ++ i ) {
148
- if (buffer -> table [i ].occupied ) {
149
- // totalSize += buffer->table[i].requestSize;
150
- count ++ ;
169
+ for (int slot = 0 ; slot < WITNESS_ASSOCIATIVITY ; ++ slot ) {
170
+ if (buffer -> table [i ].occupied [slot ]) {
171
+ // totalSize += buffer->table[i].requestSize;
172
+ count ++ ;
173
+ }
151
174
}
152
175
}
153
176
addReplyMultiBulkLen (c , count );
154
177
// addReplyMultiBulkLen(c, totalSize);
155
178
for (int i = 0 ; i < WITNESS_NUM_ENTRIES_PER_TABLE ; ++ i ) {
156
- if (buffer -> table [i ].occupied ) {
157
- addReplySds (c , sdsnewlen (buffer -> table [i ].request ,
158
- buffer -> table [i ].requestSize ));
179
+ for (int slot = 0 ; slot < WITNESS_ASSOCIATIVITY ; ++ slot ) {
180
+ if (buffer -> table [i ].occupied [slot ]) {
181
+ addReplySds (c , sdsnewlen (buffer -> table [i ].request [slot ],
182
+ buffer -> table [i ].requestSize [slot ]));
183
+ }
159
184
}
160
185
}
161
186
}
0 commit comments