Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

initial commit

  • Loading branch information...
commit c62b949db8a6aff2def234d47bc541a4000f1192 0 parents
Matt Ingenthron ingenthr authored
385 LICENSE.txt
... ... @@ -0,0 +1,385 @@
  1 +Unless otherwise noted, all files in this distribution are released
  2 +under the Common Development and Distribution License (CDDL),
  3 +Version 1.0 only. Exceptions are noted within the associated
  4 +source files.
  5 +
  6 +--------------------------------------------------------------------
  7 +
  8 +
  9 +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0
  10 +
  11 +1. Definitions.
  12 +
  13 + 1.1. "Contributor" means each individual or entity that creates
  14 + or contributes to the creation of Modifications.
  15 +
  16 + 1.2. "Contributor Version" means the combination of the Original
  17 + Software, prior Modifications used by a Contributor (if any),
  18 + and the Modifications made by that particular Contributor.
  19 +
  20 + 1.3. "Covered Software" means (a) the Original Software, or (b)
  21 + Modifications, or (c) the combination of files containing
  22 + Original Software with files containing Modifications, in
  23 + each case including portions thereof.
  24 +
  25 + 1.4. "Executable" means the Covered Software in any form other
  26 + than Source Code.
  27 +
  28 + 1.5. "Initial Developer" means the individual or entity that first
  29 + makes Original Software available under this License.
  30 +
  31 + 1.6. "Larger Work" means a work which combines Covered Software or
  32 + portions thereof with code not governed by the terms of this
  33 + License.
  34 +
  35 + 1.7. "License" means this document.
  36 +
  37 + 1.8. "Licensable" means having the right to grant, to the maximum
  38 + extent possible, whether at the time of the initial grant or
  39 + subsequently acquired, any and all of the rights conveyed
  40 + herein.
  41 +
  42 + 1.9. "Modifications" means the Source Code and Executable form of
  43 + any of the following:
  44 +
  45 + A. Any file that results from an addition to, deletion from or
  46 + modification of the contents of a file containing Original
  47 + Software or previous Modifications;
  48 +
  49 + B. Any new file that contains any part of the Original
  50 + Software or previous Modifications; or
  51 +
  52 + C. Any new file that is contributed or otherwise made
  53 + available under the terms of this License.
  54 +
  55 + 1.10. "Original Software" means the Source Code and Executable
  56 + form of computer software code that is originally released
  57 + under this License.
  58 +
  59 + 1.11. "Patent Claims" means any patent claim(s), now owned or
  60 + hereafter acquired, including without limitation, method,
  61 + process, and apparatus claims, in any patent Licensable by
  62 + grantor.
  63 +
  64 + 1.12. "Source Code" means (a) the common form of computer software
  65 + code in which modifications are made and (b) associated
  66 + documentation included in or with such code.
  67 +
  68 + 1.13. "You" (or "Your") means an individual or a legal entity
  69 + exercising rights under, and complying with all of the terms
  70 + of, this License. For legal entities, "You" includes any
  71 + entity which controls, is controlled by, or is under common
  72 + control with You. For purposes of this definition,
  73 + "control" means (a) the power, direct or indirect, to cause
  74 + the direction or management of such entity, whether by
  75 + contract or otherwise, or (b) ownership of more than fifty
  76 + percent (50%) of the outstanding shares or beneficial
  77 + ownership of such entity.
  78 +
  79 +2. License Grants.
  80 +
  81 + 2.1. The Initial Developer Grant.
  82 +
  83 + Conditioned upon Your compliance with Section 3.1 below and
  84 + subject to third party intellectual property claims, the Initial
  85 + Developer hereby grants You a world-wide, royalty-free,
  86 + non-exclusive license:
  87 +
  88 + (a) under intellectual property rights (other than patent or
  89 + trademark) Licensable by Initial Developer, to use,
  90 + reproduce, modify, display, perform, sublicense and
  91 + distribute the Original Software (or portions thereof),
  92 + with or without Modifications, and/or as part of a Larger
  93 + Work; and
  94 +
  95 + (b) under Patent Claims infringed by the making, using or
  96 + selling of Original Software, to make, have made, use,
  97 + practice, sell, and offer for sale, and/or otherwise
  98 + dispose of the Original Software (or portions thereof).
  99 +
  100 + (c) The licenses granted in Sections 2.1(a) and (b) are
  101 + effective on the date Initial Developer first distributes
  102 + or otherwise makes the Original Software available to a
  103 + third party under the terms of this License.
  104 +
  105 + (d) Notwithstanding Section 2.1(b) above, no patent license is
  106 + granted: (1) for code that You delete from the Original
  107 + Software, or (2) for infringements caused by: (i) the
  108 + modification of the Original Software, or (ii) the
  109 + combination of the Original Software with other software
  110 + or devices.
  111 +
  112 + 2.2. Contributor Grant.
  113 +
  114 + Conditioned upon Your compliance with Section 3.1 below and
  115 + subject to third party intellectual property claims, each
  116 + Contributor hereby grants You a world-wide, royalty-free,
  117 + non-exclusive license:
  118 +
  119 + (a) under intellectual property rights (other than patent or
  120 + trademark) Licensable by Contributor to use, reproduce,
  121 + modify, display, perform, sublicense and distribute the
  122 + Modifications created by such Contributor (or portions
  123 + thereof), either on an unmodified basis, with other
  124 + Modifications, as Covered Software and/or as part of a
  125 + Larger Work; and
  126 +
  127 + (b) under Patent Claims infringed by the making, using, or
  128 + selling of Modifications made by that Contributor either
  129 + alone and/or in combination with its Contributor Version
  130 + (or portions of such combination), to make, use, sell,
  131 + offer for sale, have made, and/or otherwise dispose of:
  132 + (1) Modifications made by that Contributor (or portions
  133 + thereof); and (2) the combination of Modifications made by
  134 + that Contributor with its Contributor Version (or portions
  135 + of such combination).
  136 +
  137 + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are
  138 + effective on the date Contributor first distributes or
  139 + otherwise makes the Modifications available to a third
  140 + party.
  141 +
  142 + (d) Notwithstanding Section 2.2(b) above, no patent license is
  143 + granted: (1) for any code that Contributor has deleted
  144 + from the Contributor Version; (2) for infringements caused
  145 + by: (i) third party modifications of Contributor Version,
  146 + or (ii) the combination of Modifications made by that
  147 + Contributor with other software (except as part of the
  148 + Contributor Version) or other devices; or (3) under Patent
  149 + Claims infringed by Covered Software in the absence of
  150 + Modifications made by that Contributor.
  151 +
  152 +3. Distribution Obligations.
  153 +
  154 + 3.1. Availability of Source Code.
  155 +
  156 + Any Covered Software that You distribute or otherwise make
  157 + available in Executable form must also be made available in Source
  158 + Code form and that Source Code form must be distributed only under
  159 + the terms of this License. You must include a copy of this
  160 + License with every copy of the Source Code form of the Covered
  161 + Software You distribute or otherwise make available. You must
  162 + inform recipients of any such Covered Software in Executable form
  163 + as to how they can obtain such Covered Software in Source Code
  164 + form in a reasonable manner on or through a medium customarily
  165 + used for software exchange.
  166 +
  167 + 3.2. Modifications.
  168 +
  169 + The Modifications that You create or to which You contribute are
  170 + governed by the terms of this License. You represent that You
  171 + believe Your Modifications are Your original creation(s) and/or
  172 + You have sufficient rights to grant the rights conveyed by this
  173 + License.
  174 +
  175 + 3.3. Required Notices.
  176 +
  177 + You must include a notice in each of Your Modifications that
  178 + identifies You as the Contributor of the Modification. You may
  179 + not remove or alter any copyright, patent or trademark notices
  180 + contained within the Covered Software, or any notices of licensing
  181 + or any descriptive text giving attribution to any Contributor or
  182 + the Initial Developer.
  183 +
  184 + 3.4. Application of Additional Terms.
  185 +
  186 + You may not offer or impose any terms on any Covered Software in
  187 + Source Code form that alters or restricts the applicable version
  188 + of this License or the recipients' rights hereunder. You may
  189 + choose to offer, and to charge a fee for, warranty, support,
  190 + indemnity or liability obligations to one or more recipients of
  191 + Covered Software. However, you may do so only on Your own behalf,
  192 + and not on behalf of the Initial Developer or any Contributor.
  193 + You must make it absolutely clear that any such warranty, support,
  194 + indemnity or liability obligation is offered by You alone, and You
  195 + hereby agree to indemnify the Initial Developer and every
  196 + Contributor for any liability incurred by the Initial Developer or
  197 + such Contributor as a result of warranty, support, indemnity or
  198 + liability terms You offer.
  199 +
  200 + 3.5. Distribution of Executable Versions.
  201 +
  202 + You may distribute the Executable form of the Covered Software
  203 + under the terms of this License or under the terms of a license of
  204 + Your choice, which may contain terms different from this License,
  205 + provided that You are in compliance with the terms of this License
  206 + and that the license for the Executable form does not attempt to
  207 + limit or alter the recipient's rights in the Source Code form from
  208 + the rights set forth in this License. If You distribute the
  209 + Covered Software in Executable form under a different license, You
  210 + must make it absolutely clear that any terms which differ from
  211 + this License are offered by You alone, not by the Initial
  212 + Developer or Contributor. You hereby agree to indemnify the
  213 + Initial Developer and every Contributor for any liability incurred
  214 + by the Initial Developer or such Contributor as a result of any
  215 + such terms You offer.
  216 +
  217 + 3.6. Larger Works.
  218 +
  219 + You may create a Larger Work by combining Covered Software with
  220 + other code not governed by the terms of this License and
  221 + distribute the Larger Work as a single product. In such a case,
  222 + You must make sure the requirements of this License are fulfilled
  223 + for the Covered Software.
  224 +
  225 +4. Versions of the License.
  226 +
  227 + 4.1. New Versions.
  228 +
  229 + Sun Microsystems, Inc. is the initial license steward and may
  230 + publish revised and/or new versions of this License from time to
  231 + time. Each version will be given a distinguishing version number.
  232 + Except as provided in Section 4.3, no one other than the license
  233 + steward has the right to modify this License.
  234 +
  235 + 4.2. Effect of New Versions.
  236 +
  237 + You may always continue to use, distribute or otherwise make the
  238 + Covered Software available under the terms of the version of the
  239 + License under which You originally received the Covered Software.
  240 + If the Initial Developer includes a notice in the Original
  241 + Software prohibiting it from being distributed or otherwise made
  242 + available under any subsequent version of the License, You must
  243 + distribute and make the Covered Software available under the terms
  244 + of the version of the License under which You originally received
  245 + the Covered Software. Otherwise, You may also choose to use,
  246 + distribute or otherwise make the Covered Software available under
  247 + the terms of any subsequent version of the License published by
  248 + the license steward.
  249 +
  250 + 4.3. Modified Versions.
  251 +
  252 + When You are an Initial Developer and You want to create a new
  253 + license for Your Original Software, You may create and use a
  254 + modified version of this License if You: (a) rename the license
  255 + and remove any references to the name of the license steward
  256 + (except to note that the license differs from this License); and
  257 + (b) otherwise make it clear that the license contains terms which
  258 + differ from this License.
  259 +
  260 +5. DISCLAIMER OF WARRANTY.
  261 +
  262 + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS"
  263 + BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
  264 + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED
  265 + SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
  266 + PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
  267 + PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY
  268 + COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
  269 + INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
  270 + NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
  271 + WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
  272 + ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
  273 + DISCLAIMER.
  274 +
  275 +6. TERMINATION.
  276 +
  277 + 6.1. This License and the rights granted hereunder will terminate
  278 + automatically if You fail to comply with terms herein and fail to
  279 + cure such breach within 30 days of becoming aware of the breach.
  280 + Provisions which, by their nature, must remain in effect beyond
  281 + the termination of this License shall survive.
  282 +
  283 + 6.2. If You assert a patent infringement claim (excluding
  284 + declaratory judgment actions) against Initial Developer or a
  285 + Contributor (the Initial Developer or Contributor against whom You
  286 + assert such claim is referred to as "Participant") alleging that
  287 + the Participant Software (meaning the Contributor Version where
  288 + the Participant is a Contributor or the Original Software where
  289 + the Participant is the Initial Developer) directly or indirectly
  290 + infringes any patent, then any and all rights granted directly or
  291 + indirectly to You by such Participant, the Initial Developer (if
  292 + the Initial Developer is not the Participant) and all Contributors
  293 + under Sections 2.1 and/or 2.2 of this License shall, upon 60 days
  294 + notice from Participant terminate prospectively and automatically
  295 + at the expiration of such 60 day notice period, unless if within
  296 + such 60 day period You withdraw Your claim with respect to the
  297 + Participant Software against such Participant either unilaterally
  298 + or pursuant to a written agreement with Participant.
  299 +
  300 + 6.3. In the event of termination under Sections 6.1 or 6.2 above,
  301 + all end user licenses that have been validly granted by You or any
  302 + distributor hereunder prior to termination (excluding licenses
  303 + granted to You by any distributor) shall survive termination.
  304 +
  305 +7. LIMITATION OF LIABILITY.
  306 +
  307 + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
  308 + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
  309 + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF
  310 + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
  311 + LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
  312 + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
  313 + LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK
  314 + STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
  315 + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
  316 + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
  317 + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
  318 + INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
  319 + APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
  320 + NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
  321 + CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
  322 + APPLY TO YOU.
  323 +
  324 +8. U.S. GOVERNMENT END USERS.
  325 +
  326 + The Covered Software is a "commercial item," as that term is
  327 + defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial
  328 + computer software" (as that term is defined at 48
  329 + C.F.R. 252.227-7014(a)(1)) and "commercial computer software
  330 + documentation" as such terms are used in 48 C.F.R. 12.212
  331 + (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
  332 + C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
  333 + U.S. Government End Users acquire Covered Software with only those
  334 + rights set forth herein. This U.S. Government Rights clause is in
  335 + lieu of, and supersedes, any other FAR, DFAR, or other clause or
  336 + provision that addresses Government rights in computer software
  337 + under this License.
  338 +
  339 +9. MISCELLANEOUS.
  340 +
  341 + This License represents the complete agreement concerning subject
  342 + matter hereof. If any provision of this License is held to be
  343 + unenforceable, such provision shall be reformed only to the extent
  344 + necessary to make it enforceable. This License shall be governed
  345 + by the law of the jurisdiction specified in a notice contained
  346 + within the Original Software (except to the extent applicable law,
  347 + if any, provides otherwise), excluding such jurisdiction's
  348 + conflict-of-law provisions. Any litigation relating to this
  349 + License shall be subject to the jurisdiction of the courts located
  350 + in the jurisdiction and venue specified in a notice contained
  351 + within the Original Software, with the losing party responsible
  352 + for costs, including, without limitation, court costs and
  353 + reasonable attorneys' fees and expenses. The application of the
  354 + United Nations Convention on Contracts for the International Sale
  355 + of Goods is expressly excluded. Any law or regulation which
  356 + provides that the language of a contract shall be construed
  357 + against the drafter shall not apply to this License. You agree
  358 + that You alone are responsible for compliance with the United
  359 + States export administration regulations (and the export control
  360 + laws and regulation of any other countries) when You use,
  361 + distribute or otherwise make available any Covered Software.
  362 +
  363 +10. RESPONSIBILITY FOR CLAIMS.
  364 +
  365 + As between Initial Developer and the Contributors, each party is
  366 + responsible for claims and damages arising, directly or
  367 + indirectly, out of its utilization of rights under this License
  368 + and You agree to work with Initial Developer and Contributors to
  369 + distribute such responsibility on an equitable basis. Nothing
  370 + herein is intended or shall be deemed to constitute any admission
  371 + of liability.
  372 +
  373 +--------------------------------------------------------------------
  374 +
  375 +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND
  376 +DISTRIBUTION LICENSE (CDDL)
  377 +
  378 +For Covered Software in this distribution, this License shall
  379 +be governed by the laws of the State of California (excluding
  380 +conflict-of-law provisions).
  381 +
  382 +Any litigation relating to this License shall be subject to the
  383 +jurisdiction of the Federal Courts of the Northern District of
  384 +California and the state courts of the State of California, with
  385 +venue lying in Santa Clara County, California.
5 Makefile.am
... ... @@ -0,0 +1,5 @@
  1 +AUTOMAKE_OPTIONS = foreign
  2 +bin_PROGRAMS = testclient
  3 +
  4 +testclient_SOURCES = main.c libmemc.c libmemc.h boxmuller.c metrics.c
  5 +
42 boxmuller.c
... ... @@ -0,0 +1,42 @@
  1 +/* code borrowed from ftp://ftp.taygeta.com/pub/c/boxmuller.c */
  2 +/* boxmuller.c Implements the Polar form of the Box-Muller
  3 + Transformation
  4 +
  5 + (c) Copyright 1994, Everett F. Carter Jr.
  6 + Permission is granted by the author to use
  7 + this software for any application provided this
  8 + copyright notice is preserved.
  9 +
  10 +*/
  11 +#include <math.h>
  12 +#include <stdlib.h>
  13 +
  14 +double box_muller(double m, double s) /* normal random variate generator */
  15 +{ /* mean m, standard deviation s */
  16 + double x1, x2, w, y1;
  17 + static double y2;
  18 + static int use_last = 0;
  19 +
  20 + if (use_last) /* use value from previous call */
  21 + {
  22 + y1 = y2;
  23 + use_last = 0;
  24 + }
  25 + else
  26 + {
  27 + do {
  28 + x1 = 2.0 * drand48() - 1.0;
  29 + x2 = 2.0 * drand48() - 1.0;
  30 + w = x1 * x1 + x2 * x2;
  31 + } while ( w >= 1.0 );
  32 +
  33 + w = sqrt( (-2.0 * log( w ) ) / w );
  34 + y1 = x1 * w;
  35 + y2 = x2 * w;
  36 + use_last = 1;
  37 + }
  38 +
  39 + double result = ( m + y1 * s );
  40 +
  41 + return result;
  42 +}
107 config/bootstrap
... ... @@ -0,0 +1,107 @@
  1 +#!/usr/bin/env bash
  2 +# Taken from lighthttpd server (BSD). Thanks Jan!
  3 +# then taken from libmemcached :)
  4 +# Run this to generate all the initial makefiles, etc.
  5 +
  6 +die() { echo "$@"; exit 1; }
  7 +
  8 +# LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}
  9 +LIBTOOLIZE_FLAGS=" --automake --copy --force"
  10 +# ACLOCAL=${ACLOCAL:-aclocal}
  11 +ACLOCAL_FLAGS="-I m4"
  12 +# AUTOHEADER=${AUTOHEADER:-autoheader}
  13 +# AUTOMAKE=${AUTOMAKE:-automake}
  14 +AUTOMAKE_FLAGS="--add-missing --copy --force"
  15 +# AUTOCONF=${AUTOCONF:-autoconf}
  16 +
  17 +ARGV0=$0
  18 +ARGS="$@"
  19 +
  20 +
  21 +run() {
  22 + echo "$ARGV0: running \`$@' $ARGS"
  23 + $@ $ARGS
  24 +}
  25 +
  26 +## jump out if one of the programs returns 'false'
  27 +set -e
  28 +
  29 +## We do not currently support glibtoolize
  30 +if test x$LIBTOOLIZE = x; then
  31 + if test \! "x`which glibtoolize 2> /dev/null | grep -v '^no'`" = x; then
  32 + LIBTOOLIZE=glibtoolize
  33 + elif test \! "x`which libtoolize-1.5 2> /dev/null | grep -v '^no'`" = x; then
  34 + LIBTOOLIZE=libtoolize-1.5
  35 + elif test \! "x`which libtoolize 2> /dev/null | grep -v '^no'`" = x; then
  36 + LIBTOOLIZE=libtoolize
  37 + else
  38 + echo "libtoolize 1.5.x wasn't found, exiting"; exit 0
  39 + fi
  40 +fi
  41 +
  42 +## suse has aclocal and aclocal-1.9
  43 +if test x$ACLOCAL = x; then
  44 + if test \! "x`which aclocal-1.10 2> /dev/null | grep -v '^no'`" = x; then
  45 + ACLOCAL=aclocal-1.10
  46 + elif test \! "x`which aclocal-1.9 2> /dev/null | grep -v '^no'`" = x; then
  47 + ACLOCAL=aclocal-1.9
  48 + elif test \! "x`which aclocal19 2> /dev/null | grep -v '^no'`" = x; then
  49 + ACLOCAL=aclocal19
  50 + elif test \! "x`which aclocal 2> /dev/null | grep -v '^no'`" = x; then
  51 + ACLOCAL=aclocal
  52 + else
  53 + echo "automake 1.9.x (aclocal) wasn't found, exiting"; exit 0
  54 + fi
  55 +fi
  56 +
  57 +if test x$AUTOMAKE = x; then
  58 + if test \! "x`which automake-1.10 2> /dev/null | grep -v '^no'`" = x; then
  59 + AUTOMAKE=automake-1.10
  60 + elif test \! "x`which automake-1.9 2> /dev/null | grep -v '^no'`" = x; then
  61 + AUTOMAKE=automake-1.9
  62 + elif test \! "x`which automake19 2> /dev/null | grep -v '^no'`" = x; then
  63 + AUTOMAKE=automake19
  64 + elif test \! "x`which automake 2> /dev/null | grep -v '^no'`" = x; then
  65 + AUTOMAKE=automake
  66 + else
  67 + echo "automake 1.9.x wasn't found, exiting"; exit 0
  68 + fi
  69 +fi
  70 +
  71 +
  72 +## macosx has autoconf-2.59 and autoconf-2.60
  73 +if test x$AUTOCONF = x; then
  74 + if test \! "x`which autoconf-2.59 2> /dev/null | grep -v '^no'`" = x; then
  75 + AUTOCONF=autoconf-2.59
  76 + elif test \! "x`which autoconf259 2> /dev/null | grep -v '^no'`" = x; then
  77 + AUTOCONF=autoconf259
  78 + elif test \! "x`which autoconf 2> /dev/null | grep -v '^no'`" = x; then
  79 + AUTOCONF=autoconf
  80 + else
  81 + echo "autoconf 2.59+ wasn't found, exiting"; exit 0
  82 + fi
  83 +fi
  84 +
  85 +if test x$AUTOHEADER = x; then
  86 + if test \! "x`which autoheader-2.59 2> /dev/null | grep -v '^no'`" = x; then
  87 + AUTOHEADER=autoheader-2.59
  88 + elif test \! "x`which autoheader259 2> /dev/null | grep -v '^no'`" = x; then
  89 + AUTOHEADER=autoheader259
  90 + elif test \! "x`which autoheader 2> /dev/null | grep -v '^no'`" = x; then
  91 + AUTOHEADER=autoheader
  92 + else
  93 + echo "autoconf 2.59+ (autoheader) wasn't found, exiting"; exit 0
  94 + fi
  95 +fi
  96 +
  97 +
  98 +# --force means overwrite ltmain.sh script if it already exists
  99 +# run $LIBTOOLIZE $LIBTOOLIZE_FLAGS || die "Can't execute libtoolize"
  100 +
  101 +run $ACLOCAL $ACLOCAL_FLAGS || die "Can't execute aclocal"
  102 +run $AUTOHEADER || die "Can't execute autoheader"
  103 +
  104 +# --add-missing instructs automake to install missing auxiliary files
  105 +# and --force to overwrite them if they already exist
  106 +run $AUTOMAKE $AUTOMAKE_FLAGS || die "Can't execute automake"
  107 +run $AUTOCONF || die "Can't execute autoconf"
97 configure.ac
... ... @@ -0,0 +1,97 @@
  1 +AC_PREREQ(2.52)
  2 +AC_INIT(memcachebench, 0.5.0, ingenthr@cep.net)
  3 +AC_CONFIG_SRCDIR(main.c)
  4 +AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
  5 +AM_CONFIG_HEADER(config.h)
  6 +
  7 +AC_PROG_CC
  8 +AC_PROG_CC_C99
  9 +AM_PROG_CC_C_O
  10 +AC_PROG_INSTALL
  11 +AC_C_CONST
  12 +
  13 +AC_ARG_ENABLE(64bit,
  14 + [AS_HELP_STRING([--enable-64bit],[build 64bit version])])
  15 +if test "x$enable_64bit" == "xyes"
  16 +then
  17 + org_cflags=$CFLAGS
  18 + CFLAGS=-m64
  19 + AC_RUN_IFELSE(
  20 + [AC_LANG_PROGRAM([], [dnl
  21 +return sizeof(void*) == 8 ? 0 : 1;
  22 + ])
  23 + ],[
  24 + CFLAGS="-m64 $org_cflags"
  25 + ],[
  26 + AC_MSG_ERROR([Don't know how to build a 64-bit object.])
  27 + ])
  28 +fi
  29 +
  30 +AC_ARG_WITH(libmemcached,
  31 + AS_HELP_STRING(--with-libmemcached,[Add support for libmemcached]),
  32 + [
  33 + if test "x$withval" = "xno"
  34 + then
  35 + without_libmemcached=true
  36 + else
  37 + if test "x$withval" != "x"
  38 + then
  39 + CFLAGS="-I$withval/include $CFLAGS"
  40 + CPPFLAGS="-I$withval/include $CPPFLAGS"
  41 + # TODO: linux should have --rpath instead of -R
  42 + LDFLAGS="-L$withval/lib -Wl,-R$withval/lib"
  43 + fi
  44 + fi
  45 + ]
  46 +)
  47 +
  48 +AC_ARG_WITH(memcached,
  49 + AS_HELP_STRING(--with-memcached,[Specify location of memcached installation]),
  50 + [
  51 + if test "x$withval" = "xno"
  52 + then
  53 + without_memcached=true
  54 + else
  55 + if test "x$withval" != "x"
  56 + then
  57 + CFLAGS="-I$withval/include $CFLAGS"
  58 + CPPFLAGS="-I$withval/include $CPPFLAGS"
  59 + fi
  60 + fi
  61 + ]
  62 +)
  63 +
  64 +# Currently I only support GCC and Sun Studio
  65 +if test "$GCC" = "yes"
  66 +then
  67 + CFLAGS="-Wall -O3 $CFLAGS"
  68 +else
  69 + CFLAGS="-Xa -xstrconst -mt -xunroll=2 -xprefetch=auto -xprefetch_level=3 $CFLAGS"
  70 +fi
  71 +
  72 +AC_SEARCH_LIBS(socket, socket)
  73 +AC_SEARCH_LIBS(gethostbyname, nsl)
  74 +AC_SEARCH_LIBS(log, m)
  75 +AC_SEARCH_LIBS(sqrt, m)
  76 +AC_SEARCH_LIBS(pthread_create, pthread)
  77 +
  78 +AC_CHECK_HEADER(sys/mman.h, AC_DEFINE(HAVE_MMAN_H, 1, [Define if you have sys/mman.h]))
  79 +AC_CHECK_FUNC(mmap, AC_DEFINE(HAVE_MMAP, 1, [Define if you have mmap]))
  80 +AC_CHECK_FUNC(madvise, AC_DEFINE(HAVE_MADVISE, 1, [Define if you have madvise]))
  81 +AC_CHECK_FUNC(gethrtime, AC_DEFINE(HAVE_GETHRTIME, 1, [Define if you have gethrtime]))
  82 +
  83 +if test "$without_libmemcaced" != "true"
  84 +then
  85 + AC_CHECK_HEADER(libmemcached/memcached.h,
  86 + AC_SEARCH_LIBS(memcached_create, memcached,
  87 + AC_DEFINE(HAVE_LIBMEMCACHED, 1, [Define if you have libmemcached/memcached.h])))
  88 +fi
  89 +
  90 +if test "$without_memcaced" != "true"
  91 +then
  92 + AC_CHECK_HEADER(memcached/protocol_binary.h,
  93 + AC_DEFINE(HAVE_PROTOCOL_BINARY, 1, [Define if you have memcached/protocol_binary.h]))
  94 +fi
  95 +
  96 +AC_CONFIG_FILES(Makefile)
  97 +AC_OUTPUT
752 libmemc.c
... ... @@ -0,0 +1,752 @@
  1 +/*
  2 + * CDDL HEADER START
  3 + *
  4 + * The contents of this file are subject to the terms of the
  5 + * Common Development and Distribution License (the "License").
  6 + * You may not use this file except in compliance with the License.
  7 + *
  8 + * See LICENSE.txt included in this distribution for the specific
  9 + * language governing permissions and limitations under the License.
  10 + *
  11 + * When distributing Covered Code, include this CDDL HEADER in each
  12 + * file and include the License file at LICENSE.txt.
  13 + * If applicable, add the following below this CDDL HEADER, with the
  14 + * fields enclosed by brackets "[]" replaced with your own identifying
  15 + * information: Portions Copyright [yyyy] [name of copyright owner]
  16 + *
  17 + * CDDL HEADER END
  18 + */
  19 +
  20 +/*
  21 + * Portions Copyright 2009 Matt Ingenthron
  22 + */
  23 +
  24 +#include "config.h"
  25 +
  26 +#include "libmemc.h"
  27 +
  28 +#if HAVE_PROTOCOL_BINARY
  29 +#include <memcached/protocol_binary.h>
  30 +#endif
  31 +#include <sys/types.h>
  32 +#include <sys/socket.h>
  33 +#include <netdb.h>
  34 +#include <arpa/inet.h>
  35 +#include <netinet/tcp.h>
  36 +#include <unistd.h>
  37 +#include <errno.h>
  38 +#include <stdlib.h>
  39 +#include <string.h>
  40 +#include <stdio.h>
  41 +#include <assert.h>
  42 +
  43 +struct Server {
  44 + int sock;
  45 + struct addrinfo *addrinfo;
  46 + const char *errmsg;
  47 + const char *peername;
  48 + char *buffer;
  49 + int buffersize;
  50 +};
  51 +
  52 +enum StoreCommand {add, set, replace};
  53 +
  54 +struct Memcache {
  55 + struct Server** servers;
  56 + enum Protocol protocol;
  57 + int no_servers;
  58 +};
  59 +
  60 +static struct Server* server_create(const char *name, in_port_t port);
  61 +static void server_destroy(struct Server *server);
  62 +static int textual_store(struct Server* server, enum StoreCommand cmd,
  63 + const struct Item *item);
  64 +static int textual_get(struct Server* server, struct Item* item);
  65 +static int binary_store(struct Server* server, enum StoreCommand cmd,
  66 + const struct Item *item);
  67 +static int binary_get(struct Server* server, struct Item* item);
  68 +static int libmemc_store(struct Memcache* handle, enum StoreCommand cmd, const struct Item *item);
  69 +static struct Server *get_server(struct Memcache *handle, const char *key);
  70 +static int server_connect(struct Server *server);
  71 +
  72 +
  73 +/**
  74 + * External interface
  75 + */
  76 +struct Memcache* libmemc_create(enum Protocol protocol) {
  77 + struct Memcache* ret = calloc(1, sizeof(struct Memcache));
  78 + if (ret != NULL) {
  79 + ret->protocol = protocol;
  80 + }
  81 + return ret;
  82 +}
  83 +
  84 +void libmemc_destroy(struct Memcache* handle) {
  85 + for (int ii = 0; ii < handle->no_servers; ++ii) {
  86 + server_destroy(handle->servers[ii]);
  87 + }
  88 + free(handle);
  89 +}
  90 +
  91 +int libmemc_add_server(struct Memcache *handle, const char *host, in_port_t port) {
  92 + struct Server** servers = calloc(handle->no_servers + 1, sizeof(struct Server));
  93 + struct Server** old = handle->servers;
  94 +
  95 + if (servers == 0) {
  96 + return -1;
  97 + }
  98 +
  99 + for (int ii = 0; ii < handle->no_servers; ++ii) {
  100 + servers[ii] = handle->servers[ii];
  101 + }
  102 +
  103 + handle->servers = servers;
  104 + free(old);
  105 +
  106 + struct Server *server = server_create(host, port);
  107 + if (server != NULL) {
  108 + handle->servers[handle->no_servers++] = server;
  109 + }
  110 +
  111 + return 0;
  112 +}
  113 +
  114 +int libmemc_add(struct Memcache *handle, const struct Item *item) {
  115 + return libmemc_store(handle, add, item);
  116 +}
  117 +
  118 +int libmemc_set(struct Memcache *handle, const struct Item *item) {
  119 + return libmemc_store(handle, set, item);
  120 +}
  121 +
  122 +int libmemc_replace(struct Memcache *handle, const struct Item *item) {
  123 + return libmemc_store(handle, replace, item);
  124 +}
  125 +
  126 +int libmemc_get(struct Memcache *handle, struct Item *item) {
  127 + struct Server* server = get_server(handle, item->key);
  128 + if (server == NULL) {
  129 + return -1;
  130 + } else {
  131 + if (server->sock == -1) {
  132 + if (server_connect(server) == -1) {
  133 + fprintf(stderr, "%s\n", server->errmsg);
  134 + fflush(stderr);
  135 + return -1;
  136 + }
  137 + }
  138 +
  139 + if (handle->protocol == Binary) {
  140 + return binary_get(server, item);
  141 + } else {
  142 + return textual_get(server, item);
  143 + }
  144 + }
  145 +}
  146 +
  147 +static struct addrinfo *lookuphost(const char *hostname, in_port_t port)
  148 +{
  149 + struct addrinfo *ai = 0;
  150 + struct addrinfo hints = {0};
  151 + char service[NI_MAXSERV];
  152 + int error;
  153 +
  154 + hints.ai_flags = AI_PASSIVE|AI_ADDRCONFIG;
  155 + hints.ai_family = AF_UNSPEC;
  156 + hints.ai_protocol = IPPROTO_TCP;
  157 + hints.ai_socktype = SOCK_STREAM;
  158 +
  159 + (void)snprintf(service, NI_MAXSERV, "%d", port);
  160 + if ((error = getaddrinfo(hostname, service, &hints, &ai)) != 0) {
  161 + if (error != EAI_SYSTEM) {
  162 + fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(error));
  163 + } else {
  164 + perror("getaddrinfo()");
  165 + }
  166 + }
  167 +
  168 + return ai;
  169 +}
  170 +
  171 +int libmemc_connect_server(const char *hostname, in_port_t port)
  172 +{
  173 + struct addrinfo *ai = lookuphost(hostname, port);
  174 + int sock = -1;
  175 + if (ai != NULL) {
  176 + if ((sock = socket(ai->ai_family, ai->ai_socktype,
  177 + ai->ai_protocol)) != -1) {
  178 + if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
  179 + fprintf(stderr, "Failed to connect socket: %s\n",
  180 + strerror(errno));
  181 + close(sock);
  182 + sock = -1;
  183 + }
  184 + } else {
  185 + fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
  186 + }
  187 +
  188 + freeaddrinfo(ai);
  189 + }
  190 + return sock;
  191 +}
  192 +
  193 +/**
  194 + * Internal functions used by both protocols
  195 + */
  196 +static uint32_t simplehash(const char *key) {
  197 + if (key == 0) {
  198 + return 0;
  199 + }
  200 + uint32_t ret = 0;
  201 + for (ret = *key; *key != 0; ++key) {
  202 + ret = (ret << 4) + *key;
  203 + }
  204 + return ret;
  205 +}
  206 +
  207 +static struct Server *get_server(struct Memcache *handle, const char *key) {
  208 + if (handle->no_servers == 1) {
  209 + return handle->servers[0];
  210 + } else if (handle->no_servers > 0) {
  211 + int idx = simplehash(key) % handle->no_servers;
  212 + return handle->servers[idx];
  213 + } else {
  214 + return NULL;
  215 + }
  216 +}
  217 +
  218 +static int libmemc_store(struct Memcache* handle, enum StoreCommand cmd,
  219 + const struct Item *item) {
  220 + struct Server* server = get_server(handle, item->key);
  221 + if (server == NULL) {
  222 + return -1;
  223 + } else {
  224 + if (server->sock == -1) {
  225 + if (server_connect(server) == -1) {
  226 + return -1;
  227 + }
  228 + }
  229 +
  230 + if (handle->protocol == Binary) {
  231 + return binary_store(server, cmd, item);
  232 + } else {
  233 + return textual_store(server, cmd, item);
  234 + }
  235 + }
  236 +}
  237 +
  238 +static size_t server_receive(struct Server* server, char* data, size_t size, int line);
  239 +static int server_sendv(struct Server* server, struct iovec *iov, int iovcnt);
  240 +static int server_send(struct Server* server, const void *data, size_t size);
  241 +static int server_connect(struct Server *server);
  242 +static void server_disconnect(struct Server *server);
  243 +
  244 +void server_destroy(struct Server *server) {
  245 + if (server != NULL) {
  246 + if (server->sock != -1) {
  247 + close(server->sock);
  248 + }
  249 + free(server->buffer);
  250 + free(server);
  251 + }
  252 +}
  253 +
  254 +struct Server* server_create(const char *name, in_port_t port) {
  255 + struct addrinfo* ai = lookuphost(name, port);
  256 + struct Server* ret = NULL;
  257 + if (ai != NULL) {
  258 + ret = calloc(1, sizeof(struct Server));
  259 + if (ret != 0) {
  260 + char buffer[1024];
  261 + ret->sock = -1;
  262 + ret->errmsg = 0;
  263 + ret->addrinfo = ai;
  264 + sprintf(buffer, "%s:%d", name, port);
  265 + ret->peername = strdup(buffer);
  266 + ret->buffer = malloc(65 * 1024);
  267 + ret->buffersize = 65 * 1024;
  268 + server_connect(ret);
  269 + if (ret->buffer == NULL) {
  270 + server_destroy(ret);
  271 + ret = 0;
  272 + }
  273 + }
  274 + }
  275 +
  276 + return ret;
  277 +}
  278 +
  279 +static void server_disconnect(struct Server *server) {
  280 + if (server->sock != -1) {
  281 + (void)close(server->sock);
  282 + server->sock = -1;
  283 + }
  284 +}
  285 +
  286 +static int server_connect(struct Server *server)
  287 +{
  288 + int flag = 1;
  289 +
  290 + if ((server->sock = socket(server->addrinfo->ai_family,
  291 + server->addrinfo->ai_socktype,
  292 + server->addrinfo->ai_protocol)) == -1) {
  293 + char errmsg[1024];
  294 + sprintf(errmsg, "Failed to create socket: %s", strerror(errno));
  295 + server->errmsg = strdup(errmsg);
  296 + return -1;
  297 + }
  298 +
  299 + if (setsockopt(server->sock, IPPROTO_TCP, TCP_NODELAY,
  300 + &flag, sizeof(flag)) == -1) {
  301 + perror("Failed to set TCP_NODELAY");
  302 + }
  303 +
  304 + if (connect(server->sock, server->addrinfo->ai_addr,
  305 + server->addrinfo->ai_addrlen) == -1) {
  306 + char errmsg[1024];
  307 + sprintf(errmsg, "Failed to connect socket: %s", strerror(errno));
  308 + server->errmsg = strdup(errmsg);
  309 + server_disconnect(server);
  310 + return -1;
  311 + }
  312 +
  313 + return 0;
  314 +}
  315 +
  316 +static int server_send(struct Server* server, const void *data, size_t size) {
  317 + size_t offset = 0;
  318 + do {
  319 + ssize_t sent = send(server->sock, ((const char*)data) + offset, size - offset, 0);
  320 + if (sent == -1) {
  321 + if (errno != EINTR) {
  322 + char errmsg[1024];
  323 + sprintf(errmsg, "Failed to send data to server: %s", strerror(errno));
  324 + server->errmsg = strdup(errmsg);
  325 + server_disconnect(server);
  326 + return -1;
  327 + }
  328 + } else {
  329 + offset += sent;
  330 + }
  331 + } while (offset < size);
  332 +
  333 + return 0;
  334 +}
  335 +
  336 +static int server_sendv(struct Server* server, struct iovec *iov, int iovcnt) {
  337 +#ifdef WIN32
  338 + // @todo I might have a scattered IO function on windows...
  339 + for (int ii = 0; ii < iovcnt; ++ii) {
  340 + if (send(server, iov[ii].iov_base, iov[ii].iov_len) != 0) {
  341 + return -1;
  342 + }
  343 + }
  344 +#else
  345 + // @todo Verify implementation if the writev returns with partitial
  346 + // writes!
  347 + size_t size = 0;
  348 + for (int ii = 0; ii < iovcnt; ++ ii) {
  349 + size += iov[ii].iov_len;
  350 + }
  351 +
  352 + do {
  353 + ssize_t sent = writev(server->sock, iov, iovcnt);
  354 + if (sent == -1) {
  355 + if (errno != EINTR) {
  356 + char errmsg[1024];
  357 + sprintf(errmsg, "Failed to send data to server: %s", strerror(errno));
  358 + server->errmsg = strdup(errmsg);
  359 + server_disconnect(server);
  360 + return -1;
  361 + }
  362 + } else {
  363 + if (sent == size) {
  364 + return 0;
  365 + }
  366 +
  367 + for (int ii = 0; ii < iovcnt && sent > 0; ++ii) {
  368 + if (iov[ii].iov_len < sent) {
  369 + size -= iov[ii].iov_len;
  370 + sent -= iov[ii].iov_len;
  371 + iov[ii].iov_len = 0;
  372 + } else {
  373 +#ifdef __sun
  374 + iov[ii].iov_base += sent;
  375 +#else
  376 + // iov_base is a void pointer...
  377 + iov[ii].iov_base = ((char*)iov[ii].iov_base) + sent;
  378 +#endif
  379 + iov[ii].iov_len -= sent;
  380 + size -= sent;
  381 + break;
  382 + }
  383 + }
  384 + }
  385 + } while (size > 0);
  386 +#endif
  387 + return 0;
  388 +}
  389 +
  390 +static size_t server_receive(struct Server* server, char* data, size_t size, int line) {
  391 + size_t offset = 0;
  392 + int stop = 0;
  393 + do {
  394 + ssize_t nread = recv(server->sock, data + offset, size - offset, 0);
  395 + if (nread == -1) {
  396 + if (errno != EINTR) {
  397 + char errmsg[1024];
  398 + sprintf(errmsg, "Failed to receive data from server: %s", strerror(errno));
  399 + server->errmsg = strdup(errmsg);
  400 + server_disconnect(server);
  401 + return -1;
  402 + }
  403 + } else {
  404 + if (line) {
  405 + if (strchr(data + offset, '\r') != 0) {
  406 + stop = 1;
  407 + }
  408 + }
  409 + offset += nread;
  410 + }
  411 + } while (offset < size && !stop);
  412 +
  413 + if (line && !stop) {
  414 + server->errmsg = strdup("Protocol error");
  415 + server_disconnect(server);
  416 + return -1;
  417 + }
  418 +
  419 + return offset;
  420 +}
  421 +
  422 +
  423 +/* Byte swap a 64-bit number */
  424 +static int64_t swap64(int64_t in) {
  425 +#ifndef __sparc
  426 + /* Little endian, flip the bytes around until someone makes a faster/better
  427 + * way to do this. */
  428 + int64_t rv = 0;
  429 + int i = 0;
  430 + for(i = 0; i < 8; i++) {
  431 + rv = (rv << 8) | (in & 0xff);
  432 + in >>= 8;
  433 + }
  434 + return rv;
  435 +#else
  436 + /* big-endian machines don't need byte swapping */
  437 + return in;
  438 +#endif
  439 +}
  440 +
  441 +
  442 +/**
  443 + * Implementation of the Binary protocol
  444 + */
  445 +static int binary_get(struct Server* server, struct Item* item)
  446 +{
  447 +#if HAVE_PROTOCOL_BINARY
  448 + uint16_t keylen = item->keylen;
  449 + uint32_t bodylen = keylen;
  450 +
  451 + protocol_binary_request_get request = { .bytes = {0} };
  452 + request.message.header.request.magic = PROTOCOL_BINARY_REQ;
  453 + request.message.header.request.opcode = PROTOCOL_BINARY_CMD_GET;
  454 + request.message.header.request.keylen = htons(keylen);
  455 + request.message.header.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
  456 + request.message.header.request.bodylen = htonl(bodylen);
  457 +
  458 + struct iovec iovec[2];
  459 + iovec[0].iov_base = (void*)&request;
  460 + iovec[0].iov_len = sizeof(request);
  461 + iovec[1].iov_base = (void*)item->key;
  462 + iovec[1].iov_len = keylen;
  463 +
  464 + server_sendv(server, iovec, 2);
  465 +
  466 + protocol_binary_response_set response;
  467 + size_t nread = server_receive(server, (char*)response.bytes,
  468 + sizeof(response.bytes), 0);
  469 + if (nread != sizeof(response)) {
  470 + server->errmsg = strdup("Protocol error");
  471 + server_disconnect(server);
  472 + return -1;
  473 + }
  474 +
  475 + bodylen = ntohl(response.message.header.response.bodylen);
  476 + if (response.message.header.response.status == 0) {
  477 + if (item->data != NULL) {
  478 + if ((bodylen-response.message.header.response.extlen) > item->size) {
  479 + free(item->data);
  480 + item->data = NULL;
  481 + }
  482 + }
  483 +
  484 + if (item->data == NULL) {
  485 + item->size = bodylen - response.message.header.response.extlen;
  486 + item->data = malloc(item->size);
  487 + if (item->data == NULL) {
  488 + server->errmsg = strdup("failed to allocate memory\n");
  489 + server_disconnect(server);
  490 + return -1;
  491 + }
  492 + }
  493 +
  494 + if (response.message.header.response.extlen != 0) {
  495 + assert(response.message.header.response.extlen == 4);
  496 + uint32_t flags;
  497 + struct iovec iovec[2];
  498 + iovec[0].iov_base = (void*)&flags;
  499 + iovec[0].iov_len = sizeof(flags);
  500 + iovec[1].iov_base = item->data;
  501 + iovec[1].iov_len = item->size;
  502 +
  503 + ssize_t nread = readv(server->sock, iovec, 2);
  504 + if (nread < bodylen) {
  505 + // partial read.. read the rest!
  506 + nread -= 4;
  507 + size_t left = item->size - nread;
  508 + if (server_receive(server, item->data + nread, left, 0) != left) {
  509 + abort();
  510 + }
  511 + }
  512 + } else {
  513 + size_t nread = server_receive(server, item->data, item->size, 0);
  514 + assert(nread == item->size);
  515 + }
  516 +
  517 + item->cas_id = swap64(response.message.header.response.cas);
  518 + } else {
  519 + char *buffer = malloc(bodylen + 1);
  520 + if (buffer == NULL) {
  521 + server->errmsg = strdup("failed to allocate memory\n");
  522 + server_disconnect(server);
  523 + return -1;
  524 + }
  525 + buffer[bodylen] = '\0';
  526 + server_receive(server, buffer, bodylen, 0);
  527 + server->errmsg = buffer;
  528 +
  529 + return -1;
  530 + }
  531 +
  532 + return 0;
  533 +#endif
  534 + return -1;
  535 +}
  536 +
  537 +static int binary_store(struct Server* server,
  538 + enum StoreCommand cmd,
  539 + const struct Item *item)
  540 +{
  541 +#if HAVE_PROTOCOL_BINARY
  542 + protocol_binary_request_set request = { .bytes = {0} };
  543 + request.message.header.request.magic = PROTOCOL_BINARY_REQ;
  544 +
  545 + switch (cmd) {
  546 + case add :
  547 + request.message.header.request.opcode = PROTOCOL_BINARY_CMD_ADD; break;
  548 + case set :
  549 + request.message.header.request.opcode = PROTOCOL_BINARY_CMD_SET; break;
  550 + case replace :
  551 + request.message.header.request.opcode = PROTOCOL_BINARY_CMD_REPLACE; break;
  552 + default:
  553 + abort();
  554 + }
  555 +
  556 + uint16_t keylen = item->keylen;
  557 + request.message.header.request.keylen = htons(keylen);
  558 + request.message.header.request.extlen = 8;
  559 + request.message.header.request.datatype = 0;
  560 + request.message.header.request.reserved = 0;
  561 + request.message.header.request.bodylen = htonl(keylen + item->size + 8);
  562 + request.message.header.request.opaque = 0;
  563 + request.message.header.request.cas = swap64(item->cas_id);
  564 + request.message.body.flags = 0;
  565 + request.message.body.expiration = htonl(item->exptime);
  566 +
  567 + struct iovec iovec[3];
  568 + iovec[0].iov_base = (void*)&request;
  569 + iovec[0].iov_len = sizeof(request);
  570 + iovec[1].iov_base = (void*)item->key;
  571 + iovec[1].iov_len = keylen;
  572 + iovec[2].iov_base = item->data;
  573 + iovec[2].iov_len = item->size;
  574 +
  575 + server_sendv(server, iovec, 3);
  576 +
  577 + protocol_binary_response_set response;
  578 + size_t nread = server_receive(server, (char*)response.bytes,
  579 + sizeof(response.bytes), 0);
  580 + if (nread != sizeof(response)) {
  581 + server->errmsg = strdup("Protocol error");
  582 + server_disconnect(server);
  583 + return -1;
  584 + }
  585 +
  586 + if (response.message.header.response.status == 0 &&
  587 + response.message.header.response.bodylen != 0) {
  588 + server->errmsg = strdup("Unexpected data returned\n");
  589 + server_disconnect(server);
  590 + return -1;
  591 + } else if (response.message.header.response.bodylen != 0) {
  592 + uint32_t len = ntohl(response.message.header.response.bodylen);
  593 + char* buffer = malloc(len);
  594 + if (buffer == 0) {
  595 + server->errmsg = strdup("failed to allocate memory\n");
  596 + server_disconnect(server);
  597 + return -1;
  598 + }
  599 +
  600 + size_t nread = server_receive(server, buffer, len, 0);
  601 + free(buffer);
  602 + }
  603 +
  604 + return (response.message.header.response.status == 0) ? 0 : -1;
  605 +#endif
  606 + return -1;
  607 +}
  608 +
  609 +/**
  610 + * Implementation of the Textual protocol
  611