Changeset df427f
- Timestamp:
- 01/08/08 16:56:51 (4 years ago)
- Branches:
- master, ketama-compat
- Children:
- ff08e9
- Parents:
- 12f8a2
- git-author:
- Tomash Brechko <tomash.brechko@…> (01/08/08 16:52:49)
- git-committer:
- Tomash Brechko <tomash.brechko@…> (01/08/08 16:56:51)
- Files:
-
- 5 edited
-
Fast.xs (modified) (7 diffs)
-
lib/Cache/Memcached/Fast.pm (modified) (2 diffs)
-
src/array.h (modified) (1 diff)
-
src/client.c (modified) (11 diffs)
-
src/client.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
Fast.xs
r12f8a2 rdf427f 260 260 struct xs_mkey_result 261 261 { 262 AV * key_val;262 AV *vals; 263 263 AV *flags; 264 I32 ax;265 int stack_offset;266 264 }; 267 268 269 static270 char *271 get_key(void *arg, int key_index, size_t *key_len)272 {273 I32 ax;274 struct xs_mkey_result *mkey_res;275 SV *key_sv;276 char *res;277 STRLEN len;278 279 mkey_res = (struct xs_mkey_result *) arg;280 281 ax = mkey_res->ax;282 key_sv = ST(mkey_res->stack_offset + key_index);283 res = SvPV(key_sv, len);284 *key_len = len;285 286 return res;287 }288 265 289 266 … … 293 270 int use_cas, cas_type cas) 294 271 { 295 I32 ax;296 272 struct xs_mkey_result *mkey_res; 297 SV * key_sv, *value_sv;273 SV *value_sv; 298 274 299 275 value_sv = (SV *) opaque; … … 301 277 mkey_res = (struct xs_mkey_result *) arg; 302 278 303 ax = mkey_res->ax;304 key_sv = ST(mkey_res->stack_offset + key_index);305 av_push(mkey_res->key_val, SvREFCNT_inc(key_sv));306 279 if (! use_cas) 307 280 { 308 av_ push(mkey_res->key_val, newRV_noinc(value_sv));281 av_store(mkey_res->vals, key_index, newRV_noinc(value_sv)); 309 282 } 310 283 else … … 314 287 av_push(cas_val, newSVuv(cas)); 315 288 av_push(cas_val, newRV_noinc(value_sv)); 316 av_ push(mkey_res->key_val, newRV_noinc((SV *) cas_val));317 } 318 319 av_ push(mkey_res->flags, newSVuv(flags));289 av_store(mkey_res->vals, key_index, newRV_noinc((SV *) cas_val)); 290 } 291 292 av_store(mkey_res->flags, key_index, newSVuv(flags)); 320 293 } 321 294 … … 480 453 struct value_object object = 481 454 { alloc_value, mkey_store, free_value, &mkey_res }; 482 int key_count;455 int i, key_count; 483 456 PPCODE: 484 457 key_count = items - 1; 485 mkey_res.ax = ax; 486 mkey_res.stack_offset = 1; 487 mkey_res.key_val = newAV(); 458 mkey_res.vals = newAV(); 488 459 mkey_res.flags = newAV(); 489 av_extend(mkey_res. key_val, key_count * 2);460 av_extend(mkey_res.vals, key_count); 490 461 av_extend(mkey_res.flags, key_count); 491 if (key_count > 0) 492 client_mget(memd, ix, key_count, get_key, &object); 462 client_reset(memd); 463 for (i = 0; i < key_count; ++i) 464 { 465 const char *key; 466 STRLEN key_len; 467 468 key = SvPV(ST(i + 1), key_len); 469 client_get(memd, ix, i, key, key_len, &object); 470 } 471 client_execute(memd); 493 472 EXTEND(SP, 2); 494 PUSHs(sv_2mortal(newRV_noinc((SV *) mkey_res. key_val)));473 PUSHs(sv_2mortal(newRV_noinc((SV *) mkey_res.vals))); 495 474 PUSHs(sv_2mortal(newRV_noinc((SV *) mkey_res.flags))); 496 475 XSRETURN(2); … … 598 577 599 578 HV * 600 _rvav2rvhv(array) 601 AV * array 579 _rvav2rvhv(keys, vals) 580 AV * keys 581 AV * vals 602 582 PROTOTYPE: $ 603 583 PREINIT: … … 607 587 /* Why sv_2mortal() is needed is explained in perlxs. */ 608 588 sv_2mortal((SV *) RETVAL); 609 max_index = av_len(array); 610 if ((max_index & 1) != 1) 611 croak("Even sized list expected"); 612 i = 0; 613 while (i <= max_index) 589 max_index = av_len(vals); 590 for (i = 0; i <= max_index; ++i) 614 591 { 615 592 SV **pkey, **pval; 616 593 HE *he; 617 594 618 pkey = av_fetch(array, i++, 0); 619 pval = av_fetch(array, i++, 0); 620 if (! (pkey && pval)) 621 croak("Undefined values in the list"); 595 pval = av_fetch(vals, i, 0); 596 if (! (pval && SvOK(*pval))) 597 continue; 598 599 pkey = av_fetch(keys, i, 0); 600 if (! pkey) 601 croak("Undefined key in the list"); 602 622 603 he = hv_store_ent(RETVAL, *pkey, SvREFCNT_inc(*pval), 0); 623 604 if (! he) -
lib/Cache/Memcached/Fast.pm
r3a7104 rdf427f 681 681 my Cache::Memcached::Fast $self = shift; 682 682 683 my ($key_val, $flags) = $self->{_xs}->mget(@_); 684 685 my $vi = 1; 686 foreach my $f (@$flags) { 687 if (_unpack_value($self, $$key_val[$vi], $f)) { 688 $$key_val[$vi] = ${$$key_val[$vi]}; 689 $vi += 2; 683 my ($vals, $flags) = $self->{_xs}->mget(@_); 684 685 my $keys = \@_; 686 687 my $i = -1; 688 foreach my $v (@$vals) { 689 ++$i; 690 691 next unless defined $v; 692 693 if (_unpack_value($self, $v, $flags->[$i])) { 694 $v = $$v; 690 695 } else { 691 splice(@$key_val, $vi - 1, 2);696 undef $v; 692 697 } 693 698 } 694 699 695 return Cache::Memcached::Fast::_xs::_rvav2rvhv($key _val);700 return Cache::Memcached::Fast::_xs::_rvav2rvhv($keys, $vals); 696 701 } 697 702 … … 749 754 my Cache::Memcached::Fast $self = shift; 750 755 751 my ($key_val, $flags) = $self->{_xs}->mgets(@_); 752 753 my $vi = 1; 754 foreach my $f (@$flags) { 755 if (_unpack_value($self, ${$$key_val[$vi]}[1], $f)) { 756 ${$$key_val[$vi]}[1] = ${${$$key_val[$vi]}[1]}; 757 $vi += 2; 756 my ($vals, $flags) = $self->{_xs}->mgets(@_); 757 758 my $keys = \@_; 759 760 my $i = -1; 761 foreach my $v (@$vals) { 762 ++$i; 763 764 next unless defined $v; 765 766 if (_unpack_value($self, $v->[1], $flags->[$i])) { 767 $v->[1] = ${$v->[1]}; 758 768 } else { 759 splice(@$key_val, $vi - 1, 2);769 undef $v; 760 770 } 761 771 } 762 772 763 return Cache::Memcached::Fast::_xs::_rvav2rvhv($key _val);773 return Cache::Memcached::Fast::_xs::_rvav2rvhv($keys, $vals); 764 774 } 765 775 -
src/array.h
rd61894 rdf427f 58 58 #define array_push(array) ++(array).elems 59 59 60 #define array_pop(array) --(array).elems 61 60 62 #define array_append(array, add) (array).elems += add 61 63 -
src/client.c
r12f8a2 rdf427f 318 318 array_clear(state->iov_buf); 319 319 320 if (! parse_reply && ! state->noreply)321 ++state->nowait_count;322 323 320 state->write_offset = 0; 324 321 state->index_head = state->index_tail = -1; … … 1620 1617 } 1621 1618 1619 if (parse_reply) 1620 ++state->command_count; 1621 else if (! *noreply) 1622 ++state->nowait_count; 1623 1622 1624 return state; 1623 1625 } … … 1648 1650 1649 1651 1652 inline 1650 1653 void 1651 1654 client_reset(struct client *c) … … 1717 1720 iov_push(state, (void *) value, value_size); 1718 1721 iov_push(state, STR_WITH_LEN("\r\n")); 1719 1720 ++state->command_count;1721 1722 1722 1723 return client_execute(c); … … 1760 1761 iov_push(state, STR_WITH_LEN("\r\n")); 1761 1762 1762 ++state->command_count;1763 1764 1763 return client_execute(c); 1765 1764 } … … 1779 1778 return MEMCACHED_FAILURE; 1780 1779 1781 if (array_empty(state->iov_buf)) 1782 value_state_reset(&state->u.value, o, (cmd == CMD_GETS)); 1783 1784 switch (cmd) 1785 { 1786 case CMD_GET: 1787 iov_push(state, STR_WITH_LEN("get")); 1788 break; 1789 1790 case CMD_GETS: 1791 iov_push(state, STR_WITH_LEN("gets")); 1792 break; 1793 } 1780 if (! array_empty(state->iov_buf)) 1781 { 1782 /* Pop off trailing \r\n because we are about to add another key. */ 1783 array_pop(state->iov_buf); 1784 ++state->key_count; 1785 --state->command_count; 1786 } 1787 else 1788 { 1789 value_state_reset(&state->u.value, o, (cmd == CMD_GETS)); 1790 1791 switch (cmd) 1792 { 1793 case CMD_GET: 1794 iov_push(state, STR_WITH_LEN("get")); 1795 break; 1796 1797 case CMD_GETS: 1798 iov_push(state, STR_WITH_LEN("gets")); 1799 break; 1800 } 1801 } 1802 1794 1803 iov_push(state, c->prefix, c->prefix_len); 1795 1804 iov_push(state, (void *) key, key_len); 1796 1805 iov_push(state, STR_WITH_LEN("\r\n")); 1797 1806 1798 ++state->command_count;1799 1800 1807 return MEMCACHED_SUCCESS; 1801 }1802 1803 1804 int1805 client_mget(struct client *c, enum get_cmd_e cmd,1806 int key_count, get_key_func get_key, struct value_object *o)1807 {1808 static const size_t request_size = 2 + 2;1809 1810 struct server *s;1811 struct command_state *state;1812 int i;1813 1814 client_reset(c);1815 1816 for (i = 0; i < key_count; ++i)1817 {1818 char *key;1819 size_t key_len;1820 1821 key = get_key(o->arg, i, &key_len);1822 1823 state = get_state(c, i, key, key_len, request_size, 0,1824 parse_get_reply, NULL);1825 if (! state)1826 continue;1827 1828 if (array_empty(state->iov_buf))1829 {1830 value_state_reset(&state->u.value, o, (cmd == CMD_GETS));1831 1832 switch (cmd)1833 {1834 case CMD_GET:1835 iov_push(state, STR_WITH_LEN("get"));1836 break;1837 1838 case CMD_GETS:1839 iov_push(state, STR_WITH_LEN("gets"));1840 break;1841 }1842 }1843 1844 iov_push(state, c->prefix, c->prefix_len);1845 iov_push(state, (void *) key, key_len);1846 }1847 1848 for (array_each(c->servers, struct server, s))1849 {1850 state = &s->cmd_state;1851 1852 if (is_active(state))1853 {1854 state->key_count = (array_size(state->iov_buf) - 1) / 2;1855 iov_push(state, STR_WITH_LEN("\r\n"));1856 1857 ++state->command_count;1858 }1859 }1860 1861 return client_execute(c);1862 1808 } 1863 1809 … … 1902 1848 array_append(c->str_buf, str_size); 1903 1849 } 1904 1905 ++state->command_count;1906 1850 1907 1851 return client_execute(c); … … 1938 1882 } 1939 1883 1940 ++state->command_count;1941 1942 1884 return client_execute(c); 1943 1885 } … … 1985 1927 array_append(c->str_buf, str_size); 1986 1928 } 1987 1988 ++state->command_count;1989 1929 } 1990 1930 … … 2022 1962 --state->nowait_count; 2023 1963 command_state_reset(state, 0, parse_nowait_reply); 2024 2025 ++state->command_count;2026 1964 } 2027 1965 … … 2057 1995 2058 1996 iov_push(state, STR_WITH_LEN("version\r\n")); 2059 2060 ++state->command_count;2061 1997 } 2062 1998 -
src/client.h
r12f8a2 rdf427f 156 156 extern 157 157 int 158 client_mget(struct client *c, enum get_cmd_e cmd,159 int key_count, get_key_func get_key, struct value_object *o);160 161 extern162 int163 158 client_arith(struct client *c, enum arith_cmd_e cmd, 164 159 const char *key, size_t key_len,
Note: See TracChangeset
for help on using the changeset viewer.
