| 362 | } |
| 363 | |
| 364 | void RedisReply::CopyFromDifferentArena(const RedisReply& other) { |
| 365 | _type = other._type; |
| 366 | _length = other._length; |
| 367 | switch (_type) { |
| 368 | case REDIS_REPLY_ARRAY: { |
| 369 | RedisReply* subs = (RedisReply*)_arena->allocate(sizeof(RedisReply) * _length); |
| 370 | if (subs == NULL) { |
| 371 | LOG(FATAL) << "Fail to allocate RedisReply[" << _length << "]"; |
| 372 | return; |
| 373 | } |
| 374 | for (int i = 0; i < _length; ++i) { |
| 375 | new (&subs[i]) RedisReply(_arena); |
| 376 | } |
| 377 | _data.array.last_index = other._data.array.last_index; |
| 378 | if (_data.array.last_index > 0) { |
| 379 | // incomplete state |
| 380 | for (int i = 0; i < _data.array.last_index; ++i) { |
| 381 | subs[i].CopyFromDifferentArena(other._data.array.replies[i]); |
| 382 | } |
| 383 | } else { |
| 384 | for (int i = 0; i < _length; ++i) { |
| 385 | subs[i].CopyFromDifferentArena(other._data.array.replies[i]); |
| 386 | } |
| 387 | } |
| 388 | _data.array.replies = subs; |
| 389 | } |
| 390 | break; |
| 391 | case REDIS_REPLY_INTEGER: |
| 392 | _data.integer = other._data.integer; |
| 393 | break; |
| 394 | case REDIS_REPLY_NIL: |
| 395 | break; |
| 396 | case REDIS_REPLY_STRING: |
| 397 | // fall through |
| 398 | case REDIS_REPLY_ERROR: |
| 399 | // fall through |
| 400 | case REDIS_REPLY_STATUS: |
| 401 | if (_length < (int)sizeof(_data.short_str)) { |
| 402 | memcpy(_data.short_str, other._data.short_str, _length + 1); |
| 403 | } else { |
| 404 | char* d = (char*)_arena->allocate((_length/8 + 1)*8); |
| 405 | if (d == NULL) { |
| 406 | LOG(FATAL) << "Fail to allocate string[" << _length << "]"; |
| 407 | return; |
| 408 | } |
| 409 | memcpy(d, other._data.long_str, _length + 1); |
| 410 | _data.long_str = d; |
| 411 | } |
| 412 | break; |
| 413 | } |
| 414 | } |
| 415 | |
| 416 | void RedisReply::SetArray(int size) { |
| 417 | if (_type != REDIS_REPLY_NIL) { |