[
  {
    "path": ".gitignore",
    "content": "target\n*.log\n*.classpath\n*.project\n*.settings\n*.DS_Store\n*.class\njredis.tmproj\n*.iml\n*.idea\n"
  },
  {
    "path": "DEV-NOTES.txt",
    "content": "Wed Feb 1 2012 \n\n\t* Merged chunk-pipelien branch to master\n\t  REFERENCE commit a9cff24fd8f041ec181598c571989680a4e5ad15 is\n\t  master prior to merge.\n\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "README",
    "content": "(This README is mainly addressing the project structure and build.  For information\nabout JRedis, please see the RELEASE-NOTES.) \n\n----------------------------------------------------------\nBUILD\n----------------------------------------------------------\n\n* Requirements:\n\n- maven \n\nProject uses Maven 2 as the build management system.  You\nwill need maven to conveniently build and package the \nproject jars.\n\nProject master is built on Mac OS X 10.5 using maven 2.0.9.\n\n* howto\n\nProject is not yet using assemblies, but is a multi-module\nmaven build with master POM in root directory (where you \nfound this document).\n\nEach module has its own pom, but you will need to run maven\nwith specific goals at the level of a major sub-module.  As\nof now (intial release alpha.0-04152009) that translates to\na 'Core' and an 'Examples'.  \n\nIf you wish to use JRedis only you will need the product of\nthe Core-RI (reference implementation).  \n\nIf you wish to run benchmarks + use JRedis, you will also \nneed to build the Core-BENCHMARK.\n\nSimplest thing to do is to run maven with goal package at\nthe Core module level.  This will initiate and build each\nmodule in Core:\n\nAPI - The specifications, which are mostly interfaces.\nRI - The reference implementation, which is you will use.\nBENCH - The benchmark classes\nALL - A convenience virtual module that will build a \nunified jar of all modules besides itself in Core.\n\nOn command line in ~/core/., issue:\n\n   mvn install\n\nThis will compile, test, package, and install JRedis\ncore artifacts in your local repository and create a \nset of jars in each core module's 'target' directory.\n\nThe pom of the Core as well as the super pom in the root\nfolder use a source attachment plugin, so a source jar \nwill also be created for each module.  \n\nThe poms of core-ri, core-bench, and core-all use a \ninclude dependencies mechanism which will build, besides\nthe individual module's jar, an aggregate unified jar of\nthe module's classes + the classes of any dependency it\nhas declared.  (Only install goal will do this -- package\ngoal will simply create the module's own jar file(s)).\n\nFor example, issuing mvn install from core will create\nin module core-bench's target directory the class and\nsource jars for the BENCH module + a single jar containing\nall dependencies, which for BENCH are 'API' and 'RI'.\n\nThe build system uses a structured naming convention \nwhich results in longish names, but it is very effective.\n(You can obviously simply change the jar names when you\ndeploy to your application's lib or jvm classpath as you\nsee fit.)\n\nThe super pom in project root will initiate the same for\nall modules of JRedis, which as of now are CORE, and\nEXAMPLES.  (Same considerations apply here.)\n\n\n   **** IMPORTANT NOTE REGARDING UNIT TEST ****\n\nRunning unit tests is absolutely critical to a sane process\nfor developing JRedis, given that it is subject to a very\ndemanding refactoring regime (as it is a work in progress).\n\nThat means testing is critical for the master copy and\naccordingly ALL poms in the project require SUCCESSFUL \ntests after compile before continuing.\n\n   **** REDIS MUST BE RUNNING ON LOCALHOST *****\n\nSo, as tests on a connector without a server are fairly\npointless, this project will NOT build unless you have \nyour localhost (6379) Redis server running.\n\n   **** BUILD USES PASSWORD 'jredis' ****\n\nIf you do not have password set on your redis, no \nworries. \n\nIf you do, the build will fail, unless you do one\nof the following:\n\n1) Change the password in core/pom.xml to match your\npassword in redis.conf\n\n2) Alternatively tell maven to skip tests:\n\n   mvn -Dmaven.test.skip=true install\n\n\n  **** REMEMBER:  TESTS WILL FLUSH DBS 13 AND 10 *****\n\n-\n\n04-21-09 \n\n"
  },
  {
    "path": "RELEASE-NOTES.txt",
    "content": "\n\n                       ~!! n o ' r o o z !!~\n                       \n-------------------------------------------------------------------------\n n o ' r o o z                                 R E L E A S E   N O T E S\n-------------------------------------------------------------------------\n\n         JREDIS SPECIFICATION AND REFERENCE IMPLEMENTATION\n\n[updated on 04-21-09]\n\n * About \n \nThis is the initial (alpha.0) release of JREDIS, (code named \"no'rooz\").\nWork on this began around the Persian New Year (No'Rooz, meaning New Day)\nand has continued since then almost to the exclusion of nearly everything\nelse. \n\n\n * Redis compliance\n \nThe specification and the implementation in this release comply with the \nthe latest redis development release specification as of 04-21-09 and \ntested against the build of the REDIS server from the github repository.\n\n\n * Structure\n \nJREDIS is composed of a Reference and a reference Implementation, under\na unified top-level packages.  (A single jar build is provided in this\nrelease, which can be included in your classpath and simply utilized.)\n\nFurther Java artifacts include testing, benchmarking, and example source\ndirectories.  All these, and the core, can be found under the java \ndirectory.  To build JREDIS, you will only need to compile the files\nunder ~/java/src/.\n\n\n * Included features\n\nThis initial revision includes a complete functioning Synchronous\nconnector for REDIS.  (Asynchronous connection and pipelining support are\non the immediate TODO shortlist.)  The initial release connection only\nsupports (for now) a use case scenario of create, continuously use, and\ndiscard.  Enhanced connection maintenance and transparent re-connect are\nalso on the immediate TODO list for the initial revision.  This connector\nis exposed for use as org.jredis.ri.alphazero.JRedisClient and you simply\nneed to instantiate and immediately use it to connect to your localhost\nREDIS server.  This is a synchronous mode connection, with blocking \nsemantics for JRedis API, and is intended for use strictly in a synchronized\nrequest/reply manner.  To achieve concurrent connections, simply create\na client instance per thread.  (See the benchmark classes for examples.)\n\nA queuing synchronous mode connector suitable for use in containers is \non the drawing board.  (If you can not wait for this, you may hack your\nown by placing a JRedis facade in front of a combination of classes from\njava.util.concurrent and using a pool of JRedisClients behind the scenes.)\n\nIf you elect to do this, do note that connections to Redis are effectively\nstateful and you can not trivially use a connection to serve the requests\nof multiple requesters (threads) IFF you use commands such as SELECT.\n\nBeyond that, JREDIS as of now supports basic Java serialization and you\ncan use your Java objects as 'values' for String, Set, and List keys in\nREDIS.  And of course, the JRedis interface has been designed to provide\nflexibility and 'native' REDIS access, so you can always send whatever\nbyte[] that you want (which is probably more efficient if you already\nhave externalization means for your Java classes).\n\n\n * Requirements\n\nREDIS:\nObviously you will need a REDIS server to use JREDIS!  JREDIS is fully\ncompliant with all documented REDIS beta-0.09 commands, and also supports \nEXPIRE.  JREDIS as of now does NOT support the earlier 0.08 versions\nbut structurally is able to handle a multiplicity of REDIS versions,\nand you should be able to create your own variant of ProtocolHandler\nto interact with earlier (obsolete) versions of REDIS.\n\nJAVA:\nJREDIS has no external dependencies at this time.  The alpha.0 release\nhas been developed using Java 6 to utilize enhanced reporting afforded\nby the compiler to implementations of Java interfaces.  However, JRE 6\nor any of its features or libraries are not a fundamental requirement\nand this release has the incompatible usage instances commented out to\nallow for use with JRE 5.x and above.\n\nPlease note that while this software may or may not work under JDK 1.4.x\nor earlier, it is simply *not* a goal for this project to support these\nearlier version of Java, as that would adversely constrain the options\nin both the expression of JRedis semantics and an effective implementation.\n\nTESTS:\nTest source files and classes clearly require TestNG library , \nbut these test artifacts are not included in the drop-in jar so JUnit is\nnot a requirement for using JRedis.\n\nBUILD:\nJREDIS was built on Eclipse 3.4, on Apple's Mac OS X 10.5 running JVM1.6.\nThe JREDIS core software itself can be built simply using jacav and jar\n\nThat said, the current release uses structured Maven 2 poms to build\nthe project and execute the tests.\n\n * Status\n \nThis software is a *work in progress* and subject to change.  Careful\nconsideration has been given to the concerns and requirements of the end-\nuser of this software to minimize the impact of (certain) changes to \nthe code-base as development continues, to extend functionality, to \nenhance performance, and to address the feedback of its user community.\n\nThat said, this is working code that has been tested and stressed, and\nminimally provides a viable and versatile interface between Java systems\nand the REDIS database.  Coding to the specification artifacts will \nminimize, but will not eliminate, any impact of the un-going developments.  \n\nRough edges are to be expected, and your patience appreciated while this\nrelease makes the necessary transition to maturity.\n\nAnd finally, *all the usual caveats regarding software apply:  So\nto repeat from the license terms,  JREDIS is distributed on an \"AS IS\" \nBASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or \nimplied.\n\n\n * Performance\n\nThe performance characteristics of this intial JREDIS No'Rooz implementation\nare acceptable.  In developing a connector for a system such as REDIS, there\nare a few performance bottle necks which are inevitable.  Based on intial\neducated guesses and a few recent insights gained through the use of a \nprofiling tool, every attempt has been made to optimize the performance of\nthis initial revision.  Nevertheless (and thankfully), there remain many\nareas for further enhancement of the included sychronous connector (JRedis-\nClient).\n\na) Network IO\n\nThis release has a known bottleneck that can be addressed, and will be \nlikely after the work on the Asynchronous connection has reached the same \nlevel of development as the initial synchronous connection in the initial\nrelease.  While it is expected that a blocking network client would be io-\nbound to a significant degree, this is actually not that bad in this release.\n\nThe wip Asynch connection (still using stream sockets, and not yet NIO),\nhas been clocked at anywhere from 100,000 to 175,000 PING/INCRs on a single\nnon-blocking connection to a localhost REDIS.  (These are relative numbers\nbut a reference point is that the REDIS redis-bench program clocks at around\n34K/sec for the same).  The work on this was stopped to get this release\nprepared and resumption of work is a high priority as it was way too much\nfun!\n\n\nb) java.lang.String\n\nThe worst offender, and an inescapable one at that, is the String class of\nJava, as far as performance hotspots are concerned.  On one hand, it is \ngreat to have a Unicode character string implementations that allows JREDIS\nto use (as tested) Russian, Chinese, and Farsi, keys in storing information \nin REDIS, nevertheless, the performance hit of conversion of (typical) ASCII\nstrings to byte[] required for the protocol are quite annoying: \n\nGiven that String is a final class, little short of caching can be done \nabout it. (Any suggestions addressing this is greatly appreciated.) \n\n\nc) data conversion and byte shoveling.\n \nThe current implementation makes every attempt to minimize the allocation\nof byte[] buffers, and subsequent copying of bytes from one array to another,\nbut in some cases there is nothing than can be done about it. \n\nAlso, some attempts have been made to optimize conversion from numbers to\nbyte[] and back, to avoid a visit to the dreaded String.getBytes <g>. The\ncurrent (hack) solution will cost a few hundred Ks of RAM per classloader\nbut its probably worth it.\n\n\n * Documentation\n \nDocumentation is a priority item.  In the interim please refer to the java\napi docs.  If you are not familiar with the REDIS command set, you are \ncertainly encouraged to read the Command reference and get to know the\nREDIS vocabulary.  The main critical interfaces exposed by JREDIS is the\nJRedis interface which is a near analog of the redis command set.\n\nThe overall connector design itself is documented as a ~UML diagram image\ncapture.    \n  \n\n * Updates\n \nUpdates about JREDIS specification and reference implementation\nwill be posted at:\n\n   JREDIS project site:\n   http://code.google.com/p/jredis/\n\nand\n\n   REDIS Google newsgroup:\n   http://groups.google.com/group/redis-db\n\n+spontanous updates will also be posted to twitter under\n\n  http://twitter.com/SunOf27\n\n\n * Feedback\n    \nYour feedback is welcomed and appreciated.  Please direct your\nquestions, suggestion, comments, concerns, and complaints to\nthe above public forums, or directly to me @ \n\n   alphazero@sensesay.net\n\nMost specially, information regarding bugs, performance, and \nusability issues, will be highly appreciated. \n\n\n/ Enjoy!\n\n\n~ Dedicated to my lovely parents, Kiyou and Farideh. ~\n\nJoubin \n04-12-09\nFairfax Station, NoVA\n\n\n"
  },
  {
    "path": "Release/RELEASE-NOTES-Update-03122010.txt",
    "content": "Final release for Redis 1.2.n compliant clients.\n\nREQUIREMENTS CHANGES:\n\nRequires Redis server 1.2.n.  This release is NOT compatible with either Redis 1.000 or 2.n (development edge).\n\nSee: \nhttp://code.google.com/p/redis/downloads/list\n\nNEW FEATURES:\n\n* Heartbeat\n\nConnectors will launch a heartbeat thread to maintain connections.  Frequency can be set using ConnectionSpec, with default of 1/sec.\n\n* Synchronous semantics for Pipeline\n\nSee JRedisPipeline.sync().  In a nutshell, allows for mixing in synchronous semantics when using the asynchronous pipelines.  For example, you may issue a set of asynchronous commands (per JRedisFuture interface) and then use pipeline.sync() to obtain a JRedis (synchronous) interface to issue a blocking command.  See UsingJredisPipeline.exampleUseofSyncInPipeline() (in /Examples)\n\n\nBUG FIX:\n\nA few bugs were reported and have been addressed.  (Thanks to all who provided feedback.)\n\nSee: \nhttp://github.com/alphazero/jredis/issues/closed \n\nROAD MAP:\n\nDevelopment focus will be on Redis 2.n compliance in tandem with Redis edge (http://github.com/antirez/redis), and maintenance for (this) 1.2.n compliant clients. \n\n/enjoy\n\n03-12-2010\nNoVA\n\n"
  },
  {
    "path": "Release/RELEASE-NOTES-Update-08132009.txt",
    "content": "This update includes changes to the JRedis interface, as previously announced.\n\nAPI CHANGES:\n\nAs of this release update, you will need to specify the password and/or db on connect time.\nYou will no longer be able to change the selected db for a connection.\nThe default db selected on connect is db 0.  \n\nThe test suites are all positive on these changes.  (Fairly substantial changes in the internal\nconnector packages.)  That said, I have not had the time to conduct exhaustive testing beyond\nthe test suites.  If you find a bug, please report it under issues in github.  If you post to \nthe Redis newsgroup, please indicate JRedis in the subject line as I usually just skim the \nlist's subjects and may miss your feedback.  \n\nBUG FIX:\n\nPrevious releases had a bug that reconnected to db 0 on timed out connections.  Per the changes\nin this release, the automatic reconnect will connect to the Redis server using the authorization\ncredentials (if any), and, the db you specified, on the initial connection (using new JRedisClient()).\n\n\nROAD MAP:\n\nNow that we have the db select issue out of the way, the way is clear for connection pooling and \nthread safe connections. \n\nAlso, the ConnectionFactory interface of the specification may be finally brought into use to allow\nfor complete user control over the Redis and TCP connection characteristics.  (Current implementation\nrelies on a default ConnectionSpec to create its connection.)  This will potentially of use to domains\nthat require specialized settings for the buffer sizes, tcp preferences, etc.\n\nPipe-lining is also an upcoming addtion.  Frankly its been held back for no better reason other than\nmy laziness and/or other pressing issues occupying my time.  A rough implementation has been played\nwith and the performance characteristic increases are in the order of magnitude. (100,000 ops/sec vs\n30,000 for the synch clients on my machine).  Of course these are throughput measures, and not latency.\n\n/enjoy\n\n08-13-2009\nNoVA\n\n"
  },
  {
    "path": "Release/RELEASE-NOTES-Update-11082009.txt",
    "content": "This is a fairly substantial update release and the final release supporting Redis 1.000.\n\nThis update includes changes to the JRedis interface, as previously announced.\n\nREQUIREMENTS CHANGES:\n\nNot so much a change but a strict conformance to Java 5.  For whatever reasons (me?) maven\napparently had ignored the Java 1.5 directives in the build and I was blissfully unaware \nthat the project was, in fact, using Java 6 constructs (specificially the enhanced semantics\nof @Override).  Well, no more.  JRedis is now strictly 1.5.  \n\n\nAPI CHANGES:\n\n* Asynchronous semantics\n\nA new JRedisFuture interface has been introduced to provide asynchronous call interaction\nsemantics with redis.  This is the very first try at this interface and I am not specially\nhappy with the amount of angled bracket typing required to use Future<x> directly.  So \nforewarned that JRedisFuture may change (for the better) and we'll introduce new types to \nalleviate the angled bracket typing when using this interface. \n \n* spec package reorg\n\nA few interfaces were shuffled around in course of refactorings and introduction of the\nasynch semantics.  Fairly minor stuff, but it could potentially break some of your import\nstatements.\n\n\nNEW FEATURES:\n\n(See the examples project for usage details of new additions).\n\n* Pipelining\nPipelines supporting both synchronous and asynchronous call semantics are provided.  \nNew JRedisPipeline, JRedisPipelineService respectively provide Asynch and Synch access\nto redis.  Both are safe for concurrent use.\n\nNote that while this release is Redis 1.000 compliant, there was a rewrite of redis that\nchanged how pipelining was implemented on server side, and the pipelining in this release\nhas only passed unit test against Redis 1.050.\n\n* Asynchronous call semantics\nBesides the pipelines, the new JRedisAsynchClient also supports the JRedisFuture interface\nand (unlike pipelines) provides true fire and forget behaviour, with minimal latencies in\ncall completion.  Please note that unlike the pipelines (which queue pending responses \nAFTER writing the request to the remote server) the asynch client will queue your request.\nSo you can fire and forget, but you MUST remember that memory is a constrained resource\nand you can not queue more requests that your JVM can handle <g>.\n\nBUG FIX:\n\nA couple of bugs were reported since that last update and have been fixed in this release.\n\nReconnect has proven to be a can of worms and given that it is *impossible* for JRedis to \nguarantee a completely transparent reconnect without potentially resending commands without\nbecoming excessively complex (and incurring computation costs for even those who do not require\nit) the clients will reconnect but will NOT attempt to transparently resend your\ncommand.  A ClientRuntimeException will be thrown after reconnect to alert the caller that\na reconnect occured at some point during the execution of the request.  (Java sockets will\nNOT raise exceptions on write even in case of a disconnection so it is nearly impossible to\nguarantee transparent reconnect since it is unknown whether the command write actually went \nthrough or not.)\n \n\nROAD MAP:\n\nFirst up is the addtion of support for the new Redis commands, such as MSet, all the Z*s, etc.\n\nAfter that, we'll likely introduce a extensible mechanism for the user applications to spec\na server selection/distribution mechanism, with a basic hashing implementation for sharding.\n\n/enjoy\n\n11-08-2009\nNoVA\n\n"
  },
  {
    "path": "Release/RELEASE_BUILD_TIME",
    "content": "Fri Mar 12 11:19:49 EST 2010\n"
  },
  {
    "path": "core/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "core/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "core/README",
    "content": "README : JRedis Module Core\n\n----------------------------------------------------------\nBUILD\n----------------------------------------------------------\n\nFor build instructions refer to the README in root.\n\n----------------------------------------------------------\nMODULES\n----------------------------------------------------------\n\nThe Core module is composed of all the core elements that\nare used to create JRedis clients and connectors for the\nRedis server.  \n\nThis includes: \n\n- the specification (API),\n- the reference implementation (RI),\n- the benchmark module (BENCH)\n\nAn additional module ALL is a virtual module used to \ncreate a unified jar for the core.  (Its a hack of manve;\nlikely will be replaced by an assembly directive in the\nfuture.  If you are a maven guru let me know how to do it\nbetter.)\n\n* JRedis users\n\nIf you want to use JRedis clients and connectors, you'll\nonly need the classes of API and RI.  \n\nDepending on your preferences and requirements, you may\neither uses the individual jars for each module, OR,\nsimply use the jar 'with dependencies' in RI's target \ndirectory.\n\nEach module should also produce a source jar.  (See build\ninstructions.)\n\nNo javadocs are produced as of now.  (c.f. maven newbiness).\n\n**** PLEASE REFER TO UNIT TEST INFO IN ROOT README *****\n\n/end\n"
  },
  {
    "path": "core/all/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "core/all/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "core/all/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<!-- parent -->\n\t<parent>\n\t\t<groupId>org.jredis</groupId>\n\t\t<artifactId>jredis-core</artifactId>\n\t\t<version>a.0-SNAPSHOT</version>\n\t</parent>\n\n\t<!-- production | jar -->\n\t<!-- NOTE: this something of a hack and perhaps there is a standard way \n\t\tto do it in maven: the 'core-all' is an empty module that simply requires \n\t\tall the other (functional) modules of core and its production creates a jar \n\t\twith all the core classes included. (Assembly is probably what I am looking \n\t\tfor .. -->\n\n\t<name>JRedis - Core - ALL [Jar POM]</name>\n\t<groupId>org.jredis</groupId>\n\t<artifactId>jredis-core-all</artifactId>\n\t<version>a.0-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\t<dependencies>\n\t\t<!-- declare dependency on all core modules for dependency jar -->\n\t\t<!-- api -->\n\t\t<dependency>\n\t\t\t<groupId>org.jredis</groupId>\n\t\t\t<artifactId>jredis-core-api</artifactId>\n\t\t\t<version>a.0-SNAPSHOT</version>\n\t\t</dependency>\n\n\t\t<!-- ri -->\n\t\t<dependency>\n\t\t\t<groupId>org.jredis</groupId>\n\t\t\t<artifactId>jredis-core-ri</artifactId>\n\t\t\t<version>a.0-SNAPSHOT</version>\n\t\t</dependency>\n\n\t\t<!-- bench -->\n\t\t<dependency>\n\t\t\t<groupId>org.jredis</groupId>\n\t\t\t<artifactId>jredis-core-bench</artifactId>\n\t\t\t<version>a.0-SNAPSHOT</version>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-assembly-plugin</artifactId>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>simple-install</id>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>attached</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t\t<configuration>\n\t\t\t\t\t<descriptorRefs>\n\t\t\t\t\t\t<descriptorRef>jar-with-dependencies</descriptorRef>\n\t\t\t\t\t</descriptorRefs>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n</project>\n"
  },
  {
    "path": "core/api/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "core/api/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "core/api/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<!-- parent -->\n\t<parent>\n\t\t<groupId>org.jredis</groupId>\n\t\t<artifactId>jredis-core</artifactId>\n\t\t<version>a.0-SNAPSHOT</version>\n\t</parent>\n\n\t<!-- production | jar -->\n\t<name>JRedis - Core - API</name>\n\t<groupId>org.jredis</groupId>\n\t<artifactId>jredis-core-api</artifactId>\n\t<version>a.0-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\n\t<dependencies>\n\t\t<!-- unit testing -->\n\t\t<dependency>\n\t\t\t<groupId>org.testng</groupId>\n\t\t\t<artifactId>testng</artifactId>\n\t\t\t<version>7.7.0</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t\t<!-- logging -->\n\t\t<dependency>\n\t\t\t<groupId>log4j</groupId>\n\t\t\t<artifactId>log4j</artifactId>\n\t\t\t<version>1.2.12</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>commons-logging</groupId>\n\t\t\t<artifactId>commons-logging</artifactId>\n\t\t\t<version>1.1.1</version>\n\t\t</dependency>\n\t</dependencies>\n\n</project>\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/ClientRuntimeException.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n\n/**\n * Base class for all non-Redis exceptions relating to client runtime.  Implementations\n * must only throw this type of exception when the problem(s) encountered are neither Redis usage errors, nor \n * unexpected code segment execution.\n * <p>\n * For example, failure to establish a connection, or losing the connection, should raise this type of exception.  But\n * encountering parse errors in Redis responses streams is a bug and should be noted by raising a {@link ProviderException}.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic class ClientRuntimeException extends RuntimeException {\n\n\t/**  */\n\tprivate static final long\tserialVersionUID\t= _specification.Version.major;\n\t\n\t/**\n\t * @param message\n\t */\n\tpublic ClientRuntimeException(String message) {\n\t\tsuper (message);\n\t}\n\n\t/**\n\t * @param message\n\t * @param cause\n\t */\n\tpublic ClientRuntimeException(String message, Throwable cause) {\n\t\tsuper(message, cause);\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t//\tSuper overrides\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc)\n\t * @see java.lang.Throwable#getLocalizedMessage()\n\t */\n\t@Override\n    final public String getLocalizedMessage () {\n\t\treturn this.getMessage();\n    }\n\n\t/* (non-Javadoc)\n\t * @see java.lang.Throwable#getMessage()\n\t */\n\t@Override\n    final public String getMessage () {\n\t\tStringBuffer buff = new StringBuffer();\n\t\t\n\t\tString message = super.getMessage();\n\t\tif(null == message) buff.append(\"[BUG: null message]\");\n\t\telse buff.append(message);\n\t\t\n\t\tThrowable cause = getCause();\n\t\tif(null != cause) buff.append(\" cause: => [\").append(cause.getClass().getSimpleName()).append(\": \").append(cause.getMessage()).append(\"]\");\n\t\t\n\t\treturn buff.toString();\n    }\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/Codec.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n\n\n/**\n * Defines the necessary methods for a Java type encoder-decoder.  Implementations of this\n * interface can be registered with a {@link CodecManager} used by a {@link JRedis} implementation\n * (whether per instance or by other relations per JRedis provider implementation), and used\n * during the encoding of an semantic java type into {@link byte[]} and back.  \n *\n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, Apr 14, 2009\n * @since   alpha.0\n * \n */\n\npublic interface Codec <T extends Object>  {\n\t/**\n\t * @param bytes\n\t * @return an instance of type <code>T</code> corresponding to the value of decoded <code>bytes</code>\n\t */\n\tpublic T decode (byte[] bytes);\n\t/**\n\t * @param object\n\t * @return\n\t */\n\tpublic byte[] encode (T object);\n\t/**\n\t * @param type\n\t * @return whether this codec supports the (en/de)coding of the type <code>T</code>\n\t */\n\tpublic boolean supports (Class<?> type);\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/Event.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.io.Serializable;\nimport java.lang.ref.WeakReference;\n\n/**\n * Generic Event class for JRedis and sub-modules.\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Mar 29, 2010\n * @since   alpha.0\n * \n * @param <SRC>\n * @param <ETYPE>\n * @param <INFO>\n */\npublic class Event <SRC, ETYPE, INFO> implements Serializable{\n\t/**  */\n    private static final long serialVersionUID = 1L;\n    \n\t/**  */\n\tprivate final ETYPE type;\n\t/**  */\n\tprivate transient WeakReference<SRC> srcRef;\n\t/**  */\n\tprivate final INFO info;\n\t\n\t/**\n\t * @param src\n\t * @param eType\n\t * @param info\n\t */\n\tprotected Event(SRC src, ETYPE eType, INFO info){\n\t\tthis.type = eType;\n\t\tthis.srcRef = new WeakReference<SRC>(src);\n\t\tthis.info = info;\n\t}\n\t/**\n\t * @param src\n\t * @param eType\n\t */\n\tprotected Event(SRC src, ETYPE eType){\n\t\tthis(src, eType, null);\n\t}\n\t/**\n\t * @return\n\t */\n\tpublic ETYPE getType () {\n    \treturn type;\n    }\n\t/**\n\t * @return\n\t */\n\tpublic SRC getSource () {\n    \treturn srcRef.get();\n    }\n\t/**\n\t * @return\n\t */\n\tpublic INFO getInfo () {\n    \treturn info;\n    }\n\n\tprivate void writeObject(ObjectOutputStream out) throws IOException {\n\t\tout.defaultWriteObject();\n\t\tout.writeObject(srcRef.get());\n\t}\n\n\t@SuppressWarnings(\"unchecked\")\n\tprivate void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {\n\t\tin.defaultReadObject();\n\t\tsrcRef = new WeakReference<SRC>((SRC)in.readObject());\n\t}\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/JRedis.java",
    "content": "/*\n *   Copyright 2009-2011 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.io.Serializable;\nimport java.util.List;\nimport java.util.Map;\n\n\n/**\n * <p>This is effectively a one to one mapping to Redis commands.  And that\n * is basically it.\n * <p>Beyond that , just be aware that an implementation may throw {@link ClientRuntimeException}\n * or an extension to report problems (typically connectivity) or features {@link NotSupportedException}\n * or bugs.  These are {@link RuntimeException}.\n * \n * @author  joubin (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\n@Redis(versions=\"1.07\")\npublic interface JRedis {\n\t\n\t// ------------------------------------------------------------------------\n\t// Semantic context methods\n\t// ------------------------------------------------------------------------\n\n\t// TODO: reach a decision on whether to include this or not.\n//\t/**\n//\t * Provides for access to an interface providing standard Java collections\n//\t * semantics on the specified parametric type.  \n//\t * <p>\n//\t * The type <code>T</code> can be of 3 categories:\n//\t * <ol>\n//\t * <li>It is \n//\t * </ol>\n//\t * @param <T> a Java class type that you wish to perform {@link Set}, \n//\t * {@link List}, or {@link Map}, operations. \n//\t * @return the {@link JavaSemantics} for type <code>T</code>, if the type specified meets\n//\t * the required initialization characteristics.\n//\t */\n//\tpublic <K extends Object, T> JavaSemantics<T>  semantic (Class<T>  type) throws ClientRuntimeException;\n\t\n\t// ------------------------------------------------------------------------\n\t// Security and User Management\n\t// NOTE: Moved to ConnectionSpec\n\t// ------------------------------------------------------------------------\n\n\t\n\t// ------------------------------------------------------------------------\n\t// \"Connection Handling\"\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Ping redis\n\t * @return true (unless not authorized)\n\t * @throws RedisException (as of ver. 0.09) in case of unauthorized access\n\t */\n\tpublic <K extends Object> JRedis ping () throws RedisException;\n\n\t/**\n\t * Disconnects the client.\n\t * @Redis QUIT\n\t */\n\tpublic <K extends Object> void quit ();\n\t\n\t// ------------------------------------------------------------------------\n\t// \"Commands operating on string values\"\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Bind the value to key.  \n\t * @Redis SET\n\t * @param key any UTF-8 {@link String}\n\t * @param value any bytes.  For current data size limitations, refer to\n\t * Redis documentation.\n\t * @throws RedisException on user error.\n\t * @throws ProviderException on un-documented features/bug\n\t * @throws ClientRuntimeException on errors due to operating environment (Redis or network)\n\t */\n\tpublic <K extends Object> void set (K key, byte[] value) throws RedisException;\n\t/**\n\t * Convenient method for {@link String} data binding\n\t * @Redis SET\n\t * @param key\n\t * @param stringValue\n\t * @throws RedisException\n\t * @see {@link JRedis#set(String, byte[])}\n\t */\n\tpublic <K extends Object> void set (K key, String stringValue) throws RedisException;\n\t/**\n\t * Convenient method for {@link String} numeric values binding\n\t * @Redis SET\n\t * @param key\n\t * @param numberValue\n\t * @throws RedisException\n\t * @see {@link JRedis#set(String, byte[])}\n\t */\n\tpublic <K extends Object> void set (K key, Number numberValue) throws RedisException;\n\t/**\n\t * Binds the given java {@link Object} to the key.  Serialization format is\n\t * implementation specific.  Simple implementations may apply the basic {@link Serializable}\n\t * protocol.\n\t * @Redis SET\n\t * @param <T>\n\t * @param key\n\t * @param object\n\t * @throws RedisException\n\t * @see {@link JRedis#set(String, byte[])}\n\t */\n\tpublic <K extends Object, T extends Serializable> \n\t\t   void set (K key, T object) throws RedisException;\n\n\t/**\n\t * @Redis SETNX\n\t * @param key\n\t * @param value\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean setnx (K key, byte[] value) throws RedisException;\n\tpublic <K extends Object> boolean setnx (K key, String stringValue) throws RedisException;\n\tpublic <K extends Object> boolean setnx (K key, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   boolean setnx (K key, T object) throws RedisException;\n\n\t/**\n\t * @Redis GET\n\t * @param key\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] get (K key)  throws RedisException;\n\n\tpublic <K extends Object> byte[] getset (K key, byte[] value) throws RedisException;\n\tpublic <K extends Object> byte[] getset (K key, String stringValue) throws RedisException;\n\tpublic <K extends Object> byte[] getset (K key, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\tbyte[] getset (K key, T object) throws RedisException;\n\n\t\n\t/**\n\t * @Redis MGET\n\t * @param key\n\t * @param moreKeys\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> mget(K...keys) throws RedisException;\n\n\t/**\n\t * @Redis MSET\n\t * @param keyValueMap a {@link Map}ping of {@link String} key names to byte[] values.\n\t * @return \n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void mset(Map<K, byte[]> keyValueMap) throws RedisException;\n\t\n\tpublic <K extends Object> void mset(KeyValueSet.ByteArrays<K> mappings) throws RedisException;\n\tpublic <K extends Object> void mset(KeyValueSet.Strings<K> mappings) throws RedisException;\n\tpublic <K extends Object> void mset(KeyValueSet.Numbers<K> mappings) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> void mset(KeyValueSet.Objects<K, T> mappings) throws RedisException;\n\t\n\t/**\n\t * @Redis MSETNX\n\t * @param keyValueMap a {@link Map}ping of {@link String} key names to byte[] values.\n\t * @return false if ANY of the keys in the map already existed, true if all were new and were set.\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean msetnx(Map<K, byte[]> keyValueMap) throws RedisException;\n\t\n\tpublic <K extends Object> boolean msetnx(KeyValueSet.ByteArrays<K> mappings) throws RedisException;\n\tpublic <K extends Object> boolean msetnx(KeyValueSet.Strings<K> mappings) throws RedisException;\n\tpublic <K extends Object> boolean msetnx(KeyValueSet.Numbers<K> mappings) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> boolean msetnx(KeyValueSet.Objects<K, T> mappings) throws RedisException;\n\t\n\t/**\n\t * @Redis INCR\n\t * @param key\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long incr (K key) throws RedisException;\n\n\t/**\n\t * @Redis INCRBY\n\t * @param key\n\t * @param delta\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long incrby (K key, int delta) throws RedisException;\n\n\t/**\n\t * @Redis DECR\n\t * @param key\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long decr (K key) throws RedisException;\n\n\t/**\n\t * @Redis DECRBY\n\t * @param key\n\t * @param delta\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long decrby (K key, int delta) throws RedisException;\n\n\t/**\n\t * @Redis SUBSTR\n\t * @param key\n\t * @param from\n\t * @param to\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] substr (K key, long from, long to) throws RedisException;\n\t\n\t\n\t/**\n\t * @Redis APPEND\n\t * @param key\n\t * @param value\n\t * @return length (byte count) of appended value\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long append (K key, byte[] value) throws RedisException;\n\tpublic <K extends Object> long append (K key, String stringValue) throws RedisException;\n\tpublic <K extends Object> long append (K key, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   long append (K key, T object) throws RedisException;\n\n\t// ------------------------------------------------------------------------\n\t// \"Commands operating on the key space\"\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis EXISTS\n\t * @param key\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean exists(K key) throws RedisException;\n\n\t/**\n\t * @Redis DEL\n\t * @param keys one or more non-null, non-zero-length, keys to be deleted\n\t * @return number of keys actually deleted\n\t * @throws RedisException\n\t */\n//\tpublic <K extends Object> boolean del (K key) throws RedisException;\n\tpublic <K extends Object> long del (K ... keys) throws RedisException;\n\n\t/**\n\t * @Redis TYPE\n\t * @param key\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> RedisType type (K key) throws RedisException;\n\t\n\t\n\t/**\n\t * @Redis KEYS\n\t * @param pattern\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> keys (K pattern) throws RedisException;\n\t\n\t/**\n\t * Convenience method.  Equivalent to calling <code>jredis.keys(\"*\");</code>\n\t * @Redis KEYS\n\t * @return\n\t * @throws RedisException\n\t * @see {@link JRedis#keys(String)}\n\t */\n\tpublic <K extends Object> List<byte[]> keys () throws RedisException;\n\n\t/**\n\t * @Redis RANDOMKEY\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic byte[] randomkey() throws RedisException;\n\t\n\t/**\n\t * @Redis RENAME\n\t * @param oldkey\n\t * @param newkey\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void rename (K oldkey, K newkey) throws RedisException;\n\t\n\t/**\n\t * @Redis RENAMENX\n\t * @param oldkey\n\t * @param brandnewkey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean renamenx (K oldkey, K brandnewkey) throws RedisException;\n\t\n\t/**\n\t * @Redis DBSIZE\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long dbsize () throws RedisException;\n\t\n\t/**\n\t * @Redis EXPIRE\n\t * @param key\n\t * @param ttlseconds\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean expire (K key, int ttlseconds) throws RedisException; \n\t\n\t/**\n\t * \n\t * @Redis EXPIREAT\n\t * @param key\n\t * @param UNIX epoch-time in <b>milliseconds</b>.  Note that Redis expects epochtime\n\t * in seconds. Implementations are responsible for converting to seconds.\n\t * method   \n\t * @return\n\t * @throws RedisException\n\t * @see {@link System#currentTimeMillis()}\n\t */\n\tpublic <K extends Object> boolean expireat (K key, long epochtimeMillisecs) throws RedisException; \n\t\n\t/**\n\t * @Redis TTL\n\t * @param key\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long ttl (K key) throws RedisException;\n\t\n\t// ------------------------------------------------------------------------\n\t// Commands operating on lists\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * @Redis RPUSH\n\t * @param listkey\n\t * @param value\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void rpush (K listkey, byte[] value) throws RedisException;\n\tpublic <K extends Object> void rpush (K listkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> void rpush (K listkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   void rpush (K listkey, T object) throws RedisException;\n\t\n\t/**\n\t * @Redis LPUSH\n\t * @param listkey\n\t * @param value\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void lpush (K listkey, byte[] value) throws RedisException;\n\tpublic <K extends Object> void lpush (K listkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> void lpush (K listkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   void lpush (K listkey, T object) throws RedisException;\n\t\n\t/**\n\t * @Redis LSET\n\t * @param key\n\t * @param index\n\t * @param value\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void lset (K key, long index, byte[] value) throws RedisException;\n\tpublic <K extends Object> void lset (K key, long index, String stringValue) throws RedisException;\n\tpublic <K extends Object> void lset (K key, long index, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   void lset (K key, long index, T object) throws RedisException;\n\t\n\n\t/**\n\t * @Redis LREM\n\t * @param listKey\n\t * @param value\n\t * @param count\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long lrem (K listkey, byte[] value,       int count) throws RedisException;\n\tpublic <K extends Object> long lrem (K listkey, String stringValue, int count) throws RedisException;\n\tpublic <K extends Object> long lrem (K listkey, Number numberValue, int count) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   long lrem (K listkey, T object, int count) throws RedisException;\n\t\n\t/**\n\t * Given a 'list' key, returns the number of items in the list.\n\t * @Redis LLEN\n\t * @param listkey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long llen (K listkey) throws RedisException;\n\t\n\t/**\n\t * @Redis LRANGE\n\t * @param listkey\n\t * @param from\n\t * @param to\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> lrange (K listkey, long from, long to) throws RedisException; \n\n\t/**\n\t * @Redis LTRIM\n\t * @param listkey\n\t * @param keepFrom\n\t * @param keepTo\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void ltrim (K listkey, long keepFrom, long keepTo) throws RedisException;\n\t\n\t/**\n\t * @Redis LINDEX\n\t * @param listkey\n\t * @param index\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] lindex (K listkey, long index) throws RedisException;\n\t\n\t/**\n\t * @Redis LPOP\n\t * @param listKey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] lpop (K listkey) throws RedisException;\n\t\n\t/**\n\t * @Redis RPOP\n\t * @param listKey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] rpop (K listkey) throws RedisException;\n\n\t/**\n\t * @Redis RPOPLPUSH\n\t * @param srcList\n\t * @param destList\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] rpoplpush (K srcList, K destList) throws RedisException;\n\n\t// ------------------------------------------------------------------------\n\t// Commands operating on sets\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis SADD\n\t * @param setkey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean sadd (K setkey, byte[] member) throws RedisException;\n\tpublic <K extends Object> boolean sadd (K setkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> boolean sadd (K setkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   boolean sadd (K setkey, T object) throws RedisException;\n\n\t/**\n\t * @Redis SREM\n\t * @param setKey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean srem (K setkey, byte[] member) throws RedisException;\n\tpublic <K extends Object> boolean srem (K setkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> boolean srem (K setkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   boolean srem (K setkey, T object) throws RedisException;\n\n\t/**\n\t * @Redis SISMEMBER\n\t * @param setKey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean sismember (K setkey, byte[] member) throws RedisException;\n\tpublic <K extends Object> boolean sismember (K setkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> boolean sismember (K setkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   boolean sismember (K setkey, T object) throws RedisException;\n\t\n\t/**\n\t * @Redis SMOVE\n\t * @param srcKey\n\t * @param destKey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean smove (K srcKey, K destKey, byte[] member) throws RedisException;\n\tpublic <K extends Object> boolean smove (K srcKey, K destKey, String stringValue) throws RedisException;\n\tpublic <K extends Object> boolean smove (K srcKey, K destKey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   boolean smove (K srcKey, K destKey, T object) throws RedisException;\n\t\n\t/**\n\t * @Redis SCARD\n\t * @param setKey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long scard (K setKey) throws RedisException;\t\n\t\n\t/**\n\t * @Redis SINTER\n\t * @param set1\n\t * @param sets\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> sinter (K set1, K...sets) throws RedisException;\n\t/**\n\t * @Redis SINTERSTORE\n\t * @param destSetKey\n\t * @param sets\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void sinterstore (K destSetKey, K...sets) throws RedisException;\n\n\t/**\n\t * @Redis SUNION\n\t * @param set1\n\t * @param sets\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> sunion (K set1, K...sets) throws RedisException;\n\t\n\t/**\n\t * @Redis SUNIONSTORE\n\t * @param destSetKey\n\t * @param sets\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void sunionstore (K destSetKey, K...sets) throws RedisException;\n\n\t/**\n\t * @Redis SDIFF\n\t * @param set1\n\t * @param sets\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> sdiff (K set1, K...sets) throws RedisException;\n\t\n\t/**\n\t * @Redis SDIFFSTORE\n\t * @param destSetKey\n\t * @param sets\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void sdiffstore (K destSetKey, K...sets) throws RedisException;\n\n\t/**\n\t * @Redis SMEMBERS\n\t * @param setkey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> smembers (K setKey) throws RedisException;\n\t\n\t/**\n\t * @Redis SRANDMEMBER\n\t * @param setkey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] srandmember (K setKey) throws RedisException;\n\t\n\t/**\n\t * @Redis SPOP\n\t * @param setkey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] spop (K setKey) throws RedisException;\n\t// ------------------------------------------------------------------------\n\t// Commands operating on sets\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis ZADD\n\t * @param setkey\n\t * @param score\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean zadd (K setkey, double score, byte[] member) throws RedisException;\n\tpublic <K extends Object> boolean zadd (K setkey, double score, String stringValue) throws RedisException;\n\tpublic <K extends Object> boolean zadd (K setkey, double score, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   boolean zadd (K setkey, double score, T object) throws RedisException;\n\n\t/**\n\t * @Redis ZREM\n\t * @param setKey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean zrem (K setkey, byte[] member) throws RedisException;\n\tpublic <K extends Object> boolean zrem (K setkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> boolean zrem (K setkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\t   boolean zrem (K setkey, T object) throws RedisException;\n\t\n\t/**\n\t * @Redis ZCARD\n\t * @param setKey\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long zcard (K setKey) throws RedisException;\t\n\t\n\t\n\t/**\n\t * @Redis ZSCORE\n\t * @param setkey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> Double zscore (K setkey, byte[] member) throws RedisException;\n\tpublic <K extends Object> Double zscore (K setkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> Double zscore (K setkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\tDouble zscore (K setkey, T object) throws RedisException;\n\n\t/**\n\t * @Redis ZRANK\n\t * @param setkey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long zrank (K setkey, byte[] member) throws RedisException;\n\tpublic <K extends Object> long zrank (K setkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> long zrank (K setkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\tlong zrank (K setkey, T object) throws RedisException;\n\n\t/**\n\t * @Redis ZREVRANK\n\t * @param setkey\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long zrevrank (K setkey, byte[] member) throws RedisException;\n\tpublic <K extends Object> long zrevrank (K setkey, String stringValue) throws RedisException;\n\tpublic <K extends Object> long zrevrank (K setkey, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\tlong zrevrank (K setkey, T object) throws RedisException;\n\n\t/**\n\t * @Redis ZRANGE\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> zrange (K setkey, long from, long to) throws RedisException; \n\n\t/**\n\t * @Redis ZREVRANGE\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> zrevrange (K setkey, long from, long to) throws RedisException; \n\n\t/**\n\t * Equivalent to {@link JRedis#zrange(String, long, long)} with the {@link Option.Options#WITHSCORES}.\n\t * Unlike the general ZRANGE command that only returns the values, this method returns both\n\t * values and associated scores for the specified range.\n\t *  \n\t * @Redis ZRANGE ... WITHSCORES\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return the subset of the specified set \n\t * @throws RedisException\n\t * @see JRedis#zrange(String, long, long)\n\t * @see ZSetEntry\n\t */\n\tpublic <K extends Object> List<ZSetEntry> zrangeSubset (K setkey, long from, long to) throws RedisException; \n\n\t/**\n\t * Equivalent to {@link JRedis#zrevrange(String, long, long)} with the {@link Option.Options#WITHSCORES}.\n\t * Unlike the general ZREVRANGE command that only returns the values, this method returns both\n\t * values and associated scores for the specified range.\n\t *  \n\t * @Redis ZREVRANGE ... WITHSCORES\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return the subset of the specified set \n\t * @throws RedisException\n\t * @see JRedis#zrevrange(String, long, long)\n\t * @see ZSetEntry\n\t */\n\tpublic <K extends Object> List<ZSetEntry> zrevrangeSubset (K setkey, long from, long to) throws RedisException; \n\n\t/**\n\t * @Redis ZRANGE\n\t * @param setkey\n\t * @param minScore\n\t * @param maxScore\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<byte[]> zrangebyscore (K setkey, double minScore, double maxScore) throws RedisException; \n\n\t/**\n\t * @Redis ZRANGEBYSCORE ... WITHSCORES\n\t * @param setkey\n\t * @param minScore\n\t * @param maxScore\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> List<ZSetEntry> zrangebyscoreSubset (K setkey, double minScore, double maxScore) throws RedisException;\n\n\t/**\n\t * @Redis ZREMRANGEBYSCORE\n\t * @param setkey\n\t * @param minScore\n\t * @param maxScore\n\t * @return number of removed elements\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long zremrangebyscore (K setkey, double minScore, double maxScore) throws RedisException; \n\n\t/**\n\t * @Redis ZREMRANGEBYRANK\n\t * @param setkey\n\t * @param minRank\n\t * @param maxRank\n\t * @return number of removed elements\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long zremrangebyrank (K setkey, long minRank, long maxRank) throws RedisException; \n\n\t/**\n\t * @Redis ZINCRBY\n\t * @param setkey\n\t * @param score\n\t * @param member\n\t * @return\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.07\")\n\tpublic <K extends Object> Double zincrby (K setkey, double score, byte[] member) throws RedisException;\n\tpublic <K extends Object> Double zincrby (K setkey, double score, String stringValue) throws RedisException;\n\tpublic <K extends Object> Double zincrby (K setkey, double score, Number numberValue) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\tDouble zincrby (K setkey, double score, T object) throws RedisException;\n\n\t/**\n\t * @Redis ZCOUNT\n\t * @param setkey\n\t * @param minScore\n\t * @param maxScore\n\t * @return count of set members with score in the given range.\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long zcount (K setkey, double minScore, double maxScore) throws RedisException; \n\t// ------------------------------------------------------------------------\n\t// Commands operating on hashes\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis HSET\n\t * @param key\n\t * @param field\n\t * @param value\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> boolean hset(K key, K field, byte[] value)  throws RedisException;\n\t\n\t/**\n\t * @Redis HSET\n\t * @param key\n\t * @param field\n\t * @param string\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> boolean hset(K key, K field, String string)  throws RedisException;\n\t\n\t/**\n\t * @Redis HSET\n\t * @param key\n\t * @param field\n\t * @param number\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> boolean hset(K key, K field, Number number)  throws RedisException;\n\t\n\t/**\n\t * @Redis HSET\n\t * @param <T>\n\t * @param key\n\t * @param field\n\t * @param object\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.4\")\n\tpublic <K extends Object, T extends Serializable> \n\t\tboolean hset(K key, K field, T object)  throws RedisException;\n\t\n\t/**\n\t * @Redis HGET\n\t * @param key\n\t * @param field\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.4\")\n\tpublic <K extends Object> byte[] hget(K key, K field)  throws RedisException;\n\t\n\t\n\t/**\n\t * \n\t * @Redis HEXISTS\n\t * @param key\n\t * @param field\n\t * @return true if the spec'd field exists for the spec'd (hash type) key\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> boolean hexists(K key, K field)  throws RedisException;\n\t\n\t/**\n\t * \n\t * @Redis HDEL\n\t * @param key\n\t * @param field\n\t * @return true if the spec'd field exists for the spec'd (hash type) key\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> boolean hdel(K key, K field)  throws RedisException;\n\t\n\t/**\n\t * \n\t * @Redis HLEN\n\t * @param key\n\t * @return # of fields/entries in the given hashtable.\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> long hlen(K key)  throws RedisException;\n\t\n\t/**\n\t * \n\t * @Redis HKEYS\n\t * @param key\n\t * @return list of keys in the given hashtable.\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> List<byte[]> hkeys(K key)  throws RedisException;\n\t\n\t/**\n\t * \n\t * @Redis HVALS\n\t * @param key\n\t * @return list of values in the given hashtable.\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> List<byte[]> hvals(K key)  throws RedisException;\n\t\n\t/**\n\t * \n\t * @Redis HGETALL\n\t * @param key\n\t * @return the given hash as a Map<String, byte[]>\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> Map<byte[], byte[]> hgetall(K key)  throws RedisException;\n\t\n\t// ------------------------------------------------------------------------\n\t// Transactional commands\n\t// ------------------------------------------------------------------------\n\t/**\n\t * one option is to return a subclass of JRedis (e.g. JRedisCommandSequence)\n\t * and have that interface declare discard and multi.  Benefit is being able\n\t * to associate state with the transaction.\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"2.0\")\n\tpublic <K extends Object> JRedis multi() throws RedisException;\n\t/**\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"2.0\")\n\tpublic <K extends Object> JRedis discard () throws RedisException;\n\t\n\t// ------------------------------------------------------------------------\n\t// Multiple databases handling commands\n\t// ------------------------------------------------------------------------\n\t\n//\t@Deprecated\n//\tpublic <K extends Object> JRedis select (int index) throws RedisException;\n\n\t/**\n\t * Flushes the db you selected when connecting to Redis server.  Typically,\n\t * implementations will select db 0 on connecting if non was specified.  Remember\n\t * that there is no roll-back.\n\t * @Redis FLUSHDB\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> JRedis flushdb () throws RedisException;\n\n\t/**\n\t * Flushes all dbs in the connect Redis server, regardless of which db was selected\n\t * on connect time.  Remember that there is no rollback.\n\t * @Redis FLUSHALL\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> JRedis flushall () throws RedisException;\n\n\t/**\n\t * Moves the given key from the currently selected db to the one indicated\n\t * by <code>dbIndex</code>.\n\t * @Redis MOVE\n\t * @param key\n\t * @param dbIndex\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> boolean move (K key, int dbIndex) throws RedisException;\n\t\n\t// ------------------------------------------------------------------------\n\t// Sorting\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * Usage:\n\t * <p>Usage:\n\t * <p><code><pre>\n\t * List<byte[]>  results = redis.sort(\"my-list-or-set-key\").BY(\"weight*\").LIMIT(1, 11).GET(\"object*\").DESC().ALPHA().exec();\n\t * for(byte[] item : results) {\n\t *     // do something with item ..\n\t *  }\n\t * </pre></code>\n\t * <p>Sort specification elements are all options.  You could simply say:\n\t * <p><code><pre>\n\t * List<byte[]>  results = redis.sort(\"my-list-or-set-key\").exec();\n\t * for(byte[] item : results) {\n\t *     // do something with item ..\n\t *  }\n\t * </pre></code>\n\t * <p>Sort specification elements are also can appear in any order -- the client implementation will send them to the server\n\t * in the order expected by the protocol, although it is good form to specify the predicates in natural order:\n\t * <p><code><pre>\n\t * List<byte[]>  results = redis.sort(\"my-list-or-set-key\").GET(\"object*\").DESC().ALPHA().BY(\"weight*\").LIMIT(1, 11).exec();\n\t * for(byte[] item : results) {\n\t *     // do something with item ..\n\t *  }\n\t * </pre></code>\n\t * \n\t * @Redis SORT\n\t */\n\tpublic <K extends Object> Sort sort(K key);\n\t\n\t// ------------------------------------------------------------------------\n\t// Persistence control commands\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * @Redis SAVE\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void save() throws RedisException;\n\n\t/**\n\t * @Redis BGSAVE\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> void bgsave () throws RedisException;\n\n\t/**\n\t * @Redis BGREWRITEAOF\n\t * @return ack message.  \n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> String bgrewriteaof () throws RedisException;\n\n\t/**\n\t * @Redis LASTSAVE\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> long lastsave () throws RedisException;\n\n//\t@Deprecated\n//\tpublic <K extends Object> void shutdown () throws RedisException;\n\n// ------------------------------------------------------------------------\n// Remote server control commands\n// ------------------------------------------------------------------------\n\n\t/**\n\t * @Redis INFO\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> Map<String, String>\tinfo ()  throws RedisException;\n\t\n\t/**\n\t * @Redis SLAVEOF\n\t * @param host ip address \n\t * @param port\n\t */\n\tpublic <K extends Object> void slaveof(String host, int port) throws RedisException;\n\t\n\t/**\n\t * Convenience method.  Turns off replication.\n\t * @Redis SLAVEOF \"no one\"\n\t */\n\tpublic <K extends Object> void slaveofnone() throws RedisException;\n\t\n\t// ------------------------------------------------------------------------\n\t// Diagnostics commands\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis ECHO\n\t * @param msg\n\t * @return\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> byte[] echo (byte[] msg) throws RedisException;\n\tpublic <K extends Object> byte[] echo (String msg) throws RedisException;\n\tpublic <K extends Object> byte[] echo (Number msg) throws RedisException;\n\tpublic <K extends Object, T extends Serializable> \n\t\tbyte[] echo (T msg) throws RedisException;\n\t\n\t/**\n\t * @Redis DEBUG OBJECT <key>\n\t * @param key\n\t * @return\n\t * @throws RedisException\n\t * @see {@link ObjectInfo}\n\t */\n\tpublic <K extends Object> ObjectInfo debug (K key) throws RedisException;\n\t\n\tpublic <K extends Object> boolean setbit(K key, int offset, boolean value) throws RedisException;\n\n\tpublic <K extends Object> boolean getbit(K key, int offset) throws RedisException;\n\t\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/JRedisFuture.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.io.Serializable;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.protocol.ResponseStatus;\n\n\n/**\n * The asynchronous interface to Redis.\n * <p>\n * This is effectively a one to one mapping to Redis commands.  Depending on the implementation\n * either the redis response and/or redis write are asynchronous.  Regardless, each method returns\n * an extension of {@link Future} and the returned results conforms to the contract of that interface (which\n * you should review).\n * <p>\n * If your request results in a {@link RedisException}, the call to {@link Future#get()} (of either flavor)\n * will raise a {@link ExecutionException} with {@link ExecutionException#getCause()} returning the underlying\n * {@link RedisException}.\n * <p>\n * Similarly, if the request results in either {@link ClientRuntimeException} or {@link ProviderException}, the\n * {@link Future}'s {@link ExecutionException} will wrap these as the cause.\n * <p>\n * Beyond that , just be aware that an implementation may throw {@link ClientRuntimeException}\n * or an extension to report problems (typically connectivity) or {@link ProviderException}\n * (to highlight implementation features/bugs).  \n * These are {@link RuntimeException} that have been encountered while trying to queue your request.\n * <p>\n * <b>Note</b> that this interface provides no guarantees whatsoever regarding the execution of your requests beyond\n * the strict ordering of the requests per your invocations.  Specifically, in the event of connection issues, this\n * interface's contract does not place any requirements on the implementation beyond to notify the user of such issues\n * either during a call to this interface, or, on the attempt to get the result of a pending response on {@link Future#get()}.\n * Refer to the documentation of the implementation of {@link JRedisFuture} for the specifics of behavior in context of\n * errors. \n * \n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\n@Redis(versions=\"1.07\")\npublic interface JRedisFuture {\n\t\n\t// ------------------------------------------------------------------------\n\t// \"Connection Handling\"\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Ping redis\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> ping ();\n\n\t/**\n\t * Disconnects the client.\n\t * @Redis QUIT\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> quit ();\n\t\n\t/**\n\t * Optional connection control command. \n\t * @param <K>\n\t * @return\n\t */\n\tpublic Future<ResponseStatus> flush ();\n\t\n\t// ------------------------------------------------------------------------\n\t// \"Commands operating on string values\"\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Bind the value to key.  \n\t * @Redis SET\n\t * @param key any UTF-8 {@link String}\n\t * @param value any bytes.  For current data size limitations, refer to\n\t * Redis documentation.\n\t * @throws ProviderException on un-documented features/bug\n\t * @throws ClientRuntimeException on errors due to operating environment (Redis or network)\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> set (K key, byte[] value);\n\t/**\n\t * Convenient method for {@link String} data binding\n\t * @Redis SET\n\t * @param key\n\t * @param stringValue\n\t * @see {@link JRedis#set(String, byte[])}\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> set (K key, String stringValue);\n\t/**\n\t * Convenient method for {@link String} numeric values binding\n\t * @Redis SET\n\t * @param key\n\t * @param numberValue\n\t * @see {@link JRedis#set(String, byte[])}\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> set (K key, Number numberValue);\n\t/**\n\t * Binds the given java {@link Object} to the key.  Serialization format is\n\t * implementation specific.  Simple implementations may apply the basic {@link Serializable}\n\t * protocol.\n\t * @Redis SET\n\t * @param <T>\n\t * @param key\n\t * @param object\n\t * @see {@link JRedis#set(String, byte[])}\n\t */\n\tpublic <K extends Object, T extends Serializable> \n\t\t   Future<ResponseStatus> set (K key, T object);\n\n\t/**\n\t * @Redis SETNX\n\t * @param key\n\t * @param value\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> setnx (K key, byte[] value);\n\tpublic <K extends Object> Future<Boolean> setnx (K key, String stringValue);\n\tpublic <K extends Object> Future<Boolean> setnx (K key, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\t   Future<Boolean> setnx (K key, T object);\n\n\tpublic <K extends Object> Future<Boolean> setbit(K key, int offset, boolean value);\n\n\n\t\n\t/**\n\t * @Redis GET\n\t * @param key\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> get (K key) ;\n\n\tpublic <K extends Object> Future<byte[]> getset (K key, byte[] value);\n\tpublic <K extends Object> Future<byte[]> getset (K key, String stringValue);\n\tpublic <K extends Object> Future<byte[]> getset (K key, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<byte[]> getset (K key, T object);\n\n\n\tpublic <K extends Object> Future<Boolean> getbit(K key, int offset);\n\n\t\t\n\t/**\n\t * @Redis MGET\n\t * @param key\n\t * @param moreKeys\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> mget(String ... keys);\n\n\t/**\n\t * @Redis MSET\n\t * @param keyValueMap a {@link Map}ping of {@link String} key names to byte[] values.\n\t * @return Future<Boolean> indicating if all of sets were OK or not\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> mset(Map<K, byte[]> keyValueMap);\n\t\n\tpublic <K extends Object> Future<ResponseStatus> mset(KeyValueSet.ByteArrays<K> mappings);\n\tpublic <K extends Object> Future<ResponseStatus> mset(KeyValueSet.Strings<K> mappings);\n\tpublic <K extends Object> Future<ResponseStatus> mset(KeyValueSet.Numbers<K> mappings);\n\tpublic <K extends Object, T extends Serializable> Future<ResponseStatus> mset(KeyValueSet.Objects<K, T> mappings);\n\t\n\t/**\n\t * @Redis MSETNX\n\t * @param keyValueMap a {@link Map}ping of {@link String} key names to byte[] values.\n\t * @return Future<Boolean> indicating if all of sets were OK or not\n\t * @throws RedisException\n\t */\n\tpublic <K extends Object> Future<Boolean> msetnx(Map<K, byte[]> keyValueMap);\n\t\n\tpublic <K extends Object> Future<Boolean> msetnx(KeyValueSet.ByteArrays<K> mappings);\n\tpublic <K extends Object> Future<Boolean> msetnx(KeyValueSet.Strings<K> mappings);\n\tpublic <K extends Object> Future<Boolean> msetnx(KeyValueSet.Numbers<K> mappings);\n\tpublic <K extends Object, T extends Serializable> Future<Boolean> msetnx(KeyValueSet.Objects<K, T> mappings);\n\t\n\t/**\n\t * @Redis INCR\n\t * @param key\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> incr (K key);\n\n\t/**\n\t * @Redis INCRBY\n\t * @param key\n\t * @param delta\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> incrby (K key, int delta);\n\n\t/**\n\t * @Redis DECR\n\t * @param key\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> decr (K key);\n\n\t/**\n\t * @Redis DECRBY\n\t * @param key\n\t * @param delta\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> decrby (K key, int delta);\n\n\t/**\n\t * @Redis SUBSTR\n\t * @param listkey\n\t * @param from\n\t * @param to\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> substr (K listkey, long from, long to); \n\t\n\t/**\n\t * @Redis APPEND\n\t * @param key\n\t * @param value\n\t * @return the length (byte count) of appended key.\n\t */\n\tpublic <K extends Object> Future<Long> append (K key, byte[] value);\n\tpublic <K extends Object> Future<Long> append (K key, String stringValue);\n\tpublic <K extends Object> Future<Long> append (K key, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\t   Future<Long> append (K key, T object);\n\n\t/**\n\t * @Redis EXISTS\n\t * @param key\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> exists(K key);\n\n\t/**\n\t * @Redis DEL\n\t * @param keys one or more, non-null, non-zero-length, keys to be deleted\n\t * @return Future<Long> of number keys actually deleted.\n\t */\n\tpublic <K extends Object> Future<Long> del (K ... keys);\n\n\t/**\n\t * @Redis TYPE\n\t * @param key\n\t * @return\n\t */\n\tpublic <K extends Object> Future<RedisType> type (K key);\n\t\n\t\n\t// ------------------------------------------------------------------------\n\t// \"Commands operating on the key space\"\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis KEYS\n\t * @param pattern\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> keys (K pattern);\n\t\n\t/**\n\t * Convenience method.  Equivalent to calling <code>jredis.keys(\"*\");</code>\n\t * @Redis KEYS\n\t * @return\n\t * @see {@link JRedis#keys(String)}\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> keys ();\n\n\t/**\n\t * @Redis RANDOMKEY\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> randomkey();\n\t\n\t/**\n\t * @Redis RENAME\n\t * @param oldkey\n\t * @param newkey\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> rename (K oldkey, K newkey);\n\t\n\t/**\n\t * @Redis RENAMENX\n\t * @param oldkey\n\t * @param brandnewkey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> renamenx (K oldkey, K brandnewkey);\n\t\n\t/**\n\t * @Redis DBSIZE\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> dbsize ();\n\t\n\t/**\n\t * @Redis EXPIRE\n\t * @param key\n\t * @param ttlseconds\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> expire (K key, int ttlseconds); \n\t\n\t/**\n\t * @Redis EXPIREAT\n\t * @param key\n\t * @param UNIX epoch-time in <b>milliseconds</b>.  Note that Redis expects epochtime\n\t * in seconds. Implementations are responsible for converting to seconds.\n\t * method   \n\t * @return\n\t * @see {@link System#currentTimeMillis()}\n\t */\n\tpublic <K extends Object> Future<Boolean> expireat (K key, long epochtimeMillisecs); \n\t\n\t/**\n\t * @Redis TTL\n\t * @param key\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> ttl (K key);\n\t\n\t// ------------------------------------------------------------------------\n\t// Commands operating on lists\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * @Redis RPUSH\n\t * @param listkey\n\t * @param value\n\t */\n\tpublic <K extends Object> Future<Long> rpush (K listkey, byte[] value);\n\tpublic <K extends Object> Future<Long> rpush (K listkey, String stringValue);\n\tpublic <K extends Object> Future<Long> rpush (K listkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Long> rpush (K listkey, T object);\n\t\n\t/**\n\t * @Redis LPUSH\n\t * @param listkey\n\t * @param value\n\t */\n\tpublic <K extends Object> Future<Long> lpush (K listkey, byte[] value);\n\tpublic <K extends Object> Future<Long> lpush (K listkey, String stringValue);\n\tpublic <K extends Object> Future<Long> lpush (K listkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Long> lpush (K listkey, T object);\n\t\n\t/**\n\t * @Redis LSET\n\t * @param key\n\t * @param index\n\t * @param value\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> lset (K key, long index, byte[] value);\n\tpublic <K extends Object> Future<ResponseStatus> lset (K key, long index, String stringValue);\n\tpublic <K extends Object> Future<ResponseStatus> lset (K key, long index, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<ResponseStatus> lset (K key, long index, T object);\n\t\n\n\t/**\n\t * @Redis LREM\n\t * @param listKey\n\t * @param value\n\t * @param count\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> lrem (K listkey, byte[] value,       int count);\n\tpublic <K extends Object> Future<Long> lrem (K listkey, String stringValue, int count);\n\tpublic <K extends Object> Future<Long> lrem (K listkey, Number numberValue, int count);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Long> lrem (K listkey, T object, int count);\n\t\n\t/**\n\t * Given a 'list' key, returns the number of items in the list.\n\t * @Redis LLEN\n\t * @param listkey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> llen (K listkey);\n\t\n\t/**\n\t * @Redis LRANGE\n\t * @param listkey\n\t * @param from\n\t * @param to\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> lrange (K listkey, long from, long to); \n\n\t/**\n\t * @Redis LTRIM\n\t * @param listkey\n\t * @param keepFrom\n\t * @param keepTo\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> ltrim (K listkey, long keepFrom, long keepTo);\n\t\n\t/**\n\t * @Redis LINDEX\n\t * @param listkey\n\t * @param index\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> lindex (K listkey, long index);\n\t\n\t/**\n\t * @Redis LPOP\n\t * @param listKey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> lpop (K listkey);\n\t\n\t/**\n\t * @Redis RPOP\n\t * @param listKey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> rpop (K listkey);\n\n\t/**\n\t * @Redis RPOPLPUSH\n\t * @param srcList\n\t * @param destList\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> rpoplpush (String srcList, String destList);\n\t// ------------------------------------------------------------------------\n\t// Commands operating on sets\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis SADD\n\t * @param setkey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> sadd (K setkey, byte[] member);\n\tpublic <K extends Object> Future<Boolean> sadd (K setkey, String stringValue);\n\tpublic <K extends Object> Future<Boolean> sadd (K setkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Boolean> sadd (K setkey, T object);\n\n\t/**\n\t * @Redis SREM\n\t * @param setKey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> srem (K setkey, byte[] member);\n\tpublic <K extends Object> Future<Boolean> srem (K setkey, String stringValue);\n\tpublic <K extends Object> Future<Boolean> srem (K setkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Boolean> srem (K setkey, T object);\n\n\t/**\n\t * @Redis SISMEMBER\n\t * @param setKey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> sismember (K setkey, byte[] member);\n\tpublic <K extends Object> Future<Boolean> sismember (K setkey, String stringValue);\n\tpublic <K extends Object> Future<Boolean> sismember (K setkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Boolean> sismember (K setkey, T object);\n\t\n\t/**\n\t * @Redis SMOVE\n\t * @param srcKey\n\t * @param destKey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> smove (K srcKey, K destKey, byte[] member);\n\tpublic <K extends Object> Future<Boolean> smove (K srcKey, K destKey, String stringValue);\n\tpublic <K extends Object> Future<Boolean> smove (K srcKey, K destKey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Boolean> smove (K srcKey, K destKey, T object);\n\t\n\t/**\n\t * @Redis SCARD\n\t * @param setKey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> scard (K setKey);\t\n\t\n\t/**\n\t * @Redis SINTER\n\t * @param set1\n\t * @param sets\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> sinter (K set1, K...sets);\n\t/**\n\t * @Redis SINTERSTORE\n\t * @param destSetKey\n\t * @param sets\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> sinterstore (K destSetKey, K...sets);\n\n\t/**\n\t * @Redis SUNION\n\t * @param set1\n\t * @param sets\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> sunion (K set1, K...sets);\n\t\n\t/**\n\t * @Redis SUNIONSTORE\n\t * @param destSetKey\n\t * @param sets\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> sunionstore (K destSetKey, K...sets);\n\n\t/**\n\t * @Redis SDIFF\n\t * @param set1\n\t * @param sets\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> sdiff (K set1, K...sets);\n\t\n\t/**\n\t * @Redis SDIFFSTORE\n\t * @param destSetKey\n\t * @param sets\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> sdiffstore (K destSetKey, K...sets);\n\n\t/**\n\t * @Redis SMEMBERS\n\t * @param setkey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> smembers (K setkey);\n\t\n\t/**\n\t * @Redis SRANDMEMBER\n\t * @param setkey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> srandmember (K setkey);\n\n\t/**\n\t * @Redis SPOP\n\t * @param setkey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> spop (K setkey);\n\t// ------------------------------------------------------------------------\n\t// Commands operating on sorted sets\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis ZADD\n\t * @param setkey\n\t * @param score\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> zadd (K setkey, double score, byte[] member);\n\tpublic <K extends Object> Future<Boolean> zadd (K setkey, double score, String stringValue);\n\tpublic <K extends Object> Future<Boolean> zadd (K setkey, double score, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Boolean> zadd (K setkey, double score, T object);\n\n\t/**\n\t * @Redis ZREM\n\t * @param setKey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> zrem (K setkey, byte[] member);\n\tpublic <K extends Object> Future<Boolean> zrem (K setkey, String stringValue);\n\tpublic <K extends Object> Future<Boolean> zrem (K setkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Boolean> zrem (K setkey, T object);\n\n\t/**\n\t * @Redis ZCARD\n\t * @param setKey\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> zcard (K setKey);\t\n\t\n\t/**\n\t * @Redis ZSCORE\n\t * @param setkey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Double> zscore (K setkey, byte[] member);\n\tpublic <K extends Object> Future<Double> zscore (K setkey, String stringValue);\n\tpublic <K extends Object> Future<Double> zscore (K setkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Double> zscore (K setkey, T object);\n\n\t/**\n\t * @Redis ZRANK\n\t * @param setkey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> zrank (K setkey, byte[] member);\n\tpublic <K extends Object> Future<Long> zrank (K setkey, String stringValue);\n\tpublic <K extends Object> Future<Long> zrank (K setkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Long> zrank (K setkey, T object);\n\n\t/**\n\t * @Redis ZREVRANK\n\t * @param setkey\n\t * @param member\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> zrevrank (K setkey, byte[] member);\n\tpublic <K extends Object> Future<Long> zrevrank (K setkey, String stringValue);\n\tpublic <K extends Object> Future<Long> zrevrank (K setkey, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Long> zrevrank (K setkey, T object);\n\n\t/**\n\t * @Redis ZRANGE\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> zrange (K setkey, long from, long to); \n\n\t/**\n\t * @Redis ZREVRANGE\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> zrevrange (K setkey, long from, long to); \n\n\t/**\n\t * Equivalent to {@link JRedis#zrange(String, long, long)} with the {@link Command.Option#WITHSCORES}.\n\t * Unlike the general ZRANGE command that only returns the values, this method returns both\n\t * values and associated scores for the specified range.\n\t * \n\t * @Redis ZRANGE ... WITHSCORES\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return\n\t * @see JRedis#zrange(String, long, long)\n\t * @see ZSetEntry\n\t */\n\tpublic <K extends Object> Future<List<ZSetEntry>> zrangeSubset (K setkey, long from, long to); \n\n\t/**\n\t * Equivalent to {@link JRedis#zrange(String, long, long)} with the {@link Command.Option#WITHSCORES}.\n\t * Unlike the general ZRANGE command that only returns the values, this method returns both\n\t * values and associated scores for the specified range.\n\t * \n\t * @Redis ZREVRANGE ... WITHSCORES\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return\n\t * @see JRedis#zrevrange(String, long, long)\n\t * @see ZSetEntry\n\t */\n\tpublic <K extends Object> Future<List<ZSetEntry>> zrevrangeSubset (K setkey, long from, long to); \n\n\t/**\n\t * @Redis ZINCRBY\n\t * @param setkey\n\t * @param score\n\t * @param member\n\t * @return\n\t */\n\t@Redis(versions=\"1.07\")\n\tpublic <K extends Object> Future<Double> zincrby (K setkey, double score, byte[] member);\n\tpublic <K extends Object> Future<Double> zincrby (K setkey, double score, String stringValue);\n\tpublic <K extends Object> Future<Double> zincrby (K setkey, double score, Number numberValue);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Double> zincrby (K setkey, double score, T object);\n\n\t/**\n\t * @Redis ZRANGEBYSCORE\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<byte[]>> zrangebyscore (K setkey, double minScore, double maxScore); \n\n\t/**\n\t * @Redis ZRANGEBYSCORE ... WITHSCORES\n\t * @param setkey\n\t * @param minScore\n\t * @param maxScore\n\t * @return\n\t */\n\tpublic <K extends Object> Future<List<ZSetEntry>> zrangebyscoreSubset (K setkey, double minScore, double maxScore);\n\n\t/**\n\t * @Redis ZREMRANGEBYSCORE\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return number of removed elements\n\t */\n\tpublic <K extends Object> Future<Long> zremrangebyscore (K setkey, double minScore, double maxScore); \n\n\t/**\n\t * @Redis ZCOUNT\n\t * @param setkey\n\t * @param minScore\n\t * @param maxScore\n\t * @return number of removed elements\n\t */\n\tpublic <K extends Object> Future<Long> zcount (K setkey, double minScore, double maxScore); \n\n\t/**\n\t * @Redis ZREMRANGEBYRANK\n\t * @param setkey\n\t * @param from\n\t * @param to\n\t * @return number of removed elements\n\t */\n\tpublic <K extends Object> Future<Long> zremrangebyrank (K setkey, long minRank, long maxRank); \n\t\n\t\n\t// ------------------------------------------------------------------------\n\t// Commands operating on hashes\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis HSET\n\t * @param key\n\t * @param field\n\t * @param value\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> Future<Boolean> hset(K key, K entry, byte[] value);\n\t\n\t/**\n\t * @Redis HSET\n\t * @param key\n\t * @param field\n\t * @param string\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> Future<Boolean> hset(K key, K entry, String string);\n\t\n\t/**\n\t * @Redis HSET\n\t * @param key\n\t * @param field\n\t * @param number\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> Future<Boolean> hset(K key, K entry, Number number);\n\t\n\t/**\n\t * @Redis HSET\n\t * @param <T>\n\t * @param key\n\t * @param field\n\t * @param object\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.4\")\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<Boolean> hset(K key, K entry, T object);\n\t\n\t/**\n\t * @Redis HGET\n\t * @param key\n\t * @param field\n\t * @return\n\t */\n\t@Redis(versions=\"1.3.4\")\n\tpublic <K extends Object> Future<byte[]> hget(K key, K entry);\n\t\n\n\t/**\n\t * @Redis HINCRBY\n\t * @param key\n\t * @param entry\n\t * @param increment\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> hincrby(K key, K entry, long increment);\n\t\n\t\n\t/**\n\t * \n\t * @Redis HEXISTS\n\t * @param key\n\t * @param field\n\t * @return true if the spec'd field exists for the spec'd (hash type) key\n\t */\n\t@Redis(versions=\"1.3.5\")\n\tpublic <K extends Object> Future<Boolean> hexists(K key, K entry);\n\t\n\t/**\n\t * \n\t * @Redis HDEL\n\t * @param key\n\t * @param field\n\t * @return true if the spec'd field exists for the spec'd (hash type) key\n\t */\n\t@Redis(versions=\"1.3.5\")\n\tpublic <K extends Object> Future<Boolean> hdel(K key, K entry);\n\t\n\t/**\n\t * \n\t * @Redis HLEN\n\t * @param key\n\t * @param field\n\t * @return # of fields/entries for the given hash type key\n\t */\n\t@Redis(versions=\"1.3.5\")\n\tpublic <K extends Object> Future<Long> hlen(K key);\n\t\n\t/**\n\t * \n\t * @Redis HKEYS\n\t * @param key\n\t * @return list of keys in the given hashtable.\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> Future<List<byte[]>> hkeys(K key);\n\t\n\t/**\n\t * \n\t * @Redis HVALS\n\t * @param key\n\t * @return list of values in the given hashtable.\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> Future<List<byte[]>> hvals(K key);\n\t\n\t/**\n\t * \n\t * @Redis HGETALL\n\t * @param key\n\t * @return the given hash as a Map<String, byte[]>\n\t * @throws RedisException\n\t */\n\t@Redis(versions=\"1.3.n\")\n\tpublic <K extends Object> Future<Map<byte[], byte[]>> hgetall(K key);\n\t\n\t// ------------------------------------------------------------------------\n\t// Multiple databases handling commands\n\t// ------------------------------------------------------------------------\n\t\n//\t@Deprecated\n//\tpublic <K extends Object> Future<ResponseStatus> select (int index);\n\n\t/**\n\t * Flushes the db you selected when connecting to Redis server.  Typically,\n\t * implementations will select db 0 on connecting if non was specified.  Remember\n\t * that there is no roll-back.\n\t * @Redis FLUSHDB\n\t * @return\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> flushdb ();\n\n\t/**\n\t * Flushes all dbs in the connect Redis server, regardless of which db was selected\n\t * on connect time.  Remember that there is no rollback.\n\t * @Redis FLUSHALL\n\t * @return\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> flushall ();\n\n\t/**\n\t * Moves the given key from the currently selected db to the one indicated\n\t * by <code>dbIndex</code>.\n\t * @Redis MOVE\n\t * @param key\n\t * @param dbIndex\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Boolean> move (K key, int dbIndex);\n\t\n\t// ------------------------------------------------------------------------\n\t// Sorting\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * <p>For Usage details regarding sort semantics, see {@link JRedis#sort}.  The\n\t * only difference in usage is that you must use the {@link Sort#execAsync()} method\n\t * which returns a {@link Future} instances.\n\t * <p>Usage:\n\t * <p><code><pre>\n\t * Future<List<byte[]>>  futureResults = redis.sort(\"my-list-or-set-key\").BY(\"weight*\").LIMIT(1, 11).GET(\"object*\").DESC().ALPHA().execAsync();\n\t * List<byte[]> results = futureResult.get();  // wait for the asynchronous response to be processed\n\t * for(byte[] item : results) {\n\t *     // do something with item ..\n\t *  }\n\t * </pre></code>\n\t * \n\t * @Redis SORT\n\t * @see Redis\n\t * @see Future\n\t * \n\t */\n\tpublic <K extends Object> Sort sort(K key);\n\t\n\t// ------------------------------------------------------------------------\n\t// Persistence control commands\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * @Redis SAVE\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> save();\n\n\t/**\n\t * @Redis BGSAVE\n\t */\n\tpublic <K extends Object> Future<ResponseStatus> bgsave ();\n\n\t/**\n\t * @Redis BGREWRITEAOF\n\t * @return ack message.  \n\t */\n\tpublic <K extends Object> Future<String> bgrewriteaof ();\n\n\t/**\n\t * @Redis LASTSAVE\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Long> lastsave ();\n\n\n// ------------------------------------------------------------------------\n// Remote server control commands\n// ------------------------------------------------------------------------\n\n\t/**\n\t * @Redis INFO\n\t * @return\n\t */\n\tpublic <K extends Object> Future<Map<String, String>>\tinfo () ;\n\n\t/**\n\t * @Redis SLAVEOF\n\t * @param host ip address \n\t * @param port\n\t */\n\tpublic <K extends Object> Future<ResponseStatus>  slaveof(String host, int port);\n\t\n\t/**\n\t * Convenience method.  Turns off replication.\n\t * @Redis SLAVEOF \"no one\"\n\t */\n\tpublic <K extends Object> Future<ResponseStatus>  slaveofnone();\n\t// ------------------------------------------------------------------------\n\t// Diagnostics commands\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis ECHO\n\t * @param msg\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> echo (byte[] msg);\n\tpublic <K extends Object> Future<byte[]> echo (String msg);\n\tpublic <K extends Object> Future<byte[]> echo (Number msg);\n\tpublic <K extends Object, T extends Serializable> \n\t\tFuture<byte[]> echo (T msg);\n\t\t\n\t/**\n\t * @Redis DEBUG OBJECT <key>\n\t * @param key\n\t * @return\n\t */\n\tpublic <K extends Object> Future<ObjectInfo> debug (K key);\n\t\n\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/KeyValueSet.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.io.Serializable;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 25, 2009\n * @since   alpha.0\n * \n */\n\npublic interface KeyValueSet <K extends Object, T> {\n\tpublic KeyValueSet<K, T> add(K key, T value);\n\tbyte[][] getMappings ();\n\t\n\tpublic interface ByteArrays<K extends Object> extends KeyValueSet<K, byte[]>{/* nop */}\n\tpublic interface Numbers<K extends Object>  extends KeyValueSet<K, Number>{/* nop */}\n\tpublic interface Strings<K extends Object>  extends KeyValueSet<K, String>{/* nop */}\n\tpublic interface Objects<K extends Object, T extends Serializable> extends KeyValueSet<K, T>{/* nop */}\n\t\n//\tabstract static class  GenImpl<T> implements  BulkSetMappings<T> {\n//\t\tprotected final Map<String, T> map = new HashMap<String, T>();\n//        public BulkSetMappings<T> add (String key, T value) {\n//        \tmap.put(key, value);\n//\t        return this;\n//        }\n//        public Map<String, T> getMappings () { return map; }\n//        abstract protected byte[] toBytes(T value) ;\n//\t}\n//\tpublic final static class BytesValueMappings extends GenImpl<byte[]> implements  BulkSetMappings<byte[]> {\n//        abstract protected byte[] toBytes(T value) {\n//        \t\n//        }\n//\t}\n//\tpublic final static class StringValueMappings extends GenImpl<String> implements  BulkSetMappings<String> {\n//        abstract protected byte[] toBytes(T value) {\n//        \t\n//        }\n//\t}\n//\tpublic final static class NumberValueMappings extends GenImpl<Number> implements  BulkSetMappings<Number> {\n//        abstract protected byte[] toBytes(T value) {\n//        \t\n//        }\n//\t}\n//\tpublic final static class ObjectValueMappings <T extends Serializable> extends GenImpl<T> implements  BulkSetMappings<T> {\n//        abstract protected byte[] toBytes(T value) {\n//        \t\n//        }\n//\t}\n//\t\n//\tpublic static final class TestMe {\n//\t\t@SuppressWarnings(\"null\")\n//        public static void main (String[] args) {\n//\t        BulkSetMappings<byte[]> byteMappings = new BytesValueMappings();\n//\t        byteMappings\n//\t        \t.add(\"foo\", \"woof\".getBytes())\n//\t        \t.add(\"bar\", \"meow\".getBytes())\n//\t        \t.add(\"paz\", \"the salt\".getBytes())\n//\t        \t.add(\"x?\", \"yz!\".getBytes());\n//\t        \n//\t        try {\n//\t\t        JRedis jredis = null;\n//\t            if(jredis.mset(byteMappings)) {\n//\t            \tSystem.out.println(\"ok!\");\n//\t            }\n//            }\n//            catch (RedisException e) {\n//\t            // TODO Auto-generated catch block\n//\t            e.printStackTrace();\n//            }\n//        }\n//\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/NotSupportedException.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n\n/**\n * Providers can throw this exception in response for requests for <i>optional</i>\n * aspects of Redis Specification.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic class NotSupportedException extends ProviderException {\n\n\t/** \t */\n\tprivate static final long serialVersionUID = _specification.Version.major;\n\n\t/**\n\t * @param string\n\t */\n\tpublic NotSupportedException(String string) {\n\t\tsuper (string);\n\t}\n\t/**\n\t * @param string\n\t */\n\tpublic NotSupportedException(String string, Throwable cause) {\n\t\tsuper (string, cause);\n\t}\n\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/ObjectEncoding.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n/**\n * Internal Redis object encoding schemes.\n *   \n * @see ObjectInfo#getEncoding()\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Mar 17, 2010\n * @since   alpha.0 | Redis 1.3.5\n *\n */\npublic enum ObjectEncoding {\n\t/** Redis 'raw'  */\n\tRAW (),\n\t/** Redis 'int'  */\n\tINT (),\n\t/** Redis 'zipmap'  */\n\tZIPMAP(),\n\t/** Redis 'hashtable'  */\n\tHASHTABLE,\n\t/** Redis 'embstr'  */\n\tEMBSTR,\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/ObjectInfo.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.util.ArrayList;\nimport java.util.Formatter;\nimport java.util.List;\nimport java.util.StringTokenizer;\n\n/**\n * Encapsulates the debug information returned by Redis in response to DEBUG\n * OBJECT <key>.\n * \n * @author Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Mar 16, 2010\n * @since alpha.0\n * @see JRedis#debug(String)\n */\n\npublic class ObjectInfo {\n\tprivate static final long numTokens = 7;\n\tprivate final String keyAddress;\n\tprivate final long keyRefCount;\n\tprivate final ObjectEncoding encoding;\n\tprivate final long serializedLength;\n\tprivate final long lru;\n\tprivate final long lruSecondsIdle;\n\n\tpublic ObjectInfo(String keyAddress, long keyRefCount,\n\t\t\tObjectEncoding encoding, long serializedLength, long lru,\n\t\t\tlong lruSecondsIdle) {\n\t\tthis.keyAddress = keyAddress;\n\t\tthis.keyRefCount = keyRefCount;\n\t\tthis.encoding = encoding;\n\t\tthis.serializedLength = serializedLength;\n\t\tthis.lru = lru;\n\t\tthis.lruSecondsIdle = lruSecondsIdle;\n\t}\n\n\t/**\n\t * @return the keyAddress as {@link String} representation of hex address.\n\t *         Ex: \"0x100d60\"\n\t */\n\tpublic String getKeyAddress() {\n\t\treturn keyAddress;\n\t}\n\n\t/** @return the keyRefCount */\n\tpublic long getKeyRefCount() {\n\t\treturn keyRefCount;\n\t}\n\n\t/**\n\t * @return the valueAddress as {@link String} representation of hex address.\n\t *         Ex: \"0x100d60\"\n\t */\n\n\t/** @return the encoding */\n\tpublic ObjectEncoding getEncoding() {\n\t\treturn encoding;\n\t}\n\n\t/**\n\t * Convenience method to convert the address info to long. Ex: \"0x101860\" =>\n\t * 1054816. (Note that the returned number is (obviously) base 10.)\n\t * \n\t * @param addressStrRep\n\t * @return\n\t */\n\tpublic static long toLong(String addressStrRep) {\n\t\treturn Long.parseLong(addressStrRep.substring(2), 16);\n\t}\n\n\t@SuppressWarnings(\"boxing\")\n\t@Override\n\tpublic String toString() {\n\t\tFormatter formatter = new Formatter();\n\t\tformatter\n\t\t\t\t.format(\"ObjectInfo: key [addr:%s  refCnt: %d] encoding:%s serializedLength: %d lru %d lruSecondsIdle %d\",\n\t\t\t\t\t\tkeyAddress, keyRefCount, encoding, serializedLength,\n\t\t\t\t\t\tlru, lruSecondsIdle);\n\t\treturn formatter.toString();\n\t}\n\n\t/**\n\t * Strictly speaking, this doesn't belong here but cuts down on redundant\n\t * code. Parses the DEBUG OBJECT <key> response to return an instance of\n\t * {@link ObjectInfo}.\n\t * \n\t * @param strRep\n\t * @return {@link ObjectInfo}\n\t */\n\tstatic public final ObjectInfo valueOf(String strRep) {\n\t\tStringTokenizer tokenizer = new StringTokenizer(strRep);\n\t\tint tokenCnt = tokenizer.countTokens();\n\n\t\tif (tokenCnt != numTokens)\n\t\t\tthrow new ProviderException(\n\t\t\t\t\t\"DEBUG OBJECT <key> response does not conform to expected format.  Got: [\"\n\t\t\t\t\t\t\t+ strRep + \"]\");\n\n\t\tList<String> tokens = new ArrayList<String>(tokenCnt);\n\n\t\twhile (tokenizer.hasMoreElements())\n\t\t\ttokens.add(tokenizer.nextToken());\n\n\t\tString keyAddr = tokens.get(1).substring(3);\n\t\tString keyCnt = tokens.get(2).substring(\"refcount:\".length());\n\t\tString encodingRep = tokens.get(3).substring(\"encoding:\".length());\n\t\tString serlen = tokens.get(4).substring(\"serializedlength:\".length());\n\t\tString lru = tokens.get(5).substring(\"lru:\".length());\n\t\tString lruSecondsIdle = tokens.get(6).substring(\n\t\t\t\t\"lru_seconds_idle:\".length());\n\n\t\tObjectInfo info = new ObjectInfo(keyAddr, Integer.parseInt(keyCnt),\n\t\t\t\tObjectEncoding.valueOf(encodingRep.toUpperCase()),\n\t\t\t\tInteger.parseInt(serlen), Integer.parseInt(lru),\n\t\t\t\tInteger.parseInt(lruSecondsIdle));\n\n\t\treturn info;\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/ProviderException.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n\n\n/**\n * Used by JRedis implementation providers to indicate an exception related to the\n * implementation of the specification.  Effectively, this exception and its extensions\n * should only be thrown when a fault has occurred that is neither a {@link SystemException},\n * nor a Redis prompted server side error.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic class ProviderException extends ClientRuntimeException {\n\n\t/** */\n\tpublic static final long version = _specification.Version.major;\n\n\t/**  */\n\tprivate static final long\tserialVersionUID\t= _specification.Version.major;\n\t\n\n\t/**\n\t * @param message\n\t */\n\tpublic ProviderException(String message) {\n\t\tsuper(message);\n\t\t// TODO Auto-generated constructor stub\n\t}\n\n\t/**\n\t * @param message\n\t * @param cause\n\t */\n\tpublic ProviderException(String message, Throwable cause) {\n\t\tsuper(message, cause);\n\t\t// TODO Auto-generated constructor stub\n\t}\n\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/Query.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.util.List;\nimport java.util.concurrent.Future;\n\n/**\n * Provides for specifying and chaining query predicates.  The results of the query directive are returned\n * as an ordered {@link List} of <code>byte[]</code> values.\n * \n * <p>Specific {@link Query} types are obtained from the {@link JRedis} api.  Extensions of this interface\n * allow for the definition of natural expression of the query clauses.  Such interfaces should <b>only</b> \n * define methods for the optional elements of the specific query type.  Redis interface itself will also\n * only allow for obtaining a reference to such an interface by specifying the required arguments in the\n * associated method signature.\n * \n * <p>For example, to get a {@link Sort} instance, {@link JRedis} api specifies the required argument,  \n * (namely the <i>the key</i>) in the method signature for {@link JRedis#sort(String)}, and all the optional\n * elements of the SORT command are provided for in the {@link Sort} interface:\n * <p>\n * <pre><code>\n * Sort    sort = redis.sort (key)\n * List<byte[]>  results = BY(\"foo*\").LIMIT(1, 11).GET(\"*woof*\").DESC().<b>exec()</b>;\n * for(byte[] item : results) {\n *     // do something with item ..\n *  }\n * \n * </code></pre>\n * \n * @see Sort\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface Query {\n\t\n\t/**\n\t * Executes the query.\n\t * \n\t * @return the resultant value list from redis.\n\t * @throws IllegalStateException\n\t * @throws RedisException\n\t */\n\t// TODO: why illegal state?\n\tpublic List<byte[]> exec () throws IllegalStateException, RedisException;\t\n\tpublic Future<List<byte[]>> execAsync ();\t\n\t\n\tpublic static class Support {\n\t\tpublic static long unpackValue (List<byte[]> queryResult){\n\t\t\tif(null == queryResult) throw new ClientRuntimeException(\"queryResult is null\");\n\t\t\tif(queryResult.size() < 1) throw new ClientRuntimeException(\"queryResult must have at least 1 entry\");\n\t\t\treturn Long.parseLong(new String(queryResult.get(0)));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/Redis.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Annotation to mark complaint elements of JRedis implementations.\n * \n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\n@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PACKAGE})\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Redis {\n\t/**\n\t * @return array of strings denoting version of redis protocol supported\n\t */\n\tString[] versions();\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/RedisException.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport org.jredis.protocol.Command;\n\n//import org.jredis.connector.ProviderException;\n\n/**\n * [TODO: update doc regarding \"extensions\"]\n * \n * RedisExceptions are only created/raised subsequent to an error result from the redis server.\n * These exceptions are <b>_not_</b> intended as a general purpose exception mechanism for\n * implementations of this specification.  Accordingly, this exception (and extensions if any)\n * do not (and must not) provide default no arg constructors.  (Minimal information required is\n * an associated {@link Command} object.)  \n * \n * <p>Further, this class (and extension if any) should never expose a constructor accepting \n * an underlying 'cause' (as in {@link Exception#Exception(Throwable)}), since this excpetion,\n * to repeat, has very specific semantics:  <b>Redis has responded with an error \n * status to an issued command and the content of that message (e.g. \"-ERR operation on wrong type\"</b>\n * is what is required for instantiating a {@link RedisException}.\n * \n * @see ClientRuntimeException\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic final class RedisException extends Exception {\n\n\t/**  */\n\tpublic static final long version = _specification.Version.major;\n\n\t/**  */\n\tprivate static final long\tserialVersionUID = version;\n\n\t/**  */\n\tprivate final Command command;\n\t\n//\tpublic RedisException (String message) {\n//\t\tsuper (message);\n//\t}\n\t\n\tpublic RedisException (Command command, String message){\n\t\tsuper (message);\n\t\tthis.command = command;\n\t}\n\n\t/**  @return the associated {@link Command} if any */\n\tpublic Command getCommand () { return command; }\n\t\n\tpublic String toString () {\n\t\treturn \"Exception on [\" + command.code + \"] => \" + getMessage(); \n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/RedisInfo.java",
    "content": "/*\n *   Copyright 2009-2012 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport java.util.Map;\n\n/**\n * RedisInfo is a convenience enum that tracks the canonical entries returned by INFO command.\n * Exception to this is the db## when ## is db number e.g. db10.  \n * <b>\n * Note that of course the {@link JRedis#info()} command returns a {@link Map} so you can always\n * query for the db info directly using the returned map.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0-05062012\n * @since   alpha.0\n * \n */\npublic enum RedisInfo {\n\tredis_git_dirty,\n\tredis_git_sha1,\n\tused_cpu_user,\n\tclient_longest_output_list,\n\tlatest_fork_usec,\n\tused_memory_peak,\n\tpubsub_patterns,\n\tused_cpu_sys_children,\n\tused_memory_rss,\n\tlru_clock,\n\taof_enabled,\n\tmem_fragmentation_ratio,\n\tused_memory_peak_human,\n\tloading,\n\tclient_biggest_input_buf,\n\tused_cpu_sys,\n\tkeyspace_hits,\n\tevicted_keys,\n\tpubsub_channels,\n\tused_cpu_user_children,\n\tgcc_version,\n\texpired_keys,\n\tmem_allocator,\n\tkeyspace_misses,\n\tarch_bits,\n\tmultiplexing_api,\n\tredis_version,\n\tprocess_id,\n\tconnected_clients,\n\tconnected_slaves,\n\tblocked_clients,\n\tused_memory,\n\tused_memory_human,\n\tchanges_since_last_save,\n\tbgsave_in_progress,\n\tlast_save_time,\n\tbgrewriteaof_in_progress,\n\ttotal_connections_received,\n\ttotal_commands_processed,\n\tuptime_in_seconds,\n\tuptime_in_days,\n//\thash_max_zipmap_entries,\n//\thash_max_zipmap_value,\n//\tvm_enabled,\n\tos,\n\ttcp_port,\n\tused_memory_lua,\n\tlast_bgsave_status,\n\tinstantaneous_ops_per_sec,\n\trejected_connections,\n\trun_id,\n\tbgrewriteaof_scheduled,\t\n\trole\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/RedisType.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n/**\n * \n * @author Joubin Houshyar (alphazero@sensesay.net)\n */\npublic enum RedisType {\n\tNONE, \n\tstring,\n\tlist,\n\tset,\n\thash\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/Semantics.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n\n/**\n * Interface to specify the semantics of the actual key/values stored in the Redis server.\n *\n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, Aug 23, 2009\n * @since   alpha.0\n * \n */\n\npublic interface Semantics {\n\t/**\n\t * @param <T>\n\t * @param keyClass\n\t * @return the Codec used to \n\t */\n\tpublic <T> Codec<T> getKeyCodec(Class<T> keyClass);\n\t/**\n\t * @param <T>\n\t * @param keyClass\n\t * @param keyCodec\n\t * @return\n\t */\n\tpublic <T> Semantics setKeyCodec(Class<T> keyClass, Codec<T> keyCodec);\n\t/**\n\t * @param <T>\n\t * @param valueClass\n\t * @return\n\t */\n\tpublic <T> Codec<T> getValueCodec(Class<T> valueClass);\n\t/**\n\t * @param <T>\n\t * @param valueClass\n\t * @param valueCdec\n\t * @return\n\t */\n\tpublic <T> Semantics setValueCodec(Class<T> valueClass, Codec<T> valueCdec);\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/Sort.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n\npackage org.jredis;\n\nimport java.util.List;\n\n\n/**\n * Sort, a type of {@link Query}, provides for specifying and chaining the query predicates.  The results of the sort directive are returned\n * as an ordered {@link List} of <code>byte[]</code> values.\n *\n * <p>Sort instances are obtained directly from the {@link JRedis} client, by calling the eponymous method {@link JRedis#sort(String)}, which expects\n * a <i>key name</i> as its required arguments.  \n * \n * <br><i>[Note: this provides the pattern for all future query types: required args are specified in the method that returns the {@link Query} form.]</i>\n *  \n * <p>As with all {@link Query} forms, \n * <b>do not forget to call {@link Query#exec()} at the end</b>! \n *\n * <p>Usage:\n * <p><code><pre>\n * List<byte[]>  results = redis.<b>sort</b>(\"my-list-or-set-key\").BY(\"weight*\").LIMIT(1, 11).GET(\"object*\").DESC().ALPHA().<b>exec()</b>;\n * for(byte[] item : results) {\n *     // do something with item ..\n *  }\n * </pre></code>\n * <p>Sort specification elements are all optional.  You could simply say:\n * <p><code><pre>\n * List<byte[]>  results = redis.sort(\"my-list-or-set-key\").<b>exec()</b>;\n * for(byte[] item : results) {\n *     // do something with item ..\n *  }\n * </pre></code>\n * <p>Sort specification elements are also can appear in any order -- the client implementation will send them to the server\n * in the order expected by the protocol, although it is good form to specify the predicates in natural order:\n * <p><code><pre>\n * List<byte[]>  results = redis.sort(\"my-list-or-set-key\").GET(\"object*\").DESC().ALPHA().BY(\"weight*\").LIMIT(1, 11).<b>exec()</b>;\n * for(byte[] item : results) {\n *     // do something with item ..\n *  }\n * </pre></code>\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface Sort extends Query {\n\t/** species the BY clause */\n\t<K extends Object> Sort BY    (K pattern);\n\t\n\t/** specifies the GET clause */\n\t<K extends Object> Sort GET   (K pattern);\n\t\n\t/** \n\t * Specifies the LIMIT class: from is the initial index, count is the number of results \n\t * @param from  limit sort results to element at index 'from'\n\t * @param count limit sort results to count - results will be result[from] to result[from+count], inclusve.\n\t */\n\tSort LIMIT (long from, long count);\n\t\n\t/** default sort is ASCending -- use this in your sort to specify DESC sort */\n\tSort DESC  ();\n\t\n\t/** sort is be default numeric -- use this to indicate lexiographic alphanumeric sort */\n\tSort ALPHA ();\n\t\n\t/** \n\t * Store the sort results in another key.\n\t * <p>\n\t * <b>This command alters the semantics of the {@link Query#exec()} (or  {@link Query#execAsync()()}</b>\n\t * to return a list of size 1, with the single entry being the long value representing the size\n\t * of the created (store destination) list.  \n\t * <p>\n\t * <pre>\n\t *\t// NOTE: this is a Long List - javadoc doesn't print the brackets.\n\t *\t//\n\t *\tList<Long> storeResult = DefaultCodec.toLong(jredis.sort(srcSet).DESC().STORE(destKey).exec());\n\t *\n\t *\t// the STORE() option changes result semantics -- now we expect our list to have a single entry\n\t *\t// for the size of the stored list\n\t *\t//\n\t *\tsize = sortedSet.get(0);\n\t * \n\t * \tSystem.out.format(\"Sorted list (size: %d):\\n\", size);\n\t * </pre>\n \t */\n\t<K extends Object> Sort STORE (K destKey);\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/ZSetEntry.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n/**\n * An entry in a Redis \"sorted set\" and returned by a subset Z* commands.  \n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Mar 20, 2010\n * @since   alpha.0\n * \n */\n\npublic interface ZSetEntry{\n\t/**  @return the value of this entry in a Redis sorted set */\n\tbyte[] getValue();\n\t\n\t/** @return the score associated with the value */\n\tdouble getScore();\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/_specification.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface _specification {\n\n\t/** specification level */\n\tpublic interface Version {\n\t\tlong\tmajor\t= 0xA;\n\t    long \tminor\t= 0x1;\n\t}\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/Connection.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Response;\n\n/**\n * {@link Connection} defines the general (required) and optional \n * contract of a JRedis connection.\n * <p>\n * Redis protocol does not provide for request sequencing (for a\n * variety of good reasons) and guaranteed delivery semantics are\n * supported only by multi-exec (redis transaction) protocol.  Accordingly,\n * {@link Connection} is not required (given that it can not) to support\n * fault-tolerant semantics.  \n * <p>\n * If a connection <i>faults</i> during an interaction with the server \n * (e.g. anytime during send and receive) it must raise one of the following:\n * <ul>\n * <li>{@link ConnectionReset} - connection faulted but connection re-established\n * <li>{@link ConnectionFault} - connection faulted and reconnect not possible.\n * </ul>  \n * In the former case, the specific request that was being processed will not\n * be transparently re-issued by the connector.  The application layer must\n * determine what course of action to take.  \n * <p>\n * In either case, it should be noted that there exists a tiny (but possible)\n * window where even with append logging on the server, where the server received\n * and processed the request but never could reply (e.g. the server crashes for\n * whatever reason).  These considerations are irrelevant to read only commands,\n * but are significant in context of write ops (e.g. INCR).  If you require\n * guarantees on writes, you must use redis transactions (e.g. multi-bulk).\n * \n * <p>\n * That said, the {@link Connection}'s optional event and state management\n * do provide sufficient support for a softer set of guarantees for \n * transparent connection management (on fault detection, connect on demand,\n * etc.).\n * \n * <br> \n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 12, 2010\n * \n */\npublic interface Connection {\n\n\t/**\n\t * The {@link ConnectionSpec} of a Connection must be invariant during its life-cycle.\n\t * @return the associated {@link ConnectionSpec} for this Connection. \n\t */\n\tpublic ConnectionSpec getSpec();\n\t\n\t/**\n\t * A <b>blocking call</b> to service the specified request.  This method will return upon \n\t * the completion of the request response protocol with the connected redis server.  Timeouts\n\t * and related matters are not addressed by this method or the {@link Protocol} interface\n\t * and can (and should) be addressed at the implementation level (for example when creating \n\t * handler instances using a specification set, including max wait for synchronous response.)\n\t * \n\t * <p>{@link Modality#Asynchronous} handlers must always throw a {@link ClientRuntimeException}\n\t * for <b>this method which violates the contract for</b> {@link Modality#Asynchronous}  <b>handlers</b>.\n\t * \n\t * @param cmd\n\t * @param args\n\t * @return\n\t * @throws RedisException\n\t * @throws ClientRuntimeException\n\t * @throws ProviderException\n\t */\n\tpublic Response serviceRequest (Command cmd, byte[]...args) throws RedisException, ClientRuntimeException, ProviderException; \n\t\n\t\n\t/**\n\t * A <b>non-blocking call</b> to service the specified request at some point in the future.  \n\t * This method will return immediately with a {@link Future} object of parametric type {@link Response}\n\t * <p>\n\t * When the request is serviced, call to {@link Future#get()} will return the request response.\n\t * <p>{@link Modality#Synchronous} handlers must always throw a {@link ClientRuntimeException}\n\t * for <b>this method which violates the contract for</b> {@link Modality#Synchronous}  <b>handlers</b>.\n\t * <p>\n\t * If request resulted in a redis error ({@link RedisException}), the exception will be set as the cause of\n\t * the corresponding {@link ExecutionException} of the {@link Future} object returned.\n\t * @param cmd\n\t * @param args\n\t * @return the {@link Future} {@link Response}.\n\t * @throws ClientRuntimeException\n\t * @throws ProviderException\n\t * @see Future\n\t * @see ExecutionException\n\t */\n\n\tpublic Future<Response> queueRequest (Command cmd,  byte[]...args) throws ClientRuntimeException, ProviderException;\n\t\n\t// ------------------------------------------------------------------------\n\t// State management -- optional\n\t/**\n\t */\n\tpublic enum State {\n\t\t/** Connection is initialized and ready. Will connect on demand */\n\t\tINITIALIZED,\n\t\t/** Connection is established. */\n\t\tCONNECTED,\n\t\t/** Not connected to remote server.  Can connect on demand. */\n\t\tDISCONNECTED,\n\t\t/** Connection is shutdown and can be disposed. */\n\t\tTERMINATED\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Event management -- optional\n\t \n\t \t/**\n\t\t * Connection.Event propagation.\n\t\t * @optional  \n\t \t * @param connListener\n\t\t * @return true if listener was successfully added.\n\t \t */\n\t \tpublic boolean addListener(Listener connListener);\n\t \n\t/**\n\t * <b>Optional</b> event propagation method.  Removes the specified listenr\n\t * from the list of {@link Connection.Listener}s.\n\t * @param connListener\n\t * @return true if the listener was actually present and was removed.\n\t */\n\tpublic boolean removeListener(Listener connListener);\n\n\t// ========================================================================\n\t// Innner Types\n\t// ========================================================================\n\t\n\t/**\n\t * Enumeration of the top-level properties of the {@link Connection} that can be\n\t * specified by the User.  \n\t *\n\t * @author  joubin (alphazero@sensesay.net)\n\t * @date    Sep 13, 2010\n\t * \n\t */\n\tpublic enum Property {\n\t\t/** the redis server host name or ip */\n\t\tHOST,\n\t\t/** the Redis server port */\n\t\tPORT,\n\t\t/** the password used   */\n\t\tCREDENTIAL,\n\t\t/** The db selected on (re-)connect */\n\t\tDB,\n\t\t/** Defines the {@link Connection}'s {@link Connection.Modality} */\n\t\tMODALITY,\n\t\t/** On Connect (or reconnect after faults or timeouts) the maximum duration that you are willing to wait, milliseconds */\n\t\tMAX_CONNECT_WAIT,\n\t\t/** number of reconnect attempts after timeouts or faults. */\n\t\tMAX_CONNECT_ATTEMPT,\n\t\t/** if specified, is used to create the new protocol */\n\t\tPROTOCOL_CLASS,\n\t\t/** if specified, is used to create the new protocol */\n\t\tPROTOCOL_FACTORY,\n\t\t/** if specified, is used to create the new connection */\n\t\tCONNECTION_CLASS,\n\t\t/** if specified, is used to create the new connection. */\n\t\tCONNECTION_FACTORY,\n\t\t;// -- fini\n\t}\n\t/**\n\t * Enum for defining the operational modality of the protocol handlers.\n\t *   \n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, 04/02/09\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic enum Modality {\n\t\t/** blocking request/reply semantics */\n\t\tSynchronous,\n\t\t/** non-blocking request/future-response semantics */\n\t\tAsynchronous,\n\t\t/**  */\n\t\tPubSub,\n\t\t/**  */\n\t\tMonitor,\n\t\t;\n\t\t// -- end\n\t}\n\t\n\t/**\n\t * {@link Connection} listeners' callback API.\n\t * @optional\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, Mar 29, 2010\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic interface Listener {\n\t\tpublic void onEvent(Connection.Event event);\n\t}\n\t\n\t/**\n\t * Events raised by the {@link Connection}.\n\t * <br>Events are typed and may have optional event info (Objects).\n\t * @optional\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, Mar 29, 2010\n\t * @since   alpha.0\n\t * \n\t */\n\t@SuppressWarnings(\"serial\")\n    final public static class Event extends org.jredis.Event<Connection, Event.Type, Object>{\n\t\t/**\n         * @param src\n         * @param type\n         */\n        public Event (Connection src, Type type) {\n\t        super(src, type);\n        }\n        public Event (Connection src, Type type, Object eventInfo) {\n\t        super(src, type, eventInfo);\n        }\n\t\t/** Connector.Event types. */\n\t\tpublic enum Type {\n//\t\t\tINITIALIZED,\n\t\t\t/** Raised when Connector is about to initiate the connect protocol */\n\t\t\tCONNECTING,\n\t\t\t/** Raised when Connector has established connectivity to the remote server */\n\t\t\tCONNECTED,\n\t\t\t/** Raised when Connector is about to initiate the disconnect protocol */\n\t\t\tDISCONNECTING,\n\t\t\t/** Raised when Connector has disconnected from the remote server */\n\t\t\tDISCONNECTED,\n\t\t\t/** Raised when the Connector encounters a {@link ClientRuntimeException} or {@link ProviderException}.  */\n\t\t\tFAULTED,\n\t\t\t/** \n\t\t\t * Raised to signal the beginning of the shutdown sequence (commences after listerners are notified.  \n\t\t\t * Cease all activity on receipt \n\t\t\t * */\n//\t\t\tSTOPPING,\n\t\t\t/** Raised when Connector is terminated.  Dispose of your references on receipt. */\n\t\t\tSHUTDOWN\n\t\t}\n\t}\n\n\t// ------------------------------------------------------------------------\n    // Connection.Flag\n    // ------------------------------------------------------------------------\n    /**\n     * Connection flags - not necessarily mutually exclusive.  Uses a 32 bit\n     * mask for 32 (max) disctinct flags for Connnections.\n     *\n     * @author  joubin (alphazero@sensesay.net)\n     * @date    Sep 18, 2010\n     * \n     */\n    public enum Flag {  \t\n    \t/** if true will connect immediately on initialization.  otherwise on first use. */\n    \tCONNECT_IMMEDIATELY,\n//    \t/**  */\n//    \tTRANSPARENT_RECONNECT,\n//    \t/**  */\n//    \tRETRY_AFTER_RESET, \n    \t/** if true uses pipelining */\n    \tPIPELINE,\n    \t/** Connection can be used by more than 1 client concurrently */\n    \tSHARED,\n    \t/** if true attempts to maintain connection. drops are detected. Better fault tolerance guarantees, w/ some performance impact */\n    \tRELIABLE,\n    \t/** if true connection maintains conversational state - for use with multi-exec */\n    \tSTATEFUL,\n    \t/** if true service requests are logged (verbose/slower due to io)  */\n    \tTRACE,\n    \t;\n\t\tpublic final int bitmask;\n\t\tstatic final int OPAQUE_BITMASK = 0x0000;\n\t\tFlag (){\n\t\t\tthis.bitmask = (int)Math.pow(2, ordinal());\n\t\t}\n\t\tstatic final public int bitset(Flag...flags){\n\t\t\tint bitset = OPAQUE_BITMASK;\n\t\t\treturn bitset(bitset, flags);\n\t\t}\n\t\tstatic final public int bitset(final int bitset, Flag...flags){\n\t\t\tint _bitset = bitset;\n\t\t\tfor(Flag f : flags) _bitset = _bitset | f.bitmask;\n\t\t\treturn _bitset;\n\t\t}\n\t\tstatic final public int bitclear(final int bitset, Flag...flags){\n\t\t\tint _bitset = bitset;\n\t\t\tfor(Flag f : flags) _bitset = _bitset ^ f.bitmask;\n\t\t\treturn _bitset;\n\t\t}\n\t\tpublic static boolean isSet(int bitset, Flag flag) {\n\t\t\treturn (bitset & flag.bitmask) > OPAQUE_BITMASK;\n\t\t}\n    }\n    \n\t// ------------------------------------------------------------------------\n    // Connection.Socket\n    // ------------------------------------------------------------------------\n    public interface Socket {\n    \t/**\n    \t * Flag keys for SocketFlag settings of the connection specification.\n    \t * @see ConnectionSpec#getSocketFlag(SocketFlag)\n    \t * @author Joubin Houshyar (alphazero@sensesay.net)\n    \t *\n    \t */\n    \tpublic enum Flag {\n    \t\t/** Corresponds to SO_KEEP_ALIVE flag of {@link Socket}.  @see {@link Socket#setSoTimeout(int)} */\n    \t\tSO_KEEP_ALIVE,\n    \t\t;\n    \t}\n    \t/**\n    \t * Property keys for SocketProperty settings of the connection specification.\n    \t * @see ConnectionSpec#getSocketProperty(SocketProperty)\n    \t * @author Joubin Houshyar (alphazero@sensesay.net)\n    \t *\n    \t */\n    \tpublic enum Property {\n    \t\t/** \n    \t\t * Corresponds to <code><b>SO_SNDBUF</b></code> flag. see {@link Socket#setSendBufferSize(int)} \n    \t\t * <p>expected value is an <b><code>int</code></b> or an {@link Integer}.\n    \t\t */\n    \t\tSO_SNDBUF,\n    \t\t\n    \t\t/** \n    \t\t * corresponds to SO_RCVBUF flag. see {@link Socket#setReceiveBufferSize(int)} \n    \t\t */\n    \t\tSO_RCVBUF,\n    \t\t\n    \t\t/** \n    \t\t * corresponds to SO_TIMEOUT flag.  see {@link Socket#setSoTimeout(int)} \n    \t\t */\n    \t\tSO_TIMEOUT,\n    \t\t\n    \t\t/**\n    \t\t * Socket performance preferences.\n    \t\t * <p> This property will be used in conjunction with other associated properties.\n    \t\t * @See {@link SocketProperty#latency}\n    \t\t * @See {@link SocketProperty#bandwidth}\n    \t\t * @See {@link Socket#setPerformancePreferences(int, int, int)} for details.\n    \t\t */\n    \t\tSO_PREF_CONN_TIME,\n\n    \t\t/**\n    \t\t * Socket performance preferences.\n    \t\t * <p> This property will be used in conjunction with other associated properties.\n    \t\t * @See {@link SocketProperty#bandwidth}\n    \t\t * @See {@link SocketProperty#connection_time}\n    \t\t * @See {@link Socket#setPerformancePreferences(int, int, int)} for details.\n    \t\t */\n    \t\tSO_PREF_LATENCY,\n\n    \t\t/**\n    \t\t * Socket performance preferences.\n    \t\t * <p> This property will be used in conjunction with other associated properties.\n    \t\t * @See {@link SocketProperty#latency}\n    \t\t * @See {@link SocketProperty#connection_time}\n    \t\t * @See {@link Socket#setPerformancePreferences(int, int, int)} for details.\n    \t\t */\n    \t\tSO_PREF_BANDWIDTH,\n    \t}\n    }\n\t// ------------------------------------------------------------------------\n    // Connection.Factor\n    // ------------------------------------------------------------------------\n    public interface Factory {\n    \t/**\n    \t * Creates a connection to a redis server using the specified connection attributes.\n    \t * @param spec of the new connection\n    \t * @return a new {@link Connection} initialized per <code>spec</code>.\n    \t * @throws ClientRuntimeException if the requirements exceed system resources/limits.\n    \t * @throws NotSupportedException if the {@link ConnectionSpec} provided \n    \t * can not be supported by the provider.\n    \t */\n    \tpublic Connection newConnection (ConnectionSpec spec) throws ClientRuntimeException, NotSupportedException;\n    }\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/ConnectionException.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport java.net.SocketException;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis._specification;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 15, 2009\n * @since   alpha.0\n * \n */\n\nabstract public class ConnectionException extends ClientRuntimeException{\n\n\t/**  */\n\tprivate static final long serialVersionUID = _specification.Version.major;\n\t\n\t/**\n\t * TODO: not sure if specifying {@link SocketException} is a good idea.\n\t * @param msg\n\t * @param e\n\t */\n\tpublic ConnectionException(String msg, SocketException e) {\n\t\tsuper(msg, e);\n\t}\n\n\t/**\n\t * @param msg\n\t */\n\tpublic ConnectionException(String msg) {\n\t\tsuper(msg);\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/ConnectionFault.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport java.net.SocketException;\nimport org.jredis._specification;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 12, 2010\n * \n */\n\npublic class ConnectionFault extends ConnectionException {\n\t/**  */\n\tprivate static final long serialVersionUID = _specification.Version.major;\n\n\t/**\n\t * @param string\n\t * @param e\n\t */\n\tpublic ConnectionFault(String msg, SocketException e) {\n\t\tsuper(msg, e);\n\t}\n\tpublic ConnectionFault(String msg) {\n\t\tsuper(msg);\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/ConnectionReset.java",
    "content": "/*\n *   Copyright 2009-2011 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.Socket;\nimport java.net.SocketException;\n\nimport org.jredis._specification;\nimport org.jredis.protocol.Command;\n\n/**\n * This exception is thrown by a {@link Connection} to indicate that the connection to redis was\n * reset (typically due to timeout on Redis side).  \n * <p>\n * If the {@link Connection} is specified to use\n * auto-reconnect, the connection has been re-established, but, the status of the request that\n * gave rise to this exception is indeterminate, in the sense that while this exception certainly indicates\n * that the response was not received from Redis, it is not clear whether the request itself was\n * received by the server.  This is due to the fact that writing to the {@link OutputStream} of a {@link Socket}\n * that has been closed by the remote peer does NOT raise an exception.  The exception is raised (reliably) only\n * on the receive when reading from the {@link Socket}'s {@link InputStream}.\n * <p>\n * Depending on the application domain and the {@link Command} of the request, the user may retry \n * the request. \n * \n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, Apr 15, 2009\n * @since   alpha.0\n * \n */\n\npublic class ConnectionReset extends ConnectionException {\n\n\t/**  */\n\tprivate static final long serialVersionUID = _specification.Version.major;\n\t\n\tprivate static final String info = \"potential redis timeout\";\n\t/**\n\t * @param string\n\t * @param e\n\t */\n\tpublic ConnectionReset(String msg, SocketException e) {\n\t\tsuper(String.format(\"(%s) %s\", info, msg), e);\n\t}\n\tpublic ConnectionReset(String msg) {\n\t\tsuper(String.format(\"(%s) %s\", info, msg));\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/ConnectionSpec.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport java.net.InetAddress;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.jredis.connector.Connection.Modality;\nimport org.jredis.connector.Connection.Property;\n\n\n/**\n * ConnectionSpec specifies the parameters used in the creation and\n * runtime operation of JRedis connections.\n * \n * @author joubin (alphazero@sensesay.net)\n *\n * @see Factory#newConnection(ConnectionSpec)\n * @see java.resource.cci.ConnectionSpec\n * \n */\npublic interface ConnectionSpec {\n\t/**\n\t * @return\n\t */\n\tpublic InetAddress getAddress();\n\t/**\n\t * @param address\n     * @return the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setAddress(InetAddress address);\n\t/**\n\t * @return the port number for the connection\n\t */\n\tpublic int getPort ();\n\t/**\n\t * @param port\n     * @return the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setPort(int port);\n\t/**\n\t * @return the password (if any) for the connection.  Used on (re-)connect to authenticate \n\t * the client after connectivity has been established\n\t * @Redis AUTH  \n\t * @see Command#AUTH\n\t */\n\tpublic byte[] getCredentials();\n\t/**\n\t * Set the Connection's credentials, presented to Redis on (re)connects.\n\t * @param credentials\n\t * @see ConnectionSpec#setCredentials(String)\n     * @return the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setCredentials(byte[] credentials);\n\t/**\n\t * Convenience method \n\t * @param credentials\n\t * @see ConnectionSpec#setCredentials(byte[])\n     * @return the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setCredentials(String credentials);\n\t/**\n\t * @return the database selected for the connection.  Used on (re-)connect to select the db \n\t * after network connectivity has been established.\n\t * @Redis SELECT\n\t * @see Command#SELECT\n\t */\n\tpublic int getDatabase ();\n\t/**\n\t * @param database\n     * @return the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setDatabase(int database);\n\t/**\n\t * @return the {@link Modality} of this protocol handler.\n\t */\n\tpublic Modality getModality ();\n\t/**\n\t * @param modality\n\t * @return the the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setModality (Modality modality);\n\t/**\n\t * Get the {@link SocketFlag} for the {@link ConnectionSpec}\n\t * @param flag\n\t * @return the specified TCP socket flag used for the connection.\n\t * @see SocketFlag\n\t */\n\tpublic boolean getSocketFlag (Connection.Socket.Flag flag);\n\t/**\n\t * Set the {@link Connection.Socket.Flag} for the {@link ConnectionSpec}\n\t * @param flag\n\t * @param value\n\t * @return {@link ConnectionSpec} this\n\t */\n\tpublic ConnectionSpec setSocketFlag(Connection.Socket.Flag flag, Boolean value);\n\t/**\n\t * Get the {@link Connection.Socket.Property} for the {@link ConnectionSpec}\n\t * @param property\n\t * @return the specified socket property used for the connection.\n\t * @see SocketFlag\n\t */\n\tpublic Integer getSocketProperty (Connection.Socket.Property property);\n\t/**\n\t * Set the {@link SocketProperty} for the {@link ConnectionSpec}\n\t * @param property\n\t * @param value\n\t * @return the previous value (if any).  Null if none existed, per {@link Map#put(Object, Object)} semantics.\n\t */\n\tpublic ConnectionSpec setSocketProperty(Connection.Socket.Property property, Integer value);\n \t/**\n\t * @param flag\n\t * @return the {@link Connection.Flag}\n\t * @see SocketFlag\n\t */\n\tpublic boolean getConnectionFlag (Connection.Flag flag);\n\t/**\n\t * Sets the specified {@link Connection.Flag}\n\t * @param flag\n\t * @param value\n\t * @return the referenced {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setConnectionFlag(Connection.Flag flag, Boolean value);\n\t/**\n\t * @param <T>\n\t * @param proptype\n\t * @return\n\t */\n\tpublic Object getConnectionProperty(Property prop);\n\t/**\n\t * @param <T>\n\t * @param property\n\t * @param value\n\t * @return\n\t */\n\tpublic ConnectionSpec setConnectionProperty(Property prop, Object value);\n\t/**\n\t * @return\n\t */\n\tpublic int\tgetReconnectCnt ();\n\t/**\n\t * @param cnt\n\t * @return the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setReconnectCnt(int cnt);\n\t/**\n\t * @return\n\t */\n\tpublic int\tgetMaxConnectWait ();\n\t/**\n\t * @param cnt\n     * @return the {@link ConnectionSpec}\n\t */\n\tpublic ConnectionSpec setMaxConnectWait(int cnt);\n    /**\n     * @return the heartbeat period in seconds\n     */\n    public int\tgetHeartbeat();\n    /**\n     * @param seconds heartbeat period\n     * @return the {@link ConnectionSpec}\n     */\n    public ConnectionSpec setHeartbeat(int seconds);\n    \n\t// ------------------------------------------------------------------------\n\t// Reference Implementation \n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Reference implementation of {@link ConnectionSpec}.\n\t * <p>\n\t * This implementation is a read/write implementation providing no default\n\t * values of any kind.  It can be used as is and initialized as required,\n\t * or (as it is intended) it will provide support for various connection\n\t * profiles (e.g. server connectors), etc.\n\t *\n\t * @author  joubin (alphazero@sensesay.net)\n\t * @version alpha.0, Aug 23, 2009\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic static class RefImpl implements ConnectionSpec {\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Attributes\n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\t/** {@link Map} of the {@link SocketFlag}s of the {@link ConnectionSpec} */\n\t\tMap<Connection.Socket.Flag, Boolean> socketFlags = new HashMap<Connection.Socket.Flag, Boolean>();\n\t\t\n\t\t/** {@link Map} of the {@link SocketProperty}s of the {@link ConnectionSpec} */\n\t\tMap<Connection.Socket.Property, Integer> socketProperties = new HashMap<Connection.Socket.Property, Integer>();\n\t\t\n\t\t/** Connection.Flag bitmask */\n\t\tint\t\tconnectionFlagBitmask;\n\t\t\n\t\t/** {@link Map} of the {@link Connection.Flag}s of the {@link ConnectionSpec} */\n\t\tMap<Connection.Property, Object> connectionProperties = new HashMap<Connection.Property, Object>();\n\t\t\n\t\t/** heartbeat period in milliseconds */\n\t\tprivate int heartbeat;\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// Constructor(s)\n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// Interface\n\t\t// ------------------------------------------------------------------------\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getAddress() */\n\t\t@Override\n\t\tfinal public InetAddress getAddress () {\n\t\t\treturn (InetAddress) getConnectionProperty(Connection.Property.HOST);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getCredentials() */\n\t\t@Override\n\t\tfinal public byte[] getCredentials () {\n\t\t\treturn (byte[]) getConnectionProperty(Connection.Property.CREDENTIAL);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getDatabase() */\n\t\t@Override\n\t\tfinal public int getDatabase () {\n\t\t\treturn (Integer) getConnectionProperty(Connection.Property.DB);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getPort() */\n\t\t@Override\n\t\tfinal public int getPort () {\n\t\t\treturn (Integer) getConnectionProperty(Connection.Property.PORT);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getModality() */\n\t\tfinal public Modality getModality () { \n\t\t\treturn (Modality) getConnectionProperty(Connection.Property.MODALITY);\n\t\t}\n\t\t\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getMaxConnectWait() */\n\t\tfinal public int getMaxConnectWait () {\n\t\t\treturn (Integer) getConnectionProperty(Connection.Property.MAX_CONNECT_WAIT);\n\t\t}\n\t\t\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getReconnectCnt() */\n\t\t@Override\n\t\tfinal public int getReconnectCnt () {\n\t\t\treturn (Integer) getConnectionProperty(Connection.Property.MAX_CONNECT_ATTEMPT);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getSocketFlag(org.jredis.connector.ConnectionSpec.SocketFlag) */\n\t\t@Override\n\t\tfinal public boolean getSocketFlag (Connection.Socket.Flag flag) {\n\t\t\treturn socketFlags.get(flag);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getSocketProperty(org.jredis.connector.ConnectionSpec.SocketProperty) */\n\t\t@Override\n\t\tfinal public Integer getSocketProperty (Connection.Socket.Property property) {\n\t\t\treturn socketProperties.get(property);\n\t\t}\n        /* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getConnectionProperty(org.jredis.connector.Connection.Property) */\n\t\t@Override\n        final public Object getConnectionProperty(Property prop){\n\t\t\treturn connectionProperties.get(prop);\t\t\t\n\t\t}\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Property Setters\n\t\t// ------------------------------------------------------------------------\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setAddress(java.net.InetAddress) */\n\t\tfinal public ConnectionSpec setAddress (InetAddress address) {\n\t\t\tsetConnectionProperty(Connection.Property.HOST, address);\n        \treturn this;\n        }\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setPort(int) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setPort (int port) {\n\t\t\tsetConnectionProperty(Connection.Property.PORT, port);\n//        \tthis.port = port;\n        \treturn this;\n        }\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setCredentials(byte[]) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setCredentials (byte[] credentials) {\n\t\t\tsetConnectionProperty(Connection.Property.CREDENTIAL, credentials);\n        \treturn this;\n        }\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setCredentials(java.lang.String) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setCredentials (String credentials) {\n\t\t\tbyte[] bytes;\n\t\t\tif(credentials == null || credentials.length() == 0)\n\t\t\t\tbytes = null;\n\t\t\telse \n\t\t\t\tbytes = credentials.getBytes();\n        \treturn setCredentials(bytes);\n        }\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setDatabase(int) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setDatabase (int database) {\n\t\t\tsetConnectionProperty(Connection.Property.DB, database);\n        \treturn this;\n        }\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setReconnectCnt(int) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setReconnectCnt (int reconnectCnt) {\n\t\t\tsetConnectionProperty(Connection.Property.MAX_CONNECT_ATTEMPT, reconnectCnt);\n        \treturn this;\n        }\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setConnectionProperty(org.jredis.connector.Connection.Property, java.lang.Object) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setConnectionProperty(Property prop, Object value){\n\t\t\ttry {  connectionProperties.put(prop, value); }\n\t\t\tcatch (ClassCastException e){ throw new IllegalArgumentException(\"value type\", e);}\n\t\t\treturn this;\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setModality(org.jredis.connector.Connection.Modality) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setModality (Modality modality) {\n\t\t\tsetConnectionProperty(Connection.Property.MODALITY, modality);\n\t\t\treturn this;\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getMaxConnectWait(int) */\n\t\tfinal public ConnectionSpec setMaxConnectWait(int cnt) {\n\t\t\tsetConnectionProperty(Connection.Property.MAX_CONNECT_WAIT, cnt);\n\t\t\treturn this;\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setSocketFlag(org.jredis.connector.ConnectionSpec.SocketFlag, java.lang.Boolean) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setSocketFlag(Connection.Socket.Flag flag, Boolean value){\n\t\t\tsocketFlags.put(flag, value);\n\t\t\treturn this;\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setSocketProperty(org.jredis.connector.ConnectionSpec.SocketProperty, java.lang.Integer) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setSocketProperty(Connection.Socket.Property property, Integer value){\n\t\t\tsocketProperties.put(property, value);\n\t\t\treturn this;\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getConnectionFlag(org.jredis.connector.ConnectionSpec.ConnectionFlag) */\n\t\t@Override\n\t\tfinal public boolean getConnectionFlag (Connection.Flag flag){\n\t\t\treturn Connection.Flag.isSet(connectionFlagBitmask, flag);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setConnectionFlag(org.jredis.connector.ConnectionSpec.ConnectionFlag, java.lang.Boolean) */\n\t\t@SuppressWarnings(\"boxing\")\n\t\t@Override\n\t\tfinal public ConnectionSpec setConnectionFlag(Connection.Flag flag, Boolean value){\n\t\t\tconnectionFlagBitmask = \n\t\t\t\tvalue ? \n\t\t\t\t\t\tConnection.Flag.bitset(connectionFlagBitmask, flag) : \n\t\t\t\t\t\tConnection.Flag.bitclear(connectionFlagBitmask, flag);\n\t\t\treturn this;\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#getHeartbeat() */\n\t\t@Override\n\t\tfinal public int\tgetHeartbeat() {\n        \treturn heartbeat/1000;\n        }\n \t\t/* (non-Javadoc) @see org.jredis.connector.ConnectionSpec#setHeartbeat(int) */\n\t\t@Override\n\t\tfinal public ConnectionSpec setHeartbeat(int seconds) {\n        \tthis.heartbeat = seconds * 1000;\n        \treturn this;\n        }\n\t}\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/FaultedConnection.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport java.util.concurrent.Future;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\n\n/**\n * {@link FaultedConnection} is a support class for implementors of JRedis API.\n * \n * @optional\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 11, 2009\n * @since   alpha.0\n * \n */\npublic class FaultedConnection implements Connection {\n\n\t/**  */\n\tfinal private String\terrorMsg;\n\t/**  */\n\tfinal private ConnectionSpec connSpec;\n\n\t/**\n\t * instantiates a faulted connection for the given {@link ConnectionSpec}\n\t * @param connSpec\n\t * @param errMsg\n\t */\n\tpublic FaultedConnection (ConnectionSpec connSpec, String errMsg) {\n\t\tthis.errorMsg = errMsg;\n\t\tthis.connSpec = connSpec;\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#getSpec() */\n\t@Override\n\tpublic ConnectionSpec getSpec() {\n\t\treturn connSpec;\n\t}\n\t\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#serviceRequest(org.jredis.protocol.Command, byte[][]) */\n\t@Override\n\tpublic Response serviceRequest(Command cmd, byte[]... args) throws RedisException, ClientRuntimeException,\n\t\t\tProviderException \n\t{\n\t\tthrow new ClientRuntimeException (errorMsg);\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#queueRequest(org.jredis.protocol.Command, byte[][]) */\n\t@Override\n\tpublic Future<Response> queueRequest(Command cmd, byte[]... args)\n\t\t\tthrows ClientRuntimeException, ProviderException \n\t{\n\t\tthrow new ClientRuntimeException (errorMsg);\n\t}\n    /* (non-Javadoc) @see org.jredis.connector.Connection#addListener(org.jredis.connector.Connection.Listener) */\n\t@Override\n    final public boolean addListener (Listener connListener) {\n    \tthrow new NotSupportedException(\"Events not supported\");\n    }\n    /* (non-Javadoc) @see org.jredis.connector.Connection#removeListener(org.jredis.connector.Connection.Listener) */\n    @Override\n    final public boolean removeListener (Listener connListener) {\n    \tthrow new NotSupportedException(\"Events not supported\");\n    }\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/Message.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface Message {\n\t\n\t/**\n\t * Reads itself from the provided {@link InputStream}\n\t * \n\t * @param in the steam to read from.\n\t * \n\t * @throws ClientRuntimeException to indicate a system error, potentially network related\n\t * and hopefully recoverable.  Typically used to wrap and propagate the IO stream's thrown\n\t * {@link IOException}s.\n\t * \n\t * @throws ProviderException to indicate operational error not directly related to the stream,\n\t * and should be treated as a bug.\n\t */\n\tpublic void\tread (InputStream    in) throws ClientRuntimeException, ProviderException; \n\t\n\t/**\n\t * Writes itself to the provided {@link OutputStream}.\n\t * \n\t * @param out the stream to write to.\n\t * \n\t * @throws ClientRuntimeException to indicate a system error, potentially network related\n\t * and hopefully recoverable.  Typically used to wrap and propagate the IO stream's thrown\n\t * {@link IOException}s.\n\t * \n\t * @throws ProviderException to indicate operational error not directly related to the stream,\n\t * and should be treated as a bug.\n\t */\n\tpublic void\twrite (OutputStream  out)throws ClientRuntimeException, ProviderException; \n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/NotConnectedException.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis._specification;\n\n\n/**\n * This connection will should be thrown if users issue any calls on \n * the {@link JRedis} interface after a call to either {@link JRedis#quit()}\n * or {@link JRedis#shutdown()}\n * \n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n *\n */\npublic class NotConnectedException extends ClientRuntimeException {\n\t/**  */\n\tprivate static final long\tserialVersionUID\t= _specification.Version.major;\n\n\tpublic NotConnectedException (String msg) {\n\t\tsuper (msg);\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/RequestListener.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport org.jredis.protocol.Request;\nimport org.jredis.protocol.Response;\n\npublic interface RequestListener {\n\t\n\tpublic void onResponse (Object context, Request request, Response response);\n\t\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/connector/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * Native Client Interface Specification.  \n * <br>\n * This package depends on the Protocol package.\n * [TODO: document me!]\n * <p>\n * <i>This is an optional package.</i>\n */\npackage org.jredis.connector;"
  },
  {
    "path": "core/api/src/main/java/org/jredis/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * This package contains the constructs that define the Java API semantics of the\n * JRedis clients.\n * \n * TODO: elaborate on the spec requirements.\n * \n * @author joubin (alphazero@sensesay.net)\n * \n * @since       jredis-a.0\n * @compliance  redis-0.09\n * \n */\npackage org.jredis;"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/BulkResponse.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface BulkResponse extends Response {\n\t\n\t/**\n\t * @return\n\t */\n\tpublic byte[] getBulkData ();\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/Command.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\nimport org.jredis.Redis;\n\n/**\n * Redis commands, (~) verbatim. Each member of the Command enum maps to a \n * corresponding (protocol level) command in Redis.  Commands with optional\n * semantics are further distinguished: optional variants include \n * embedded '$').\n * \n * <p><b>specification</b> <code>Redis 1.00</code>\n * \n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09 (Redis 1.n)\n * @version alpha.0, 09/17/10 (Redis 2.n)\n * @since   alpha.0\n * \n */\n@Redis(versions={\"1.n\", \"2.0\"})\npublic enum Command {\n\t// security\n\tAUTH \t\t(RequestType.KEY, \t\t\tResponseType.STATUS),\n\t\n\t// connection handling\n\tPING \t\t(RequestType.NO_ARG, \t\tResponseType.STATUS), \n\tQUIT \t\t(RequestType.NO_ARG, \t\tResponseType.VIRTUAL), \n\tCONN_FLUSH \t(RequestType.NO_ARG, \t\tResponseType.NOP), \n\n\t// String values operations\n\tSET \t\t(RequestType.KEY_VALUE, \tResponseType.STATUS), \n\tGET \t\t(RequestType.KEY, \t\t\tResponseType.BULK), \n\tGETSET\t\t(RequestType.KEY_VALUE, \tResponseType.BULK), \n\tMGET\t\t(RequestType.MULTI_KEY, \tResponseType.MULTI_BULK), \n\tSETNX\t\t(RequestType.KEY_VALUE, \tResponseType.BOOLEAN),\n\tMSET\t\t(RequestType.BULK_SET, \t\tResponseType.STATUS), \n\tMSETNX\t\t(RequestType.BULK_SET, \t\tResponseType.BOOLEAN), \n\tINCR\t\t(RequestType.KEY, \t\t\tResponseType.NUMBER), \n\tINCRBY\t\t(RequestType.KEY_NUM,\t\tResponseType.NUMBER),  \n\tDECR\t\t(RequestType.KEY, \t\t\tResponseType.NUMBER), \n\tDECRBY\t\t(RequestType.KEY_NUM,\t\tResponseType.NUMBER),  \n\tEXISTS\t\t(RequestType.KEY, \t\t\tResponseType.BOOLEAN), \n\tDEL\t\t\t(RequestType.MULTI_KEY, \tResponseType.NUMBER), \n\tTYPE\t\t(RequestType.KEY, \t\t\tResponseType.STRING),\n\tSUBSTR\t\t(RequestType.KEY_NUM_NUM,\tResponseType.BULK),\n\tAPPEND\t\t(RequestType.KEY_VALUE, \tResponseType.NUMBER),\n\n\t// \"Commands operating on the key space\"\n\tKEYS\t\t(RequestType.KEY, \t\t\tResponseType.MULTI_BULK), \n\tKEYSTOLIST\t(RequestType.KEY_KEY, \t\tResponseType.NUMBER), \n\tRANDOMKEY\t(RequestType.NO_ARG,\t\tResponseType.BULK),\n\tRENAME\t\t(RequestType.KEY_KEY, \t\tResponseType.STATUS), \n\tRENAMENX\t(RequestType.KEY_KEY, \t\tResponseType.BOOLEAN), \n\tDBSIZE\t\t(RequestType.NO_ARG,\t\tResponseType.NUMBER),\n\tEXPIRE\t\t(RequestType.KEY_NUM,\t\tResponseType.BOOLEAN), \n\tEXPIREAT\t(RequestType.KEY_NUM,\t\tResponseType.BOOLEAN), \n\tTTL\t\t\t(RequestType.KEY,\t\t\tResponseType.NUMBER),\n\t\n\t// Commands operating on lists\n\tRPUSH\t\t(RequestType.KEY_VALUE,\t\tResponseType.NUMBER), \n\tRPUSHX\t(RequestType.KEY_VALUE,\t\tResponseType.NUMBER), \n\tLPUSH\t\t(RequestType.KEY_VALUE,\t\tResponseType.NUMBER),\n\tLPUSHX\t\t(RequestType.KEY_VALUE,\t\tResponseType.NUMBER),\n\tLINSERT\t(RequestType.BULK_SET,\t\tResponseType.NUMBER),\n\tLLEN\t\t(RequestType.KEY,\t\t\tResponseType.NUMBER), \n\tLRANGE\t\t(RequestType.KEY_NUM_NUM,\tResponseType.MULTI_BULK), \n\tLTRIM\t\t(RequestType.KEY_NUM_NUM,\tResponseType.STATUS),\n\tLINDEX\t\t(RequestType.KEY_NUM,\t\tResponseType.BULK), \n\tLSET\t\t(RequestType.KEY_IDX_VALUE,\tResponseType.STATUS), \n\tLREM\t\t(RequestType.KEY_CNT_VALUE,\tResponseType.NUMBER),\n\tLPOP\t\t(RequestType.KEY,\t\t\tResponseType.BULK), \n\tRPOP\t\t(RequestType.KEY,\t\t\tResponseType.BULK),\n\tRPOPLPUSH\t(RequestType.KEY_KEY,\t\tResponseType.BULK),\n\t\n\t// Commands operating on sets\n\tSADD\t\t(RequestType.KEY_VALUE,\t\tResponseType.BOOLEAN), \n\tSREM\t\t(RequestType.KEY_VALUE,\t\tResponseType.BOOLEAN), \n\tSCARD\t\t(RequestType.KEY,\t\t\tResponseType.NUMBER), \n\tSISMEMBER\t(RequestType.KEY_VALUE,\t\tResponseType.BOOLEAN), \n\tSINTER\t\t(RequestType.MULTI_KEY,\t\tResponseType.MULTI_BULK), \n\tSINTERSTORE (RequestType.MULTI_KEY,\t\tResponseType.STATUS),\n\tSUNION\t\t(RequestType.MULTI_KEY,\t\tResponseType.MULTI_BULK), \n\tSUNIONSTORE (RequestType.MULTI_KEY,\t\tResponseType.STATUS), \n\tSDIFF\t\t(RequestType.MULTI_KEY,\t\tResponseType.MULTI_BULK), \n\tSDIFFSTORE  (RequestType.MULTI_KEY,\t\tResponseType.STATUS),\n\tSMEMBERS\t(RequestType.KEY,\t\t\tResponseType.MULTI_BULK), \n\tSMOVE\t\t(RequestType.KEY_KEY_VALUE,\tResponseType.BOOLEAN),\n\tSRANDMEMBER (RequestType.KEY,  \t\t\tResponseType.BULK),\n\tSPOP     \t(RequestType.KEY,        \tResponseType.BULK),\n\t// Commands operating on sorted sets\n\tZADD\t\t(RequestType.KEY_IDX_VALUE,\tResponseType.BOOLEAN), \n\tZREM\t\t(RequestType.KEY_VALUE,\t\tResponseType.BOOLEAN),\n\tZCARD\t\t(RequestType.KEY,\t\t\tResponseType.NUMBER), \n\tZSCORE\t\t(RequestType.KEY_VALUE,\t\tResponseType.BULK),\n\tZRANK\t\t(RequestType.KEY_VALUE,\t\tResponseType.NUMBER),\n\tZREVRANK\t(RequestType.KEY_VALUE,\t\tResponseType.NUMBER),\n\tZRANGE\t\t\t(RequestType.KEY_NUM_NUM,\tResponseType.MULTI_BULK),\n\t/** ZRANGE with OPTIONS  */\n\tZRANGE$OPTS\t\t(RequestType.KEY_NUM_NUM_OPTS,\tResponseType.MULTI_BULK),\n\tZREVRANGE\t\t(RequestType.KEY_NUM_NUM,\t\tResponseType.MULTI_BULK),\n\t/** ZREVRANGE with OPTIONS  */\n\tZREVRANGE$OPTS\t(RequestType.KEY_NUM_NUM_OPTS,\tResponseType.MULTI_BULK),\n\tZINCRBY\t\t(RequestType.KEY_IDX_VALUE, ResponseType.BULK),\n\tZRANGEBYSCORE\t\t(RequestType.KEY_NUM_NUM,\tResponseType.MULTI_BULK),\n\tZRANGEBYSCORE$OPTS\t\t(RequestType.KEY_NUM_NUM_OPTS,\tResponseType.MULTI_BULK),\n\tZREMRANGEBYSCORE\t(RequestType.KEY_NUM_NUM,\tResponseType.NUMBER),\n\tZREMRANGEBYRANK\t(RequestType.KEY_NUM_NUM,\tResponseType.NUMBER),\n\tZCOUNT\t\t(RequestType.KEY_NUM_NUM, ResponseType.NUMBER),\n\t\t\n\t// Commands operating on bit sets\n\tSETBIT\t\t(RequestType.KEY_IDX_VALUE, ResponseType.NUMBER),\n\tGETBIT\t\t(RequestType.KEY_NUM, ResponseType.NUMBER),\n\t\n\t// Commands operating on hashes\n\tHSET \t\t(RequestType.KEY_KEY_VALUE, ResponseType.BOOLEAN),\n\tHGET \t\t(RequestType.KEY_VALUE, \tResponseType.BULK),\n\tHEXISTS \t(RequestType.KEY_VALUE, \tResponseType.BOOLEAN),\n\tHDEL \t\t(RequestType.KEY_VALUE, \tResponseType.BOOLEAN),\n\tHLEN \t\t(RequestType.KEY, \t\t\tResponseType.NUMBER),\n\tHKEYS \t\t(RequestType.KEY, \t\t\tResponseType.MULTI_BULK),\n\tHVALS \t\t(RequestType.KEY, \t\t\tResponseType.MULTI_BULK),\n\tHGETALL \t(RequestType.KEY, \t\t\tResponseType.MULTI_BULK),\n\tHINCRBY\t\t(RequestType.KEY_KEY_NUM, ResponseType.NUMBER),\n\t\n\t// transactional commands\n\tMULTI\t\t(RequestType.NO_ARG, \t\tResponseType.STATUS),\n\tEXEC\t\t(RequestType.NO_ARG, \t\tResponseType.RESULT_SET), // NEED NEW RESPONSE TYPE\n\tDISCARD\t\t(RequestType.NO_ARG, \t\tResponseType.STATUS),\n\t\n\t// \"Multiple databases handling commands\"\n\tSELECT\t\t(RequestType.KEY,\t\t\tResponseType.STATUS),\n\tFLUSHDB\t\t(RequestType.NO_ARG,\t\tResponseType.STATUS), \n\tFLUSHALL\t(RequestType.NO_ARG,\t\tResponseType.STATUS),\n\tMOVE\t\t(RequestType.KEY_NUM,\t\tResponseType.BOOLEAN),\n\t\n\t// Sorting\n\tSORT\t\t(RequestType.MULTI_KEY,\t\tResponseType.MULTI_BULK),\n\t/** SORT...STORE */\n\tSORT$STORE\t(RequestType.MULTI_KEY,\t\tResponseType.NUMBER),\n\t\n\t// Persistence control commands\n\tSAVE\t\t(RequestType.NO_ARG,\t\tResponseType.STATUS), \n\tBGSAVE\t\t(RequestType.NO_ARG,\t\tResponseType.STATUS), \n\tBGREWRITEAOF(RequestType.NO_ARG,\t\tResponseType.STRING), \n\tLASTSAVE\t(RequestType.NO_ARG,\t\tResponseType.NUMBER),\n\tSHUTDOWN\t(RequestType.NO_ARG, \t\tResponseType.VIRTUAL),\n\t\n\t// diagnostics commands\n\tECHO    \t(RequestType.VALUE,     \tResponseType.BULK),\n\tDEBUG\t\t(RequestType.KEY_KEY, \t\tResponseType.STRING), \n\t\n\t// Remote server control commands\n\tINFO\t\t(RequestType.NO_ARG, \t\tResponseType.BULK), \n\tMONITOR\t    (RequestType.NO_ARG, \t\tResponseType.VIRTUAL), // BUG: NOTE: TODO: not virtual ..\n\tSLAVEOF\t\t(RequestType.KEY_KEY, \t\tResponseType.STATUS),\n\t\n\t;// -- end --\n\t\n\t/** semantic sugar */\n\tpublic final String code;\n\tpublic final byte[] bytes;\n\tpublic final RequestType requestType;\n\tpublic final ResponseType responseType;\n\tprivate final int flags_bitset;\n\t\n\t/** internal */\n\tstatic final public String OPTCODE = \"$\";\n\t/**\n\t * Each enum member directly corresponds to a Redis command, per\n\t * specification.  Command semantics is specified by the element\n\t * constructor params.\n\t * @param reqType the {@link RequestType} of the Command\n\t * @param respType the {@link ResponseType} of the Command\n\t */\n\tCommand (RequestType reqType, ResponseType respType, Flag... flags) { \n\t\tthis.code = this.name();\n\t\t\n\t\tif(code.indexOf(OPTCODE) > 0) \n\t\t\tthis.bytes = code.substring(0, code.indexOf(OPTCODE)).getBytes();\n\t\telse\n\t\t\tthis.bytes = code.getBytes();\n\t\t\n\t\tthis.requestType = reqType;\n\t\tthis.responseType = respType;\n\t\t\n\t\tif(flags != null && flags.length > 0)\n\t\t\tthis.flags_bitset = Flag.bitset(flags);\n\t\telse\n\t\t\tthis.flags_bitset = Flag.OPAQUE_BITMASK_32;\n\t}\n\n\t/**\n\t * Tests if the specified flag is set for the command.\n\t * @param flag the flag\n\t * @return true if flag is set.\n\t * @see Command.Flag\n\t */\n\tfinal public boolean isSet(Flag flag) {\n\t\treturn (flags_bitset & flag.bitmask) != Flag.OPAQUE_BITMASK_32;\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Inner Types\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Redis Command Options and modifiers\n\t * \n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, Mar 20, 2010\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic enum Option {\n\t\tWITHSCORES,\n\t\tBY,\n\t\tLIMIT,\n\t\tGET,\n\t\tASC,\n\t\tDESC,\n\t\tALPHA,\n\t\tSTORE;\n\t\t/** semantic sugar */\n\t\tpublic final byte[] bytes;\n\t\tOption () {\n\t\t\tthis.bytes = name().getBytes();\n\t\t}\n\t}\n\t// TODO: wtf is this doing here?\n\t/**\n\t * Defines (32 bit) flags for {@link Command}\n\t *\n\t * @author  joubin (alphazero@sensesay.net)\n\t * @date    Sep 10, 2010\n\t * \n\t */\n\tpublic enum Flag {\n\t\tTEST,\n\t\tFOO,\n\t\tBAR,\n\t\t;// -- end --\n\t\tpublic final int bitmask;\n\t\tprivate static final int OPAQUE_BITMASK_32 = 0x0000;\n\t\tFlag (){\n\t\t\tthis.bitmask = (int)Math.pow(2, ordinal());\n\t\t}\n\t\tstatic final public int bitset(Flag...flags){\n\t\t\treturn bitset(OPAQUE_BITMASK_32, flags);\n\t\t}\n\t\tstatic final public int bitset(final int bitsetin, Flag...flags){\n\t\t\tint bitset = bitsetin;\n\t\t\tfor(Flag f : flags) bitset = bitset | f.bitmask;\n\t\t\treturn bitset;\n\t\t}\n\t\tpublic static boolean isSet(int bitset, Flag flag) {\n\t\t\treturn (bitset & flag.bitmask) > OPAQUE_BITMASK_32;\n\t\t}\n\t\tstatic final public int bitclear(final int bitsetin, Flag...flags){\n\t\t\tint bitset = bitsetin;\n\t\t\tfor(Flag f : flags) bitset = bitset ^ f.bitmask;\n\t\t\treturn bitset;\n\t\t}\n\t}\n    /**\n     * Broad Request Type categorization of the Redis Command per the request's\n     * argument signature.  These categories are a more differentiated than the\n     * Redis specification itself to impart further information about the argument\n     * semantics.\n\t *\n     * @author  Joubin (alphazero@sensesay.net)\n     * @version alpha.0, Aug 29, 2009\n     * \n     */\n    public enum RequestType {\n    \t/**  */\n    \tNO_ARG,\n    \t/**  */\n    \tKEY,\n    \t/**  */\n    \tVALUE,\n    \t/**  */\n    \tKEY_KEY,\n    \t/**  */\n    \tKEY_NUM,\n//    \t/**  */\n//    \tKEY_SPEC,\n    \t/**  */\n    \tKEY_NUM_NUM,\n    \t/** */\n    \tKEY_NUM_NUM_OPTS,\n    \t/**  */\n    \tKEY_VALUE,\n    \t/**  */\n    \tKEY_KEY_VALUE,\n    \t/**  */\n    \tKEY_IDX_VALUE,\n    \t/**  */\n    \tKEY_CNT_VALUE,  // TODO: this should be key value cnt ...\n    \t/**  */\n    \tMULTI_KEY,\n    \t/**  */\n    \tBULK_SET,\n    \t\n    \tKEY_KEY_NUM\n    }\n\n    /**\n     * Broad Response Type categorization of the Redis Command responses.\n     * <p>\n     * As with {@link RequestType}, there is further differentiation of the\n     * Redis response types to further inform the semantics.\n     * <p>\n     * Beyond that, there is also linkage between the {@link ResponseType} and\n     * its associated {@link Response} interface extension.\n     * \n     * @author  Joubin (alphazero@sensesay.net)\n     * @version alpha.0, Aug 29, 2009\n     * @see Response\n     */\n    public enum ResponseType {\n    \t/**  */\n    \tNOP (StatusResponse.class),\n    \t/**  */\n    \tVIRTUAL (StatusResponse.class),\n    \t/**  */\n    \tSTATUS (StatusResponse.class),\n    \t/**  */\n    \tQUEUED (StatusResponse.class),\n    \t/**  */\n    \tSTRING (ValueResponse.class),\n    \t/**  */\n    \tBOOLEAN (ValueResponse.class),\n    \t/**  */\n    \tNUMBER (ValueResponse.class),\n    \t/**  */\n    \tBULK (BulkResponse.class),\n    \t/**  */\n    \tMULTI_BULK (MultiBulkResponse.class),\n    \t/** */\n    \tRESULT_SET (Response.class),\n    \t;\n    \tpublic Class<? extends Response> respClass;\n    \t\n    \t/**\n    \t * For each {@link ResponseType} member, we specify the \n    \t * corresponding {@link Response} extension interface.\n    \t * @param respClass\n    \t */\n    \tResponseType (Class<? extends Response> respClass){\n    \t\tthis.respClass = respClass;\n    \t}\n    }\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/CommandNotImplemented.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\nimport org.jredis.ProviderException;\nimport org.jredis._specification;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic final class CommandNotImplemented extends ProviderException {\n\t/**  */\n\tprivate static final long serialVersionUID = _specification.Version.major;\n\t\n\t/**\n\t * @param command\n\t */\n\tpublic CommandNotImplemented (Command command) { super(command.code + \" is not supported!\");}\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/MultiBulkResponse.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\nimport java.io.InputStream;\nimport java.util.List;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\n\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface MultiBulkResponse extends Response {\n\t/**\n\t * @return the List of values returned from the server.  List may contain null elements,\n\t * reflecting '<b>nil</b>' values per redis specification.  The operation {@link List#size()} will return\n\t * the same number that is received from the server, with the exception\n\t *  \n\t * @throws ClientRuntimeException if data access is attempted before the response has been read, or,\n\t * if the provided {@link InputStream} presents any problems.\n\t *   \n\t * @throws ProviderException for any other errors beyond system level (stream, network, etc.) or\n\t * user errors (such as attempting getData before the response has been read.  \n\t */\n\tpublic List<byte[]>\t\tgetMultiBulkData () throws ClientRuntimeException, ProviderException;\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/Protocol.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.Message;\n\n\n/**\n * <p>\n * Protocol is effectively a {@link Message} factory.  Implementations of this interface\n * provides Message objects that read and write according to a specific Redis protocol\n * specification.\n * \n * <p>Implementations may use this interface to address issues regarding buffer management.\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface Protocol {\n\t\n\t/**\n\t * \n\t * @param version\n\t * @return\n\t */\n\tpublic boolean isCompatibleWithVersion (String version);\n\t\n\t/**\n\t * \n\t * @param cmd\n\t * @param args\n\t * @return\n\t * @throws ProviderException\n\t * @throws IllegalArgumentException\n\t */\n\tpublic Request createRequest (Command cmd, byte[]...args) throws ProviderException, IllegalArgumentException;\n\n\t/**\n\t * Creates a response object for the {@link Command} specified.  \n\t * <p><b>Note</b> that this {@link Response} object has not yet been read.\n\t * @param cmd the {@link Command} that will be responded to.\n\t * \n\t * @return the response object that is ready to be read from the network connection.\n\t * \n\t * @throws ClientRuntimeException if the command is invalid for this version of the protocol\n\t * @throws ProviderException if the command is not implemented\n\t * \n\t * @see Response\n\t * @See {@link Response#read(java.io.InputStream)}\n\t */\n\tpublic Response createResponse (Command cmd) throws ProviderException, ClientRuntimeException ;\n\n\t/**\n\t * EXPERIMENTAL \n\t * @param cmd\n\t * @param args\n\t * @return\n\t * @throws ProviderException\n\t * @throws IllegalArgumentException\n\t */\n\tpublic byte[] createRequestBuffer(Command cmd, byte[]...args) throws ProviderException, IllegalArgumentException;\n\t\n\tpublic interface Factory {\n\t\t/**\n\t\t * Creates a {@link Protocol} instance for a connection per the specified\n\t\t * {@link ConnectionSpec}\n\t\t * @param connSpec\n\t\t * @return the new {@link Protocol} instance.\n\t\t * @throws NotSupportedException\n\t\t */\n\t\tpublic Protocol newProtocol(ConnectionSpec connSpec) throws NotSupportedException;\n\t}\n\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/Request.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\nimport org.jredis.connector.Message;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface Request extends Message {/* nop */}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/Response.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\nimport java.io.InputStream;\nimport java.util.List;\n\nimport org.jredis.ProviderException;\nimport org.jredis.connector.Message;\n\n\n\n/**\n * [TODO: detail the requirements - this is wip.]\n * \n * <p>Response is a {@link Message} object that will read itself from a \n * {@link InputStream} upon demand.  It is provided by {@link Protocol}s\n * as the result of a call to {@link Protocol#createResponse(Command)}.\n * \n * A Response is a generalize contract and does not provide the necessary semantics \n * corresponding to the data for the various response possibilities (such as bulk data\n * to a collection, value to bytes, etc.)  \n * \n *<p>This specification also does not specify whether a response object can be\n * reused (to read the same command type response).  This is left to the provider\n * of the implementation.  If a provider does NOT wish to re-use responses,\n * they should raise a {@link ProviderException} in any subsequent calls to\n * {@link Response#read(InputStream)}.  This class, however, does not and will\n * not provide a 'reset' means.\n *  \n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface Response extends Message {\n\n\t// -------------------------------------------------------------------------\n\t// Properties\n\t// -------------------------------------------------------------------------\n\t/** \n\t * @return <b>true</b> if response was an error response.  \n\t */\n\tpublic boolean isError ();\n\t\n\t/** \n\t * @return {@link Response.Type} of this response. \n\t */\n\tpublic Type getType ();\n\n\n\t/**\n\t * @return\n\t */\n\tpublic ResponseStatus getStatus();\n\t\n\t/** \n\t * @return if response has been read.\n\t * @see Response#read(java.io.InputStream)\n\t */\n\tpublic boolean didRead ();\n\n\t\n\t// -------------------------------------------------------------------------\n\t// Associated type\n\t// ======================================================== Response.Type\n\t// -------------------------------------------------------------------------\n\t/**\n\t * A redis server responds with: \n\t * <ul>\n\t * <li>Status response - such as {@link Command#SET}\n\t * <li>Value Data (\"String\") - such as {@link Command#GET}\n\t * <li>Bulk Data - such as {@link Command#KEYS}\n\t * <li>Multi Bulk Data - such as {@link Command#LRANGE}\n\t * </ul>\n\t * <p>\n\t * This enum reflects these types and provides additional information regarding\n\t * the expected flavor of the response data.\n\t *\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, 04/02/09\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic enum Type{\n\t\t/**  */\n\t\tStatus \t  (ResponseStatus.class),\n\t\t/**  */\n\t\tValue \t  (Integer.class),\n\t\t/**  */\n\t\tBulk  \t  (byte[].class),\n\t\t/**  */\n\t\tMultiBulk (List.class);\n\t\t\n\t\t/**  */\n\t\tpublic final Class<?>\tdataClass;\n\t\t/** @return the data flavor. */\n\t\tpublic Class<?>   getDataClass() { return dataClass; }\n\t\t/**\n\t\t * @param clazz\n\t\t */\n\t\tType (Class<?> clazz){\n\t\t\tthis.dataClass = clazz;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/ResponseStatus.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic final class ResponseStatus {\n\n\t/** Status code enum -- error or ok */\n\tpublic enum Code { OK, ERROR, CIAO }\n\t\n\t/** \n\t * Hopefully we have many none error response statuses \n\t * and we don't want to keep instantiating them.  \n\t * Use this singleton instance for non-error status. \n\t */\n\tpublic static final ResponseStatus STATUS_OK = new ResponseStatus (ResponseStatus.Code.OK);\n\n\tpublic static final ResponseStatus\tSTATUS_CIAO\t= new ResponseStatus (ResponseStatus.Code.CIAO);\n\n\t/**  */\n\tprivate final Code\tcode;\n\t/**  */\n\tprivate\t\t  String msg;\n\n\t/**\n\t * @param code\n\t */\n\tpublic ResponseStatus(ResponseStatus.Code code) {\n\t\tthis.code = code;\n\t\tthis.msg = \"\";\n\t}\n\n\t/**\n\t * @param code\n\t * @param msg\n\t */\n\tpublic ResponseStatus(ResponseStatus.Code code, String msg) {\n\t\tthis.code = code;\n\t\tthis.msg = msg;\n\t}\n\n\tpublic ResponseStatus.Code code() { return code; }\n\tpublic String message() {return msg; }\n\tpublic boolean isError () { return this.code==Code.ERROR; }\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/StatusResponse.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\n/**\n * This is just a marker interface.  All responses include an implied or explicit status.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\n\npublic interface StatusResponse extends Response {/* nop */}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/ValueResponse.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\n\n/**\n * Formally, redis only returns \"integers\" as values, but in fact, an operation such as\n * {@link Command#RANDOMKEY} will return a key in a single line reply, and not a bulk reply.\n * (As of 04/02/09.  Ex randomkey response => +woof )\n * \n * <p>This class deals with all responses that are a single line responses distinct from 'status'\n * replies.  For now, this means the result is either a UTF-8 String <i>key</i> or <i>number</i>.\n * \n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic interface ValueResponse extends Response {\n\t/**\n\t * Redis number values are \"64bit signed integers\".  \n\t * @return\n\t * @throws IllegalStateException\n\t */\n\tpublic long getLongValue () throws IllegalStateException;\n\t\n\t/**\n\t * Its gone.  Everything is 64 bit signed integer now.\n\t * This is deprecated but kept in the initial release just in case things change on the Redis side.\n\t * @return\n\t * @throws IllegalStateException\n\t */\n//\t@Deprecated\n//\tpublic int getIntValue () throws IllegalStateException;\n\t\n\t/**\n\t * @return\n\t * @throws IllegalStateException\n\t */\n\tpublic String getStringValue () throws IllegalStateException;\n\t/**\n\t * @return\n\t * @throws IllegalStateException\n\t */\n\tpublic boolean getBooleanValue () throws IllegalStateException;\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/protocol/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * This package contains the constructs that reflect the Redis Protocol Specification\n * \n * TODO: elaborate on the spec requirements.\n * \n * @author joubin (alphazero@sensesay.net)\n * \n * @since       jredis-a.0\n * @compliance  redis-1.0\n * \n */\npackage org.jredis.protocol;"
  },
  {
    "path": "core/api/src/main/java/org/jredis/resource/Context.java",
    "content": "package org.jredis.resource;\n\nimport java.util.Set;\n\n/**\n * {@link Context<T>} provides basic context support for {@link Resource}s,\n * by providing methods for {@link String} parameter name/values and basic\n * namespace operations for generic {@link Object} types. \n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 16, 2009\n * @since   alpha.0\n * \n */\n\npublic interface Context {\n\tpublic String getParam (String key);\n\tpublic void setParam (String key, String value);\n\tSet<String> getParamsKeys();\n\n\tpublic Object get (String name);\n\tpublic void bind   (String name, Object value);\n\tpublic void rebind   (String name, Object value);\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/resource/Resource.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.resource;\n\n\n\n/**\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 16, 2009\n * @since   alpha.0\n * \n */\n\npublic interface Resource <T> {\n\t\n\t/**\n\t * @return the resource type specific interface.\n\t */\n\tpublic T getInterface();\n\t\n\t/**\n\t * Sets the resource context.\n\t * \n\t * @see Context<T>\n\t * @param context the context for this resource.\n\t * @throws ResourceException if the resource context provided is either insufficient, or, \n\t * if the new context (regardless of its utility) can not be used.  (For example, it already\n\t * has a context and re-setting of contexts is not supported or permissible.)\n\t */\n\tpublic void setContext (Context context) throws ResourceException;\n\t\n\t/**\n\t * @see Context<T>\n\t * @return the context for this resource. \n\t * @throws ResourceException if the resource for whatever reason can not (or will not)\n\t * return a reference to its context.  (Security considerations, for example.)\n\t */\n\tpublic Context getContext () throws ResourceException;\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/resource/ResourceException.java",
    "content": "package org.jredis.resource;\n\nimport org.jredis.ClientRuntimeException;\n\n/**\n * The overall superclass for resource related exceptions, itself an \n * extension of ClientRuntimeException.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 16, 2009\n * @since   alpha.0\n * \n */\npublic class ResourceException extends ClientRuntimeException {\n\n\n\t/**\n\t * @param message\n\t * @param cause\n\t */\n\tpublic ResourceException(String message, Throwable cause) {\n\t\tsuper(message, cause);\n\t}\n\n\t/**\n\t * @param message\n\t */\n\tpublic ResourceException(String message) {\n\t\tsuper(message);\n\t}\n\n\t/**  */\n\tprivate static final long serialVersionUID = _specification.Version.major;\n\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/resource/_specification.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.resource;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 16, 2009\n * @since   alpha.0\n * \n */\n\npublic interface _specification {\n\t\n\t/** specification level */\n\tpublic interface Version {\n\t\t/** currently at toplevel spec version */\n\t\tlong\tmajor\t= org.jredis._specification.Version.major;\n\t\t/** currently at toplevel spec version */\n\t    long \tminor\t= org.jredis._specification.Version.minor;\n\t}\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/resource/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * Optional package.\n * <p>\n * This package provides the necessary types to support non-trivial usage of JRedis\n * implementation artifacts as resources in the JRedis usage contexts.\n */\npackage org.jredis.resource; "
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/BasicCodecManager.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.semantics;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.jredis.Codec;\n\n// REFACTOR: this doesn't belong here\n//\npublic final class BasicCodecManager implements CodecManager {\n\tprivate final Map<Class<?>, Codec<?>> map = new ConcurrentHashMap<Class<?>, Codec<?>>();\n\tpublic void foo () {\n\t\tCodec<String>  stringCodec = null;\n\t\tmap.put(String.class, stringCodec);\n\t}\n\n\t@SuppressWarnings(\"unchecked\")\n\t@Override\n\tpublic <T> Codec<T> getCodec(Class<T> type) {\n\t\treturn (Codec<T>) map.get(type);\n\t}\n\n\t@Override\n\tpublic <T> boolean register(Codec<T> code, Class<T> type) {\n\t\tCodec<?> existing = map.get(type);\n\t\tif(null == existing){\n\t\t\tif (code.supports(type)){\n\t\t\t\tmap.put(type, code);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/CodecManager.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.semantics;\n\nimport org.jredis.Codec;\nimport org.jredis.JRedis;\n\n/**\n * A CodecManager maintains a mapping of Java types to {@link Codec} instances\n * and can be used by a {@link JRedis} implementation to support the optional semantic\n * methods.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 14, 2009\n * @since   alpha.0\n * \n */\n\npublic interface CodecManager {\n\tpublic <T> Codec<T>\t\tgetCodec(Class<T> type);\n\tpublic <T>\tboolean \tregister (Codec<T> code, Class<T> type);\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/KeyCodec.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n// TODO: this is the wrong package -- we'll need something either under\n// \n\npackage org.jredis.semantics;\n\nimport org.jredis.Codec;\n\n/**\n * Encoding and decoding keys is a significant (but not major) performance bottleneck.   \n * <p>\n * A KeyCodec is a {@link String} {@link Codec} that is tasked\n * with the optimal performance of encoding and decoding String keys\n * for use by connector implementations that support such extended\n * mechanisms.\n * <p>\n * This interface is projected to be implemented by a key caching\n * mechanism suitable for employment in usage scenarios where a finite\n * set of keys is repeatedly employed to accomplish domain specific tasks.\n * <p>\n * For example, a common Redis pattern is the use of atomic counters to\n * increment IDs.  Whenever this pattern is used, the key for the ID(s)\n * will be <i>repeatedly</i> encoded and decoded by a non-optimized client\n * which can not make indiscriminate decisions regarding such optimizations.\n * <p>\n * A key cache, implementing {@link KeyCodec}, for example, can be used to indicate to\n * the client that for keys, the default codec (which is basically delegating to\n * {@link String}'s {@link String#getBytes()} and {@link String#String(byte[], int, int)})\n * should not be used and that the client should use the object implementing this\n * to accomplish the same task.   \n * <p>\n * This is just a marker interface beyond that.\n * \n *  \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 15, 2009\n * @since   alpha.0\n * \n */\n\npublic interface KeyCodec<K extends Object> extends Codec<K> {/* nop */}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/SemanticJRedis.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.semantics;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.jredis.JRedis;\nimport org.jredis.RedisException;\nimport org.jredis.RedisType;\n\n/**\n * This interface is certainly optional, and as of now simply an idea\n * that needed to be put in place for review and feedback.\n * \n * [TODO: think about me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 14, 2009\n * @since   alpha.0\n * \n */\n\npublic interface SemanticJRedis <T> /* extends JRedis */\nextends CodecManager {\n\n\t// ------------------------------------------------------------------------\n\t// Semantic context methods\n\t// ------------------------------------------------------------------------\n\n\n\t// ------------------------------------------------------------------------\n\t// Security and User Management\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Required for authorizing access to the server.  This method implements\n\t * the AUTH command.  It may be used with a non-secured server without\n\t * any side effect.\n\t * \n\t * @param authorization key as defined in the server.\n\t * @throws RedisException if the server is in secure more and the \n\t * authorization provided \n\t */\n\tpublic JRedis auth (String authorization) throws RedisException;\n\n\t// ------------------------------------------------------------------------\n\t// \"Connection Handling\"\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Ping redis\n\t * @return true (unless not authorized)\n\t * @throws RedisException (as of ver. 0.09) in case of unauthorized access\n\t */\n\tpublic JRedis ping () throws RedisException;\n\tpublic void quit ();\n\n\t// ------------------------------------------------------------------------\n\t// \"Commands operating on string values\"\n\t// ------------------------------------------------------------------------\n\n\tpublic void set (String key, T value) throws RedisException;\n\n\tpublic boolean setnx (String key, T value) throws RedisException;\n\n\tpublic T get (String key)  throws RedisException;\n\n\tpublic List<T> mget(String key, String...moreKeys) throws RedisException;\n\n\tpublic long incr (String key) throws RedisException;\n\tpublic long incrby (String key, int delta) throws RedisException;\n\tpublic long decr (String key) throws RedisException;\n\tpublic long decrby (String key, int delta) throws RedisException;\n\n\tpublic boolean exists(String key) throws RedisException;\n\tpublic boolean del (String key) throws RedisException;\n\tpublic RedisType type (String key) throws RedisException;\n\n\n\t// ------------------------------------------------------------------------\n\t// \"Commands operating on the key space\"\n\t// ------------------------------------------------------------------------\n\n\tpublic List<String> keys () throws RedisException;\n\tpublic List<String> keys (String pattern) throws RedisException;\n\tpublic String randomkey() throws RedisException;\n\tpublic String rename (String oldkey, String newkey) throws RedisException;\n\tpublic boolean renamenx (String oldkey, String brandnewkey) throws RedisException;\n\tpublic long dbsize () throws RedisException;\n\tpublic boolean expire (String key, int ttlseconds) throws RedisException; \n\t// ------------------------------------------------------------------------\n\t// Commands operating on lists\n\t// ------------------------------------------------------------------------\n\n\tpublic void rpush (String listkey, T value) throws RedisException;\n\tpublic void lpush (String listkey, T value) throws RedisException;\n\tpublic void lset (String key, int index, T value) throws RedisException;\n\tpublic long lrem (String listKey, T value,       int count) throws RedisException;\n\tpublic long llen (String listkey) throws RedisException;\n\tpublic List<T> lrange (String listkey, int from, int to) throws RedisException; \n\tpublic void ltrim (String listkey, int keepFrom, int keepTo) throws RedisException;\n\tpublic T lindex (String listkey, int index) throws RedisException;\n\tpublic T lpop (String listKey) throws RedisException;\n\tpublic T rpop (String listKey) throws RedisException;\n\n\t// ------------------------------------------------------------------------\n\t// Commands operating on sets\n\t// ------------------------------------------------------------------------\n\n\tpublic boolean sadd (String setkey, T member) throws RedisException;\n\tpublic boolean srem (String setKey, T member) throws RedisException;\n\tpublic boolean sismember (String setKey, T member) throws RedisException;\n\tpublic long scard (String setKey) throws RedisException;\t\n\tpublic List<T> sinter (String set1, String...sets) throws RedisException;\n\tpublic void sinterstore (String destSetKey, String...sets) throws RedisException;\n\tpublic List<T> smembers (String setkey) throws RedisException;\n\n\t// ------------------------------------------------------------------------\n\t// Multiple databases handling commands\n\t// ------------------------------------------------------------------------\n\n\tpublic JRedis select (int index) throws RedisException;\n\tpublic JRedis flushdb () throws RedisException;\n\tpublic JRedis flushall () throws RedisException;\n\tpublic boolean move (String key, int dbIndex) throws RedisException;\n\n\t// ------------------------------------------------------------------------\n\t// Sorting\n\t// ------------------------------------------------------------------------\n\n\tpublic SemanticSort<T> sort(String key);\n\n\t// ------------------------------------------------------------------------\n\t// Persistence control commands\n\t// ------------------------------------------------------------------------\n\n\tpublic void save() throws RedisException;\n\tpublic void bgsave () throws RedisException;\n\tpublic long lastsave () throws RedisException;\n\tpublic void shutdown () throws RedisException;\n\n\t//------------------------------------------------------------------------\n\t//Remote server control commands\n\t//------------------------------------------------------------------------\n\n\tpublic Map<String, String>\tinfo ()  throws RedisException;\n}"
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/SemanticQuery.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.semantics;\n\nimport java.util.List;\n\nimport org.jredis.RedisException;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 14, 2009\n * @since   alpha.0\n * \n */\n\npublic interface SemanticQuery <T> /*extends Query*/ {\n\tpublic List <T> exec () throws IllegalStateException, RedisException;\t\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/SemanticSort.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.semantics;\n\nimport org.jredis.Sort;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 14, 2009\n * @since   alpha.0\n * \n */\n\npublic interface SemanticSort <T> extends Sort {/* nop */}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/Semantics.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.semantics;\n\nimport org.jredis.NotSupportedException;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 14, 2009\n * @since   alpha.0\n * \n */\n\npublic interface Semantics extends CodecManager{\n\tpublic <T> SemanticJRedis<T>  forType (Class<T>  type) throws NotSupportedException;\n\t\n}\n"
  },
  {
    "path": "core/api/src/main/java/org/jredis/semantics/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * This package is optional.  Its entirely debatable whether such mechanisms\n * have any legitimate place in JRedis, which is a connector to a type-less\n * system storing blobs of bytes.  At this intial point, its place here simply\n * serves the purpose of keeping the issues that this package attempts to address\n * in mind.\n * <p>\n * When all is said and done, all these artifacts will provide little more than\n * what a helper or wrapper object will provide -- JRedis can not be in the\n * type management business, as it does not control the object store.\n */\npackage org.jredis.semantics;"
  },
  {
    "path": "core/api/src/main/resources/META-INF/redis-commands-2.4.n.txt",
    "content": "auth\nping\necho\nset\nsetnx\nsetex\nget\ndel\nexists\nsetbit\ngetbit\nsetrange\ngetrange\nincr\ndecr\nincrby\ndecrby\nselect\nrandomkey\nkeys\ndbsize\nlastsave\nsave\nbgsave\nbgrewriteaof\nshutdown\nmove\nrename\nrenamenx\nlpush\nrpush\nlpushx\nrpushx\nlinsert\nlpop\nrpop\nllen\nlindex\nlrange\nltrim\ntype\nlset\nsadd\nsrem\nsmove\nsismember\nscard\nspop\nsrandmember\nsinter\nsinterstore\nsunion\nsunionstore\nsdiff\nsdiffstore\nsync\nflushdb\nflushall\nsort\nlrem\nrpoplpush\ninfo\nmget\nmonitor\nexpire\nexpireat\ngetset\nttl\npersist\nslaveof\ndebug\nmset\nmsetnx\nzadd\nzincrby\nzrange\nzrangebyscore\nzrevrangebyscore\nzcount\nzrevrange\nzcard\nzrem\nzscore\nzremrangebyscore\nmulti\nexec\ndiscard\nblpop\nbrpop\nbrpoplpush\nappend\nstrlen\nzrank\nzrevrank\nhset\nhsetnx\nhget\nhmset\nhmget\nhdel\nhlen\nzremrangebyrank\nzunionstore\nzinterstore\nhkeys\nhvals\nhgetall\nhexists\nconfig\nhincrby\nsubscribe\nunsubscribe\npsubscribe\npunsubscribe\npublish\nwatch\nunwatch\nobject\nclient\n"
  },
  {
    "path": "core/api/src/test/java/org/jredis/TestBase.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis;\n\nimport static org.testng.Assert.fail;\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.LogFactory;\nimport org.testng.Assert;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 10, 2010\n * \n */\n\npublic class TestBase {\n\n\t// ------------------------------------------------------------------------\n\t// Shared resources\n\t// ------------------------------------------------------------------------\n\t/**  */\n\tfinal protected Log log = LogFactory.getLog(TestBase.class);\n\t\n\t// ------------------------------------------------------------------------\n\t// Test support \n\t// ------------------------------------------------------------------------\n\t/**\n\t * @param <T>\n\t * @param test\n\t * @param errtype\n\t */\n\tprotected final <T extends RuntimeException> void assertDidRaiseRuntimeError (Runnable test, Class<T> errtype){\n\t\tboolean didRaiseError = false;\n\t\ttry { test.run(); }\n\t\tcatch (RuntimeException t){\n\t\t\tif(errtype.isAssignableFrom(t.getClass()))\n\t\t\t\tdidRaiseError = true; \n\t\t}\n\t\tcatch (Exception e){ fail(\"Unexpected exception\", e); }\n\t\tfinally {\n\t\t\tif(!didRaiseError) { fail(\"Failed to raise expected RuntimeError \" + errtype.getCanonicalName()); }\n\t\t}\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Test support - mildly enhanced TESTNG Assert semantics\n\t// ------------------------------------------------------------------------\n\t// notNull\n\tpublic static void assertNotNull(Object object, String msgfmt, Object...optionalFmtArgs){\n\t\tString message = String.format(msgfmt, optionalFmtArgs);\n\t\tAssert.assertNotNull (object, message);\n\t}\n\t// null\n\tpublic static void assertNull(Object object, String msgfmt, Object...optionalFmtArgs){\n\t\tString message = String.format(msgfmt, optionalFmtArgs);\n\t\tAssert.assertNull (object, message);\t\t// << has bug.  reports a boolean comp result -- TODO: fix and patch.\n\t}\n\t\n\t// equals\n\tpublic static void assertEquals(Object actual, Object expected, String msgfmt, Object...optionalFmtArgs){\n\t\tString message = String.format(msgfmt, optionalFmtArgs);\n\t\tAssert.assertEquals (actual, expected, message);\t\t\n\t}\n\tpublic static void assertEquals(byte[] actual, byte[] expected, String msgfmt, Object...optionalFmtArgs){\n\t\tString message = String.format(msgfmt, optionalFmtArgs);\n\t\tAssert.assertEquals (actual, expected, message);\t\t\n\t}\n\t\n\t// true/false\n\tpublic static void assertTrue(boolean condition, String msgfmt, Object...optionalFmtArgs){\n\t\tString message = String.format(msgfmt, optionalFmtArgs);\n\t\tAssert.assertTrue (condition, message);\n\t}\n\tpublic static void assertFalse(boolean condition, String msgfmt, Object...optionalFmtArgs){\n\t\tString message = String.format(msgfmt, optionalFmtArgs);\n\t\tAssert.assertFalse (condition, message);\n\t}\n}\n"
  },
  {
    "path": "core/api/src/test/java/org/jredis/compliance/CheckRedisCompliance.java",
    "content": "/*\n *   Copyright 2009-2012 Joubin Houshyar\n * \n *   This file is part of JRedis.\n *\n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.compliance;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport org.jredis.JRedis;\nimport org.jredis.JRedisFuture;\n\n/**\n * Informal.  A munge of redis.h is used to produce the canonical\n * Redis commands for a given Redis release.  This program reflects\n * over JRedis to determine missing commands.\n * <p>\n * TODOS: \n * <li>need to address minor variations introduced for Java readability.</li>\n * <li>beef up annotations to tighten up the compliance check</li>\n * <li>apt cycle on release would be best</li>\n * \n * \n * @author Joubin Houshyar <alphazero@sensesay.net>\n * @date:  Feb 1, 2012\n */\npublic class CheckRedisCompliance {\n\t// TODO: drive this via annotation on the JRedis interface \n\tstatic final String spec_file_path = \"META-INF\";\n\tstatic final String spec_file_prefix = \"redis-commands\";\n\tstatic final String spec_file_ext = \"txt\";\n\tfinal int major;\n\tfinal int minor;\n\tfinal InputStream specfilein;\n\t// ------------------------------------------------------------------------\n\t// Constructor\n\t// ------------------------------------------------------------------------\n\t/** \n\t * @throws Exception  \n\t */\n\tpublic CheckRedisCompliance(int major, int minor) throws Exception {\n\t\tthis.major = major;\n\t\tthis.minor = minor;\n\t\tspecfilein = getSpecFileInputStream(major, minor);\n\t}\n\tprivate void run() throws Exception {\n\t\tList<String> cmdlist = getSpecCommandList();\n\t\tcheckAndReportCompliance(cmdlist, JRedis.class);\n\t\tcheckAndReportCompliance(cmdlist, JRedisFuture.class);\n\t}\n\tprivate List<String> checkAndReportCompliance(List<String> cmdlist, Class<?> jredis_class) {\n\t\tMethod[] pubmethods = jredis_class.getMethods();\n\t\tSet<String> uniqueMethodNames = new HashSet<String>();\n\t\tfor(Method m : pubmethods)\n\t\t\tuniqueMethodNames.add(m.getName());\n\t\t\t\n\t\tList<String> notsupported = new ArrayList<String>();\n\t\tfor(String cmd : cmdlist) {\n\t\t\tif(!uniqueMethodNames.contains(cmd))\n\t\t\t\tnotsupported.add(cmd);\n\t\t}\n\t\tif(!notsupported.isEmpty()) {\n\t\t\treportNonCompliance(notsupported, jredis_class.getSimpleName());\n\t\t}\n\t\t\t\n\t\treturn notsupported;\n\t}\n\tprivate void reportNonCompliance(List<String> notsupported, String simpleName) {\n\t\tSystem.out.format(\"\\n /// non-compliance report for %-12s //////////////\\n\", simpleName);\n\t\tint i = 0;\n\t\tfor(String cmd : notsupported){\n\t\t\tSystem.out.format(\"[%2d] %s\\n\",i++, cmd);\n\t\t}\n\t\tSystem.out.format(\"\\n /////////////////////////////////////////////////////////\\n\", simpleName);\n\t}\n\tprivate List<String> getSpecCommandList() throws IOException {\n\t\tList<String> cmdlist = new ArrayList<String>();\n\t\tBufferedReader reader = new BufferedReader(new InputStreamReader(specfilein));\n\t\tString cmd = null;\n\t\twhile((cmd=reader.readLine()) != null){\n\t\t\tcmdlist.add(cmd);\n\t\t}\n\t\treturn cmdlist;\n\t}\n\tprivate static InputStream getSpecFileInputStream(int major, int minor) {\n\t\tString fname = \n\t\t\tString.format(\"%s%s%s-%d.%d.n.%s\",\n\t\t\t\tspec_file_path, File.separator,spec_file_prefix,  major, minor, spec_file_ext)\n\t\t\t      .toString();\n\t\tInputStream in = JRedis.class.getClassLoader().getResourceAsStream(fname);\n\t\tif(in == null){\n\t\t\tString errmsg = String.format(\"No spec file found: <%s>\", fname).toString();\n\t\t\tthrow new IllegalArgumentException(errmsg);\n\t\t}\n\t\treturn in;\n\t}\n\tpublic static void main(String[] args) {\n\t\ttry {\n\t\t\tnew CheckRedisCompliance(2, 4).run();\n\t\t} catch (Exception e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/api/src/test/java/org/jredis/connector/TestSpecElements.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.connector;\n\nimport org.jredis.TestBase;\nimport org.jredis.connector.Connection.Flag;\nimport org.testng.annotations.Test;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 12, 2010\n * \n */\n\npublic class TestSpecElements extends TestBase{\n\t\n\t/**\n\t * [Doc this baby]\n\t */\n\t@Test\n\tpublic void testConnectionFlags() {\n\t\tlog.info(\"TEST:CONNECTOR spec semantics - ConnectionFlags\");\n\t\t\n\t\tFlag flags[] = {Flag.CONNECT_IMMEDIATELY, Flag.SHARED, Flag.RELIABLE};\n        int bitset = Flag.bitset(flags);\n        for(Flag f : flags)\n        \tassertTrue(Flag.isSet(bitset, f), \"%s should have been set!\\n\", f.name());\n        int oldbitset = bitset;\n        \n        bitset = Flag.bitclear(bitset, flags[1]);\n        assertFalse(bitset == oldbitset, \"clearing flag should have changed bitset\");\n        assertFalse(Flag.isSet(bitset, flags[1]), \"%s should have been cleared!\\n\", flags[1].name() );\n        \n        int bitset2 = 0x0000;\n    \tbitset2 = Flag.bitset(bitset2, flags);\n        for(Flag f : flags)\n        \tassertTrue(Flag.isSet(bitset2, f), \"%s should have been set!\\n\", f.name());\n\t}\n\t/**\n\t * Test the equivalence of\n\t * {@link ConnectionSpec#setCredentials(byte[])} and {@link ConnectionSpec#setCredentials(String)}\n\t * using {@link ConnectionSpec#getCredentials()} \n\t */\n\t@Test\n\tpublic void testCredentialsOverloads () {\n\t\tString property = Connection.Property.CREDENTIAL.name();\n\t\tlog.info(String.format(\"TEST:CONNECTOR spec semantics - Credentials %s\", property));\n\t\t\n\t\t// check with actual passwords\n\t\t//\n\t\tString password = \"jredis\";\n\t\tbyte[] credentials = password.getBytes();\n\t\t\n\t\tConnectionSpec spec = new ConnectionSpec.RefImpl();\n\t\tassertNull(spec.getCredentials(), \"RefImpl should not have defined: %s\", property);\n\t\t\n\t\tspec.setCredentials(password.getBytes());\n\t\tbyte[] credentials_1 = spec.getCredentials();\n\t\tassertNotNull(credentials_1, \"RefImpl.setCredentials (byte[]) did not set: %s\", property);\n\t\t\n\t\t// use the String variant\n\t\t//\n\t\tspec.setCredentials(password);\n\t\tbyte[] credentials_2 = spec.getCredentials();\n\t\tassertNotNull(credentials_2, String.format(\"RefImpl.setCredentials(String) did not set: %s\", property));\n\n\t\t// compare them\n\t\tassertEquals(credentials_2, credentials_1, String.format(\"Overloaded methods for %s setter are not equivalent.\", property));\n\t\t\n\t\t// check for treatment of empty strings -- should be equivalent to null byte[]\n\t\t//\n\t\tspec = new ConnectionSpec.RefImpl();  // ASSUMPTION: tested above for null default value.\n\t\tpassword = \"\";\n\t\tspec.setCredentials(password);\n\t\tassertNull(spec.getCredentials(), \"RefImpl should not have set \\\"\\\" (empty) credential to non-null value: %s\", property);\n\t}\n}\n"
  },
  {
    "path": "core/api/src/test/java/org/jredis/protocol/TestCommand.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.protocol;\n\nimport org.jredis.TestBase;\nimport static org.jredis.protocol.Command.Flag.*;\n\nimport org.jredis.protocol.Command.Flag;\nimport org.testng.Assert;\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 11, 2010\n * \n */\n\npublic class TestCommand extends TestBase {\n\t@Test\n\tpublic void testCommandSemanticsRequestType () {\n\t\tlog.info(\"TEST:PROTOCOL Command sematics - RequestType\");\n\t\tfor(Command c : Command.values()){\n\t\t\tassertTrue(new String(c.bytes).indexOf(Command.OPTCODE) == -1, \"Command bytes must not include control characters.\");\n\t\t}\n\t}\n\t@Test\n\tpublic void testCommandFlags() {\n\t\tlog.info(\"TEST:PROTOCOL Command sematics - CommandFlags\");\n\t\tFlag flags[] = {TEST, FOO, BAR};\n        int bitset = Flag.bitset(flags);\n        for(Flag f : flags)\n        \tAssert.assertTrue(Flag.isSet(bitset, f), String.format(\"%s should have been set!\\n\", f.name()));\n        int oldbitset = bitset;\n        \n        bitset = Flag.bitclear(bitset, flags[1]);\n        Assert.assertFalse(bitset == oldbitset, \"clearing flag should have changed bitset\");\n        Assert.assertFalse(Flag.isSet(bitset, flags[1]), String.format(\"%s should have been cleared!\\n\", flags[1].name()));\n\t}\n}\n"
  },
  {
    "path": "core/api/src/test/resources/log4j.properties",
    "content": "# Configure logging for testing\nlog4j.rootLogger=DEBUG, stdout, logfile\n\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.layout=org.apache.log4j.PatternLayout\nlog4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c] - %m%n\n\nlog4j.appender.logfile=org.apache.log4j.RollingFileAppender\nlog4j.appender.logfile.File=target/log/jredis-api-test.log\nlog4j.appender.logfile.MaxFileSize=512KB\n\nlog4j.appender.logfile.MaxBackupIndex=1\n\n# Pattern to output: date priority [category] - message\nlog4j.appender.logfile.layout=org.apache.log4j.PatternLayout\nlog4j.appender.logfile.layout.ConversionPattern=%d %-5p [%c] - %m%n\n"
  },
  {
    "path": "core/bench/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "core/bench/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "core/bench/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<!-- parent -->\n\t<parent>\n\t\t<groupId>org.jredis</groupId>\n\t\t<artifactId>jredis-core</artifactId>\n\t\t<version>a.0-SNAPSHOT</version>\n\t</parent>\n\n\t<!-- production | jar -->\n\t<name>JRedis - Core - BENCH</name>\n\t<groupId>org.jredis</groupId>\n\t<artifactId>jredis-core-bench</artifactId>\n\t<version>a.0-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\t<dependencies>\n\n\t\t<!-- api -->\n\t\t<dependency>\n\t\t\t<groupId>org.jredis</groupId>\n\t\t\t<artifactId>jredis-core-api</artifactId>\n\t\t\t<version>a.0-SNAPSHOT</version>\n\t\t</dependency>\n\n\t\t<!-- ri -->\n\t\t<dependency>\n\t\t\t<groupId>org.jredis</groupId>\n\t\t\t<artifactId>jredis-core-ri</artifactId>\n\t\t\t<version>a.0-SNAPSHOT</version>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-assembly-plugin</artifactId>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>simple-install</id>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>attached</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t\t<configuration>\n\t\t\t\t\t<descriptorRefs>\n\t\t\t\t\t\t<descriptorRef>jar-with-dependencies</descriptorRef>\n\t\t\t\t\t</descriptorRefs>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n</project>\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/bench/JRedisBenchmark.java",
    "content": "/*\n *   Copyright 2009 Joubin Mohammad Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.bench;\n\nimport static org.jredis.bench.Util.getRandomString;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n//import org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\n//import org.jredis.RedisException;\n//import org.jredis.bench.Util.Timer;\n//import org.jredis.protocol.Command;\n//\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.RedisException;\nimport org.jredis.bench.Util.Timer;\nimport org.jredis.protocol.Command;\n\n/**\n * Runs a few benchmarks for the {@link SocketConnection}, using a concurrent set of workers, each with its own\n * unique connection to the Redis server.  \n *  \n * @author Joubin Houshyar (alphazero@sensesay.net)\n */\npublic abstract class JRedisBenchmark {\n\t\n\t/** password used to AUTH with redis select -- password is: jredis */\n\tpublic static final String password = \"jredis\";\n\n\t// ------------------------------------------------------------------------\n\t// Helper methods\n\t// ------------------------------------------------------------------------\n\n\t// ------------------------------------------------------------------------\n\t// For test data \n\t// ------------------------------------------------------------------------\n\tfinal static Random \t\trandom = new Random(System.currentTimeMillis());\n\t\n\t/**  */\n\tbyte[] \t\t\tfixedbytes;\n\n\t/**  */\n\tstatic List<String>\t\tstringList = new ArrayList<String>();\n\t\t\n\tprotected boolean quitOnRunEnd = true;\n\t/**\n     * @param b\n     */\n    protected void quitOnRunEnd (boolean flag) { this.quitOnRunEnd = flag; }\n\t// ------------------------------------------------------------------------\n\t// Extension Points\n\t// ------------------------------------------------------------------------\n\tprotected abstract Class<? extends JRedis> getImplementationClass();\n\t/**\n\t * Define this method to test a specific JRedis implementation.\n\t * \n\t * @param host\n\t * @param port\n\t * @return\n\t */\n\tprotected abstract JRedis newConnection(String host, int port, int db, String password) throws ClientRuntimeException;\n\n\t/**\n\t * Runs a set of command primitives test runs using concurrent clients. [TODO: add all commands - this is a sampling of a few.]\n\t * <p><b>Be advised that this will FLUSH the db specified.</b>  Defaults to database at index 13:  i.e. <code>jredis.select(13).flushdb()</code>. \n\t * This bench will use <code>AUTH</code> to make sure you do not accidentally destroy important data\n\t * when runnign the benchmark.  (If you don't have a password on your db, it can't be that important, right?)\n\t * \n\t * <p>Further note that this will use the password <code><b>jredis</b></code> so either\n\t * make sure the redis.conf <code>requirepass</code> is set appropriately or simply comment it out.\n\t * \n\t * @param host\n\t * @param port\n\t * @param threadCnt\n\t * @param reqCnt\n\t * @param size\n\t * @param db\n\t */\n\t\n\tprotected final void  runBenchmarks(String host, int port, int threadCnt, int reqCnt, int size, int db)\n\t{\n//\t\trandom = new Random(System.currentTimeMillis());\n\t\t\n\t\tfixedbytes = new byte[size];\n\t\trandom.nextBytes(fixedbytes);\n\t\t/** setup data */\n\t\tfor(int i=0; i<reqCnt; i++){\n//\t\t\tkeys.add(getRandomString (48));\n//\t\t\tpatternList.add(getRandomString(random.nextInt(10)+2) + patternA + getRandomString(random.nextInt(10)+2));\n//\t\t\tuniqueSet.add(getRandomString(48));\n//\t\t\tcommonSet.add(getRandomString(48));\n//\t\t\tset1.add(\"set_1\" + getRandomString(20));\n//\t\t\tset2.add(\"set_2\" + getRandomString(20));\n//\t\t\tdataList.add(getRandomBytes (128));\n\t\t\tstringList.add(getRandomString (128));\n//\t\t\tobjectList.add(new TestBean(\"testbean.\" + i));\n//\t\t\tintList.add(random.nextInt());\n//\t\t\tlongList.add(random.nextLong());\n\t\t}\n\t\tBenchmarkWorker[] workers = new BenchmarkWorker[threadCnt];\n\n\t\tSystem.out.println ();\n\t\tSystem.out.println(\"-------------------------------------------------------------------- JREDIS ----\");\n\t\tSystem.out.println(\"---\");\n\t\tSystem.out.format (\"--- Benchmarking JRedis provider: %s\\n\", getImplementationClass().getName());\n\t\tSystem.out.format (\"--- host:%s:%d (db:%d) | bytes:%d | threads:%d | reqs/conn:%d \\n\", host, port, db, size ,threadCnt, reqCnt);\n\t\tSystem.out.println(\"---\");\n\t\tSystem.out.println(\"--------------------------------------------------------------------------------\\n\\n\");\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newPingWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.PING, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newSetWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.SET, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newSetWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.GET, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newSetnxWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.SETNX, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newIncrWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.INCR, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newDecrWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.DECR, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newIncrbyWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.INCRBY, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newDecrbyWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.DECRBY, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newDbsizeWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.DBSIZE, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newLPushWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.LPUSH, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newRPushWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.RPUSH, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newLPopWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.LPOP, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newRPopWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.RPOP, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newLLenWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.LLEN, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newScardWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.SCARD, reqCnt, threadCnt, workers);\n\n\t\t\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newSaddWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.SADD, reqCnt, threadCnt, workers);\n\n\t\tfor(int i=0;i<threadCnt;i++) workers[i] = newSremWorker (host, port, db);\n\t\tBenchmarker.runBenchmark (Command.SREM, reqCnt, threadCnt, workers);\n\n\t\t//\t\tfor(int i=0;i<connectionCnt;i++) workers[i] = newSmembersWorker();\n//\t\tBenchmarker.runBenchmark (Command.SMEMBERS, reqCnt, connectionCnt, workers);\n\t\t\n\t}\n\t// ------------------------------------------------------------------------\n\t// The workers\n\t// ------------------------------------------------------------------------\n\t\n\t/** does the PING */\n\tpublic  final BenchmarkWorker newPingWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\t@Override\n\t\t\tprotected void prep() {}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++){ \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.ping();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\t\n\t/** does the DBSIZE */\n\tpublic  final BenchmarkWorker newDbsizeWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\t@Override\n\t\t\tprotected void prep() {}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++){ \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.dbsize();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the SADD */\n\tpublic final BenchmarkWorker newSaddWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.sadd (key, i);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\t\n\t/** does the SREM */\n\tpublic final BenchmarkWorker newSremWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { \n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.sadd (key, i);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.srem (key, i);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\t\n\t/** does the SCARD */\n\tpublic final BenchmarkWorker newScardWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { \n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.sadd (key, i);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.scard (key);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\t\n\t/** does the LLEN */\n\tpublic final BenchmarkWorker newLLenWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { \n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.lpush (key, 1);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.llen (key);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\t\n\t/** does the LPOP */\n\tpublic final BenchmarkWorker newLPopWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { \n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.lpush (key, 1);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.lpop (key);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the RPOP */\n\tpublic final BenchmarkWorker newRPopWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { \n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.lpush (key, 1);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.rpop (key);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the LPUSH */\n\tpublic final BenchmarkWorker newLPushWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.lpush (key, i);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the RPUSH */\n\tpublic final BenchmarkWorker newRPushWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.rpush (key, i);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the INCR */\n\tpublic final BenchmarkWorker newIncrWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.incr (key);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the DECR */\n\tpublic final BenchmarkWorker newDecrWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.decr (key);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\t/** does the INCRBY */\n\tpublic final BenchmarkWorker newIncrbyWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.incrby (key, 10);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the DECR */\n\tpublic final BenchmarkWorker newDecrbyWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tString key = \"num_\" + id;\n\t\t\t@Override\n\t\t\tprotected void prep() { }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++) { \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.decrby (key, 10);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the SET */\n\tpublic  final BenchmarkWorker newSetWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tbyte[] data = fixedbytes;\n\t\t\tString key = id + \":fixedbytes:string\";\n\t\t\t@Override\n\t\t\tprotected void prep() {  }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++){ \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.set(key, data);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/** does the SETNX */\n\tpublic  final BenchmarkWorker newSetnxWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tbyte[] data = fixedbytes;\n\t\t\tString key = id + \":fixedbytes:string\";\n\t\t\t@Override\n\t\t\tprotected void prep() {  }\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\tfor(int i=0; i<reqCnt; i++){ \n\t\t\t\t\ttry {\n\t\t\t\t\t\tjredis.setnx (key, data);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\t/** does the GET */\n\tpublic  final BenchmarkWorker newGetWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tbyte[] data = fixedbytes;\n\t\t\tString key = id + \":fixedbytes:string\";\n\t\t\t@Override\n\t\t\tprotected void prep() {\n\t\t\t\ttry {\n\t\t\t\t\tfor(int i=0; i<reqCnt; i++){ \n\t\t\t\t\t\tjredis.set(key, data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\ttry {\n\t\t\t\t\tfor(int i=0; i<reqCnt; i++){ \n\t\t\t\t\t\tjredis.get(\"fixedbytes_\"+id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t}\n\t\t};\n\t}\n\t/** does the SMEMBERS */\n\tpublic  final BenchmarkWorker newSmembersWorker (String host, int port, int db) {\n\t\treturn new BenchmarkWorker (host, port, db){\n\t\t\tList<String>  values = JRedisBenchmark.stringList;\n\t\t\tString key = id + \":stringList:set\";\n\t\t\t@Override\n\t\t\tprotected void prep() {\n\t\t\t\ttry {\n\t\t\t\t\tfor(int i=0; i<values.size(); i++){ \n\t\t\t\t\t\tjredis.sadd (key, values.get(i));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t}\n\t\t\t@Override\n\t\t\tprotected void work() {\n\t\t\t\ttry {\n\t\t\t\t\tfor(int i=0; i<reqCnt; i++){ \n\t\t\t\t\t\tjredis.smembers(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (RedisException e) { e.printStackTrace(); }\n\t\t\t}\n\t\t};\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// The Benchmarker\n\t// ------------------------------------------------------------------------\n\t\n\tpublic static class Benchmarker {\n\t\tpublic static final void runBenchmark(final Command cmd, final int reqCnt, final int threadCnt, final BenchmarkWorker[] workers) {\n\t\t\tnew Benchmarker(cmd, reqCnt, threadCnt, workers).runBenchmark();\n\t\t}\n\t\tprivate Command cmd;\n\t\tprivate BenchmarkWorker[] workers;\n\t\tprivate int threadCnt;\n\t\tprivate int reqCnt;\n\t\tprivate Benchmarker (final Command cmd, final int reqCnt, final int threadCnt, final BenchmarkWorker[] workers) {\n\t\t\tthis.cmd = cmd;\n\t\t\tthis.reqCnt = reqCnt;\n\t\t\tthis.threadCnt = threadCnt;\n\t\t\tthis.workers = workers;\n\t\t}\n\t\t\n\t\tprivate void runBenchmark () {\n\t\t\t\n\t\t\tString host = workers[0].host;\n\t\t\t\n\t\t\tfinal long[]   \t\t\tdeltas = new long[threadCnt];\n\t\t\tfinal CountDownLatch \tcompletion = new CountDownLatch(threadCnt);\n\t\t\tfinal CountDownLatch \tready = new CountDownLatch(threadCnt);\n\t\t\tfinal CountDownLatch \tmark = new CountDownLatch(1);\n\n\t\t\tfor(int i=0; i<threadCnt; i++){\n\t\t\t\tworkers[i].id = i;\n\t\t\t\tworkers[i].completion = completion;\n\t\t\t\tworkers[i].mark = mark;\n\t\t\t\tworkers[i].ready = ready;\n\t\t\t\tworkers[i].reqCnt = reqCnt;\n\t\t\t\tworkers[i].deltas = deltas;\n\t\t\t\tnew Thread (workers[i]).start();\n\t\t\t}\n\t\t\t\n\t\t\ttry {\n\t\t\t\t/* run benchmark workers */ \n\t\t\t\tready.await();\t\t\t\t\t\t\t\t\t\t// ready\n\t\t\t\tTimer timer = Timer.startNewTimer();\t\t\t\t// set\n\t\t\t\tmark.countDown();   \t\t\t\t\t\t\t\t// go\n\t\t\t\t\n\t\t\t\tSystem.out.print(\" ...\\n\");\n\t\t\t\tcompletion.await(); \t\t\t\t\t\t\t\t// ... done\n\n\t\t\t\ttimer.mark();\n\t\t\t\t\n\t\t\t\t/* report */ \n\t\t\t\t\t// overall - this is throughput\n\t\t\t\tSystem.out.format(\"===== %s =====\\n\",cmd.code);\n\t\t\t\tSystem.out.format(\"%d concurrent clients (%d %ss each) [host: %s]\\n\", threadCnt, reqCnt, cmd.code, host);\n\t\t\t\tSystem.out.format(\"  ==> %d total requests @ %f seconds\\n\", threadCnt*reqCnt, (float)timer.deltaAtMark(TimeUnit.SECONDS));\n\t\t\t\tSystem.out.format(\"  ==> %f/second\\n\", (float)timer.opsPerSecAtMark((long)threadCnt*reqCnt));\n\t\t\t\tSystem.out.println();\n\t\t\t\t\n\t\t\t\t\t// report for each - this is response time\n\t\t\t\tlong max = Long.MIN_VALUE;\n\t\t\t\tlong min = Long.MAX_VALUE;\n\t\t\t\tfor(int i=0; i<threadCnt; i++){\n\t\t\t\t\tmin = deltas[i]<min ? deltas[i] : min;\n\t\t\t\t\tmax = deltas[i]>max ? deltas[i] : max;\n\t\t\t\t}\n\t\t\t\tSystem.out.format(\"\\t\\t\\tmin: %s msecs\\n\\t\\t\\tmax: %s msecs\\n\\n\", min, max);\n\t\t\t}\n\t\t\tcatch (Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Base for all workers\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * Abstract base class for all benchmark workers.  This is a runnable that \n\t * uses the template pattern in the run method and takes care of common\n\t * time keeping tasks for the specific (child class) workers.\n\t */\n\tpublic abstract class BenchmarkWorker implements Runnable {\n\t\tfinal String host;\n\t\tfinal int port;\n\t\t\n\t\tlong[] deltas;\n\t\tCountDownLatch ready;\n\t\tCountDownLatch completion;\n\t\tCountDownLatch mark;\n\t\tint reqCnt;\n\t\tint id; \n\t\tint db;\n\n\t\tJRedis jredis = null;\n\t\t\n\t\tpublic BenchmarkWorker (String host, int port, int db) {\n\t\t\tthis.host = host;\n\t\t\tthis.port = port;\n\t\t\tthis.db = db;\n\t\t}\n\t\t\n\t\t/** \n\t\t * <p>1 - connects to the redis server\n\t\t * <p>2 - calls the {@link BenchmarkWorker#prep()} -- subclasses will implement this\n\t\t * <p>3 - waits for the mark signal to start the calls\n\t\t * <p>4 - gets the sys time, and ..\n\t\t * <p>5 - calls the {@link BenchmarkWorker#work()} method -- subclasses will implement this\n\t\t * <p>6 - gets the sys time -- this is the time delta for this worker\n\t\t * <p>7 - closes the connection, and signals completion to the benchmarker.\n\t\t */\n\t\tpublic void run() {\n\t\t\ttry {\n\n\t\t\t\tjredis = newConnection (host, 6379, db, password);\n\t\t\t\ttry {\n//\t\t\t\t\tjredis.auth (password).select(db).flushdb();\n\t\t\t\t\tjredis.flushdb();\n\t\t\t\t}\n\t\t\t\tcatch (RedisException e) {\t\t\t\t\n\t\t\t\t\tSystem.err.format(\"BENCHMARK::REDIS %s ERROR => %s\\nWorker will stop.\\n\", e.getCommand(), e.getLocalizedMessage());\n\t\t\t\t\tSystem.exit (1);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tprep();\n\t\t\t\tready.countDown();\n\t\t\t\tmark.await();\t\t// wait sig\n\t\t\t\tlong start=0;\n\t\t\t\tstart = System.currentTimeMillis();\n\t\t\t\twork();\n\t\t\t\tdeltas[id] = System.currentTimeMillis() - start;\n\t\t\t\t\n\t\t\t\tif(quitOnRunEnd)\n\t\t\t\t\tjredis.quit();\n\t\t\t\tcompletion.countDown();  // sig done\n\t\t\t} \n\t\t\tcatch (Exception e){\n\t\t\t\tSystem.err.format(\"BENCHMARK::Exception => %s\\nWill stop.\\n\", e.getLocalizedMessage());\n\t\t\t}\n\t\t}\n\t\t/** anything that needs to be done to setup the calls -- typically all time consuming data setup tasks go here ...*/\n\t\tprotected abstract void prep();\n\t\t/** Typically just a tight loop calling the redis server for the given test and using the data prep'd in {@link BenchmarkWorker#prep()} */\n\t\tprotected abstract void work();\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/bench/JRedisJProfileSubject.java",
    "content": "/*\n *   Copyright 2009 Joubin Mohammad Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.bench;\n\nimport org.jredis.JRedis;\nimport org.jredis.RedisException;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 11, 2009\n * @since   alpha.0\n * \n */\npublic class JRedisJProfileSubject {\n\tprivate final JRedis jredis;\n\n\tpublic JRedisJProfileSubject (JRedis jredis){\n\t\tthis.jredis = jredis;\n\t}\n\tprotected JRedisJProfileSubject () {\n\t\tjredis = null;\n\t}\n\t/**\n\t * In a tight loop, we execute a few select\n\t * commands that touch the various permutations of\n\t * request complexity, and response type, so that\n\t * we can pinpoint the bottlenecks and the general\n\t * runtime characteristics of the JRedic provider.\n\t * @throws RedisException\n\t */\n\tpublic void run () throws RedisException {\n\t\tLog.log(\"***** JProfileTestCase ****\");\n//\t\tjredis.auth(\"jredis\").ping().flushall();\n\t\t\n\t\tint iter = 100000;\n\t\tString key = \"foostring\";\n\t\tString cntrkey = \"foocntr\";\n\t\tString listkey = \"foolist\";\n\t\tString setkey = \"fooset\";\n\t\tbyte[] data = \"meow\".getBytes();\n\t\tlong start = System.currentTimeMillis();\n\t\tfor(Long j=0L; j<iter; j++) {\n\t\t\tjredis.incr(cntrkey);\n\t\t\tjredis.set(key, data);\n\t\t\tjredis.sadd(setkey, data);\n\t\t\tjredis.rpush(listkey, data);\n\t\t}\n\t\tlong delta = System.currentTimeMillis() - start;\n\t\tfloat rate = ((float)iter * 1000) / delta;\n\t\tSystem.out.format(\"%d iterations | %d msec | %8.2f /sec \\n\", iter, delta, rate);\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/bench/Util.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.bench;\n\nimport java.util.Random;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * @author  joubin \n */\npublic class Util {\n\t\n\t// ------------------------------------------------------------------------\n\t// Static properties\n\t// ------------------------------------------------------------------------\n\t/** \n\t * Random generator used for Util random functions, \n\t * instantiated using {@link System#currentTimeMillis()} as seed\n\t */\n\tfinal static Random \t\trandom = new Random(System.currentTimeMillis());\n\t\n\t// ------------------------------------------------------------------------\n\t// Static methods\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Generates a random {@link String} of length <code>size</code> using the default\n\t * encoding scheme.  String content is ASCII characters.\n\t * @param size of the string (character count)\n\t * @return the generated {@link String}\n\t */\n\tstatic \n\tpublic String getRandomString (int size) {\n\t\tStringBuilder builder = new  StringBuilder(size);\n\t\tfor(int i = 0; i<size; i++){\n\t\t\tchar c = (char) (random.nextInt(126-33) + 33);\n\t\t\tbuilder.append(c);\n\t\t}\n\t\treturn builder.toString();\n\t}\n\t/**\n\t * Generates a random byte[] of given <code>size</code>.\n\t * @param size of the generated array.\n\t * @return the generated array\n\t */\n\tstatic \n\tpublic byte[] getRandomBytes(int size) {\n\t\tint len = size;\n\t\tbyte[]\tbigstuff = new byte[len];\n\t\trandom.nextBytes(bigstuff);\n\t\treturn bigstuff;\n\t}\n\t// ------------------------------------------------------------------------\n\t// Inner types\n\t// ------------------------------------------------------------------------\n\t/**\n\t * A timer utility for benchmarking.  Internally uses {@link TimeUnit#MILLISECONDS}.\n\t */\n\tpublic static final class Timer {\n\t\tfinal static public TimeUnit UNIT = TimeUnit.MILLISECONDS;\n\t\tfinal long startTime = System.currentTimeMillis();\n\t\tprivate long markTime = startTime;\n\t\tprivate long delta = 0;\n\t\tprivate Timer () {}\n\t\t\n\t\tpublic static final Timer startNewTimer() {\n\t\t\treturn new Timer ();\n\t\t}\n\t\tpublic long mark () {\n\t\t\tmarkTime = now();\n\t\t\tdelta = markTime - startTime;\n\t\t\treturn delta;\n\t\t}\n\t\tpublic static final long now() { return System.currentTimeMillis(); }\n\t\t/**\n         * @param keyCount\n         * @return\n         */\n        public float opsPerSecAtDelta (long opCount, long delta) {\n\t        return (UNIT.convert(1, TimeUnit.SECONDS)*opCount)/(float)delta;\n        }\n        \n        public float opsPerSecAtMark (long opCount) {\n        \treturn opsPerSecAtDelta(opCount, deltaAtMark());\n        }\n        \n\t\t/**\n         * @return the elapsed time since call to {@link Timer#mark} in the timer's TimeUnit\n         */\n        public long deltaAtMark () { return delta;}\n        \n        /**\n         * @param unit\n         * @return the elapsed time since call to {@link Timer#mark} in the specified unit.\n         * If the unit provided is finer than the timer's internal time unit, finer precision will\n         * naturally be irrelevant.\n         */\n        public long deltaAtMark (TimeUnit unit){\n        \treturn unit.convert(deltaAtMark(), UNIT);\n        }\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/JRedisClientBenchmark.java",
    "content": "/*\n *   Copyright 2009 Joubin Mohammad Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.bench;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.bench.JRedisBenchmark;\nimport org.jredis.ri.alphazero.JRedisClient;\n\n\n/**\n * Not fully baked ... just a hack to get things going.\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/10/09\n * @since   alpha.0\n * \n */\npublic class JRedisClientBenchmark extends JRedisBenchmark {\n\n\t/**\n\t * Runs the benchmark tests.\n\t * [TODO: lets do proper usage here and clean this up.]\n\t * \n\t * Currently, uses 50 concurrent connections and 5000 requests / each connection.\n\t * TODO: munch on some commandline args ...\n\t * @param args\n\t */\n\tpublic static void main(String[] args) {\n\t\tString host = \"127.0.0.1\";\n\t\tint    port = 6379;\n\t\tint\t   size = 3;\n\t\tint workerCnt = 10;\n\t\tint reqCnt = 20000;\n\t\tint\tdb = 13;\n\t\tif(args.length > 0) db = Integer.valueOf (args[0]);\n\t\tif(args.length > 1) workerCnt = Integer.valueOf(args[1]);\n\t\tif(args.length > 2) reqCnt = Integer.valueOf(args[2]);\n\t\tif(args.length > 3) size = Integer.parseInt(args[3]);\n\t\tif(args.length > 4) host = args[4];\n\t\t\n\t\tSystem.out.format(\"==> Usage: [db [conn [req [size [host]]]]\\n\");\n\t\t\n\t\tnew JRedisClientBenchmark().runBenchmarks (host, port, workerCnt, reqCnt, size, db);\n\t}\n\t\n\t@Override\n\tprotected final JRedis newConnection(String host, int port, int db, String password) throws ClientRuntimeException {\n\t\treturn new JRedisClient(host, port, password, db);\n\t}\n\t@Override\n\tprotected final Class<? extends JRedis> getImplementationClass() {\n\t\treturn JRedisClient.class;\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/JRedisClientJProfileSubject.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.bench;\n\nimport org.jredis.JRedis;\nimport org.jredis.RedisException;\nimport org.jredis.bench.JRedisJProfileSubject;\nimport org.jredis.ri.alphazero.JRedisClient;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 24, 2009\n * @since   alpha.0\n * \n */\n\npublic class JRedisClientJProfileSubject extends JRedisJProfileSubject{\n\n\tpublic static void main(String[] args) throws RedisException {\n\t\tJRedis jredis;\n        jredis = new JRedisClient(\"localhost\", 6379, \"jredis\", 0);\n\t\tnew JRedisJProfileSubject (jredis).run();\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/JRedisPipelineServiceBenchmark.java",
    "content": "///*\n// *   Copyright 2009 Joubin Houshyar\n// * \n// *   Licensed under the Apache License, Version 2.0 (the \"License\");\n// *   you may not use this file except in compliance with the License.\n// *   You may obtain a copy of the License at\n// *    \n// *   http://www.apache.org/licenses/LICENSE-2.0\n// *    \n// *   Unless required by applicable law or agreed to in writing, software\n// *   distributed under the License is distributed on an \"AS IS\" BASIS,\n// *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *   See the License for the specific language governing permissions and\n// *   limitations under the License.\n// */\n//\n//package org.jredis.ri.alphazero.bench;\n//\n//import org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\n//import org.jredis.bench.JRedisBenchmark;\n//import org.jredis.connector.ConnectionSpec;\n//import org.jredis.ri.alphazero.JRedisPipelineService;\n//import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n//\n///**\n// * [TODO: document me!]\n// *\n// * @author  Joubin Houshyar (alphazero@sensesay.net)\n// * @version alpha.0, Nov 6, 2009\n// * @since   alpha.0\n// * \n// */\n//\n//public class JRedisPipelineServiceBenchmark extends JRedisBenchmark {\n//\tpublic static void main(String[] args) {\n////\t\thost = \"192.168.1.222\";\n//\t\tString host = \"127.0.0.1\";\n//\t\tString password = \"jredis\";\n//\t\tint    port = 6379;\n//\t\tint\t   size = 3;\n//\t\tint workerCnt = 100;\n//\t\tint reqCnt = 1000;\n//\t\tint\tdb = 13;\n//\t\tif(args.length > 0) db = Integer.valueOf (args[0]);\n//\t\tif(args.length > 1) workerCnt = Integer.valueOf(args[1]);\n//\t\tif(args.length > 2) reqCnt = Integer.valueOf(args[2]);\n//\t\tif(args.length > 3) size = Integer.parseInt(args[3]);\n//\t\tif(args.length > 4) host = args[4];\n//\t\t\n//\t\tSystem.out.format(\"==> Usage: [db [conn [req [size [host]]]]\\n\");\n//\t\t\n//\t\tnew JRedisPipelineServiceBenchmark(host, port, db, password).runBenchmarks (host, port, workerCnt, reqCnt, size, db);\n//\t}\n//\tfinal JRedis jredisService;\n//    public JRedisPipelineServiceBenchmark (String host, int port, int db, String password) {\n//\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, db, \"jredis\".getBytes());\n//\t\tjredisService = new JRedisPipelineService(connectionSpec);\n//\t\tsuper.quitOnRunEnd(false);\n//    }\n//\t@Override\n//\tprotected final JRedis newConnection (String host, int port, int db, String password) throws ClientRuntimeException {\n//\t\treturn jredisService;\n//\t}\n//\t@Override\n//\tprotected final Class<? extends JRedis> getImplementationClass() {\n//\t\treturn JRedisPipelineService.class;\n//\t}\n//}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/JRedisServiceBenchmark.java",
    "content": "///*\n// *   Copyright 2009 Joubin Houshyar\n// * \n// *   Licensed under the Apache License, Version 2.0 (the \"License\");\n// *   you may not use this file except in compliance with the License.\n// *   You may obtain a copy of the License at\n// *    \n// *   http://www.apache.org/licenses/LICENSE-2.0\n// *    \n// *   Unless required by applicable law or agreed to in writing, software\n// *   distributed under the License is distributed on an \"AS IS\" BASIS,\n// *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *   See the License for the specific language governing permissions and\n// *   limitations under the License.\n// */\n//\n//package org.jredis.ri.alphazero.bench;\n//\n//import org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\n//import org.jredis.bench.JRedisBenchmark;\n//import org.jredis.connector.ConnectionSpec;\n//import org.jredis.ri.alphazero.JRedisService;\n//import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n//\n///**\n// * [TODO: document me!]\n// *\n// * @author  Joubin (alphazero@sensesay.net)\n// * @version alpha.0, Sep 2, 2009\n// * @since   alpha.0\n// * \n// */\n//\n//public class JRedisServiceBenchmark extends JRedisBenchmark {\n//\tpublic static void main(String[] args) {\n////\t\thost = \"192.168.1.222\";\n//\t\tString host = \"127.0.0.1\";\n//\t\tString password = \"jredis\";\n//\t\tint    port = 6379;\n//\t\tint\t   size = 3;\n//\t\tint workerCnt = 100;\n//\t\tint poolCnt = 80;\n//\t\tint reqCnt = 1000;\n//\t\tint\tdb = 13;\n//\t\tif(args.length > 0) db = Integer.valueOf (args[0]);\n//\t\tif(args.length > 1) workerCnt = Integer.valueOf(args[1]);\n//\t\tif(args.length > 2) reqCnt = Integer.valueOf(args[2]);\n//\t\tif(args.length > 3) size = Integer.parseInt(args[3]);\n//\t\tif(args.length > 4) host = args[4];\n//\t\t\n//\t\tSystem.out.format(\"==> Usage: [db [conn [req [size [host]]]]\\n\");\n////\t\tSystem.out.format(\"*** host: %s:%d (db: %d) | datasize: %d | connections: %d | request/conn: %d \\n\\n\", host, port, db, size ,connectionCnt, reqCnt);\n//\t\t\n//\t\tnew JRedisServiceBenchmark(poolCnt, host, port, db, password).runBenchmarks (host, port, workerCnt, reqCnt, size, db);\n//\t}\n//\t\n//\tfinal JRedis jredisService;\n//    public JRedisServiceBenchmark (int poolCnt, String host, int port, int db, String password) {\n//\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, db, \"jredis\".getBytes());\n//\t\tjredisService = new JRedisService(connectionSpec, poolCnt);\n//\t\tsuper.quitOnRunEnd(false);\n//    }\n//\t@Override\n//\tprotected final JRedis newConnection (String host, int port, int db, String password) throws ClientRuntimeException {\n//\t\treturn jredisService;\n//\t}\n//\t@Override\n//\tprotected final Class<? extends JRedis> getImplementationClass() {\n//\t\treturn JRedisService.class;\n//\t}\n//\n//}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/SimpleBenchJRedisAsync.java",
    "content": "package org.jredis.ri.alphazero.bench;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\n\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisAsyncClient;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n\npublic class SimpleBenchJRedisAsync {\n\tpublic static void main(String[] args) {\n\t\tnew SimpleBenchJRedisAsync().run();\n\t}\n\n\tprivate void run() {\n\t\tint database = 11;\n\t\tConnectionSpec connSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, database, \"jredis\".getBytes());\n\t\tJRedisFuture jredis = new JRedisAsyncClient(connSpec);\n\t\t\n\t\tbyte[] key = \"bench-jredis-pipeline-key\".getBytes();\n\t\tint iters = 100 * 1000;\n\t\t\n\t\ttry {\n\t\t\tcleandb(jredis);\n\t\t} catch (Throwable e) {\n\t\t\te.printStackTrace();\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tfor(;;){\n\t\t\tFuture<Long> frCounter = null;\n\t\t\tlong start = System.nanoTime();\n\t\t\tfor(int i=0;i<iters; i++){\n\t\t\t\tfrCounter = jredis.incr(key);\n\t\t\t}\n\t\t\tlong queued = System.nanoTime() - start;\n\t\t\ttry {\n\t\t\t\tlong counter = frCounter.get();\n\t\t\t\tlong delta_ns = System.nanoTime() - start;\n\t\t\t\tlong delta_ms = TimeUnit.MILLISECONDS.convert(delta_ns, TimeUnit.NANOSECONDS);\n\t\t\t\tfloat opsrate = iters/delta_ms;\n\t\t\t\tSystem.out.format(\"counter: %d  msec:%d ops/msecs:%f  [q-delta:%d] [delta:%d]\\n\", counter, delta_ms, opsrate, queued, delta_ns);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tbreak;\n\t\t\t} catch (ExecutionException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void cleandb(JRedisFuture jredis) throws InterruptedException, ExecutionException {\n\t\tjredis.flushdb().get();\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/SimpleBenchJRedisChunkedPipeline.java",
    "content": "package org.jredis.ri.alphazero.bench;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\n\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.alphazero.JRedisChunkedPipeline;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\npublic class SimpleBenchJRedisChunkedPipeline implements Runnable {\n\tpublic static void main(String[] args) {\n\t\tRunnable bench = new SimpleBenchJRedisChunkedPipeline();\n\t\tThread bt = new Thread(bench, \"\");\n\t\tbt.start();\n\t\ttry {\n\t\t\tbt.join();\n\t\t} catch (InterruptedException e) {\n\t\t\t// TODO Auto-generated catch block\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t}\n\n\t@Override\n\tpublic void run() {\n\t\tint database = 11;\n\t\tConnectionSpec connSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, database, \"jredis\".getBytes());\n\t\tJRedisFuture jredis = new JRedisChunkedPipeline(connSpec);\n\t\t\n\t\tbyte[] key = \"cpct\".getBytes();\n\t\tint iters = 100000;\n\t\t\n\t\tfor(;;){\n\t\t\tFuture<Long> frCounter = null;\n\t\t\tlong start = System.nanoTime();\n\t\t\tfor(int i=0;i<iters; i++){\n\t\t\t\tfrCounter = jredis.incr(key);\n\t\t\t}\n\t\t\tlong queued = System.nanoTime() - start;\n\t\t\ttry {\n\t\t\t\tjredis.flush();\n\t\t\t\tlong counter = frCounter.get();  // NOTE: excellent place to put implicit flush()\n\t\t\t\tlong delta_ns = System.nanoTime() - start;\n\t\t\t\tlong delta_ms = TimeUnit.MILLISECONDS.convert(delta_ns, TimeUnit.NANOSECONDS);\n\t\t\t\tfloat opsrate = iters/delta_ms;\n\t\t\t\tLog.log(\"counter: %d  msec:%d ops/msecs:%f  [q-delta:%d] [delta:%d]\", counter, delta_ms, opsrate, queued, delta_ns);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tbreak;\n\t\t\t} catch (ExecutionException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t@SuppressWarnings(\"unused\")\n\tprivate void cleandb(JRedisFuture jredis) throws InterruptedException, ExecutionException {\n\t\tFuture<ResponseStatus> fr = jredis.flushdb();\n\t\tjredis.flush();\n\t\tfr.get();\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/SimpleBenchJRedisClient.java",
    "content": "package org.jredis.ri.alphazero.bench;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.jredis.JRedis;\nimport org.jredis.RedisException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisClient;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n\npublic class SimpleBenchJRedisClient {\n\tpublic static void main(String[] args) {\n\t\ttry {\n\t\t\tnew SimpleBenchJRedisClient().run();\n\t\t} catch (RedisException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\tprivate void run() throws RedisException {\n\t\tint database = 11;\n\t\tConnectionSpec connSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, database, \"jredis\".getBytes());\n\t\tJRedis jredis = new JRedisClient(connSpec);\n\t\t\n\t\tbyte[] key = \"bench-jredis-pipeline-key\".getBytes();\n\t\tint iters = 100 * 1000;\n\t\t\n\t\ttry {\n\t\t\tcleandb(jredis);\n\t\t} catch (Throwable e) {\n\t\t\te.printStackTrace();\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tfor(;;){\n\t\t\tLong counter = null;\n\t\t\tlong start = System.nanoTime();\n\t\t\tfor(int i=0;i<iters; i++){\n\t\t\t\tcounter = jredis.incr(key);\n\t\t\t}\n\t\t\tlong delta_ns = System.nanoTime() - start;\n\t\t\tlong delta_ms = TimeUnit.MILLISECONDS.convert(delta_ns, TimeUnit.NANOSECONDS);\n\t\t\tfloat opsrate = iters/delta_ms;\n\t\t\tSystem.out.format(\"counter: %d  msec:%d ops/msecs:%f  [delta:%d]\\n\", counter, delta_ms, opsrate, delta_ns);\n\t\t}\n\t}\n\n\tprivate void cleandb(JRedis jredis) throws RedisException {\n\t\tjredis.flushdb();\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/java/org/jredis/ri/alphazero/bench/SimpleBenchJRedisPipeline.java",
    "content": "package org.jredis.ri.alphazero.bench;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\n\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisPipeline;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\npublic class SimpleBenchJRedisPipeline {\n\tpublic static void main(String[] args) {\n\t\tnew SimpleBenchJRedisPipeline().run();\n\t}\n\n\tprivate void run() {\n\t\tint database = 11;\n\t\tConnectionSpec connSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, database, \"jredis\".getBytes());\n\t\tJRedisFuture jredis = new JRedisPipeline(connSpec);\n\t\t\n\t\tbyte[] key = \"pipe\".getBytes();\n\t\tint iters = 100 * 1000;\n\t\t\n\t\ttry {\n\t\t\tcleandb(jredis);\n\t\t} catch (Throwable e) {\n\t\t\te.printStackTrace();\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tfor(;;){\n\t\t\tFuture<Long> frCounter = null;\n\t\t\tlong start = System.nanoTime();\n\t\t\tfor(int i=0;i<iters; i++){\n\t\t\t\tfrCounter = jredis.incr(key);\n\t\t\t}\n\t\t\tlong queued = System.nanoTime() - start;\n\t\t\ttry {\n\t\t\t\tlong counter = frCounter.get();\n\t\t\t\tlong delta_ns = System.nanoTime() - start;\n\t\t\t\tlong delta_ms = TimeUnit.MILLISECONDS.convert(delta_ns, TimeUnit.NANOSECONDS);\n\t\t\t\tfloat opsrate = iters/delta_ms;\n\t\t\t\tLog.log (\"counter: %d  msec:%d ops/msecs:%f  [q-delta:%d] [delta:%d]\", counter, delta_ms, opsrate, queued, delta_ns);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tbreak;\n\t\t\t} catch (ExecutionException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void cleandb(JRedisFuture jredis) throws InterruptedException, ExecutionException {\n\t\tjredis.flushdb().get();\n\t}\n}\n"
  },
  {
    "path": "core/bench/src/main/resources/log4j.properties",
    "content": "# Configure logging for testing\nlog4j.rootLogger=INFO, stdout, logfile\n\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.layout=org.apache.log4j.PatternLayout\nlog4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c] - %m%n\n\nlog4j.appender.logfile=org.apache.log4j.RollingFileAppender\nlog4j.appender.logfile.File=jredis-bench.log\nlog4j.appender.logfile.MaxFileSize=512KB\n\nlog4j.appender.logfile.MaxBackupIndex=1\n\n# Pattern to output: date priority [category] - message\nlog4j.appender.logfile.layout=org.apache.log4j.PatternLayout\nlog4j.appender.logfile.layout.ConversionPattern=%d %-5p [%c] - %m%n\n"
  },
  {
    "path": "core/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<!-- parent -->\n\t<parent>\n\t\t<groupId>org.jredis</groupId>\n\t\t<artifactId>jredis</artifactId>\n\t\t<version>a.0-SNAPSHOT</version>\n\t</parent>\n\n\t<!-- coordination | build pom -->\n\t<name>JRedis - Core [Build POM]</name>\n\t<groupId>org.jredis</groupId>\n\t<artifactId>jredis-core</artifactId>\n\t<version>a.0-SNAPSHOT</version>\n\t<packaging>pom</packaging>\n\n\t<!-- production units -->\n\t<modules>\n\t\t<module>api</module>\n\t\t<module>ri</module>\n\t\t<module>bench</module>\n\t\t<module>all</module>\n\t</modules>\n\n\t<!-- core specific surefire testrunner -->\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-surefire-plugin</artifactId>\n\t\t\t\t<version>2.11</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<systemProperties>\n\t\t\t\t\t\t<!-- TestNG parameters -->\n\n\t\t\t\t\t\t<!-- redis tests | Test Server info -->\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.host</name>\n\t\t\t\t\t\t\t<value>localhost</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.port</name>\n\t\t\t\t\t\t\t<value>6379</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.password</name>\n\t\t\t\t\t\t\t<value>jredis</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<!-- redis tests | Test DBs info *NOTE* THESE WILL BE FLUSHED *NOTE* -->\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.db.1</name>\n\t\t\t\t\t\t\t<value>13</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.db.2</name>\n\t\t\t\t\t\t\t<value>10</value>\n\t\t\t\t\t\t</property>\n\n\t\t\t\t\t\t<!-- redis core tests | test data sizes -->\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.datasize.small</name>\n\t\t\t\t\t\t\t<value>128</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.datasize.medium</name>\n\t\t\t\t\t\t\t<value>2048</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.datasize.large</name>\n\t\t\t\t\t\t\t<value>524288</value>\n\t\t\t\t\t\t</property>\n\n\t\t\t\t\t\t<!-- redis core tests | test cnt limits; mostly for iteration cnts -->\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.cnt.small</name>\n\t\t\t\t\t\t\t<value>10</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.cnt.medium</name>\n\t\t\t\t\t\t\t<value>1000</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.cnt.large</name>\n\t\t\t\t\t\t\t<value>100000</value>\n\t\t\t\t\t\t</property>\n\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.expire.secs</name>\n\t\t\t\t\t\t\t<value>1</value>\n\t\t\t\t\t\t</property>\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.test.expire.wait.millisecs</name>\n\t\t\t\t\t\t\t<value>2000</value>\n\t\t\t\t\t\t</property>\n\n\t\t\t\t\t\t<!-- redis core tests | Service params -->\n\t\t\t\t\t\t<property>\n\t\t\t\t\t\t\t<name>jredis.service.connection.cnt</name>\n\t\t\t\t\t\t\t<value>5</value>\n\t\t\t\t\t\t</property>\n\n\t\t\t\t\t</systemProperties>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\t<!-- info -->\n\t<licenses>\n\t\t<license>\n\t\t\t<name>Apache 2</name>\n\t\t\t<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n\t\t\t<distribution>all</distribution>\n\t\t\t<comments>Copyright 2009 (c) Joubin Houshyar - All Right Resererved</comments>\n\t\t</license>\n\t</licenses>\n\t<developers>\n\t\t<developer>\n\t\t\t<id>joubin</id>\n\t\t\t<name>Joubin Houshyar</name>\n\t\t\t<email>alphazero@sensesay.net</email>\n\t\t\t<url>http://www.sensesay.net</url>\n\t\t\t<roles>\n\t\t\t\t<role>ReleaseManager</role>\n\t\t\t\t<role>Designer</role>\n\t\t\t\t<role>Developer</role>\n\t\t\t</roles>\n\t\t\t<timezone>UTC-5</timezone>\n\t\t</developer>\n\t</developers>\n</project>\n"
  },
  {
    "path": "core/ri/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "core/ri/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "core/ri/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<!-- parent -->\n\t<parent>\n\t\t<groupId>org.jredis</groupId>\n\t\t<artifactId>jredis-core</artifactId>\n\t\t<version>a.0-SNAPSHOT</version>\n\t</parent>\n\n\t<!-- production | jar -->\n\t<name>JRedis - Core - RI</name>\n\t<groupId>org.jredis</groupId>\n\t<artifactId>jredis-core-ri</artifactId>\n\t<version>a.0-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\t<dependencies>\n\t\t<!-- api -->\n\t\t<dependency>\n\t\t\t<groupId>org.jredis</groupId>\n\t\t\t<artifactId>jredis-core-api</artifactId>\n\t\t\t<version>a.0-SNAPSHOT</version>\n\t\t</dependency>\n\t\t<!-- unit testing -->\n\t\t<dependency>\n\t\t\t<groupId>org.testng</groupId>\n\t\t\t<artifactId>testng</artifactId>\n\t\t\t<version>7.7.0</version>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t\t<!-- logging -->\n\t\t<dependency>\n\t\t\t<groupId>log4j</groupId>\n\t\t\t<artifactId>log4j</artifactId>\n\t\t\t<version>1.2.12</version>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>commons-logging</groupId>\n\t\t\t<artifactId>commons-logging</artifactId>\n\t\t\t<version>1.1.1</version>\n\t\t</dependency>\n\t</dependencies>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-assembly-plugin</artifactId>\n\t\t\t\t<version>2.1</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>simple-install</id>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>attached</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t\t<configuration>\n\t\t\t\t\t<descriptorRefs>\n\t\t\t\t\t\t<descriptorRef>jar-with-dependencies</descriptorRef>\n\t\t\t\t\t</descriptorRefs>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\n</project>\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/RI.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 17, 2010\n * \n */\n\npublic interface RI {\n\tpublic enum Release {\n\t\tALPHA,\n\t\tBETA,\n\t\tFINAL\n\t}\n\t@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PACKAGE, ElementType.CONSTRUCTOR, ElementType.FIELD})\n\t@Retention(RetentionPolicy.RUNTIME)\n\tpublic @interface Version {\n\t\tint\t  \tmajor() default 2;\n\t\tint\t\tminor() default 0;\n\t\tRelease release() default Release.ALPHA;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/BulkSetMapping.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport java.io.Serializable;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport org.jredis.KeyValueSet;\nimport org.jredis.ri.alphazero.semantics.DefaultKeyCodec;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\nimport org.jredis.semantics.KeyCodec;\n\npublic abstract class BulkSetMapping<K extends Object, T> implements KeyValueSet<K, T>{\n\tprivate final Map<Object, T> map = new HashMap<Object, T>();\n\tabstract byte[] toBytes(T value) ;\n\tpublic byte[][] getMappings () {\n\t\tKeyCodec<Object> codec = DefaultKeyCodec.provider();\n\t\tbyte[][] mappings = new byte[map.size()*2][];\n\t\tint i = 0;\n\t\tfor (Entry<Object, T> e : map.entrySet()){\n\t\t\tmappings[i++] = codec.encode(e.getKey());\n\t\t\tmappings[i++] = toBytes(e.getValue());\n\t\t}\n\t\treturn mappings;\n\t}\n    public KeyValueSet<K, T> add (K key, T value) {\n    \tmap.put(key, value);\n        return this;\n    }\n// \n    public static <K extends Object> KeyValueSet.ByteArrays<K> newByteArrayKVSet() { return new BulkSetMapping.Bytes<K>(); }\n\tfinal static class Bytes<K extends Object> extends BulkSetMapping<K, byte[]> implements  KeyValueSet.ByteArrays<K> {\n\t    byte[] toBytes(byte[] value) { return value;}\n\t}\n    public static <K extends Object> KeyValueSet.Strings<K> newStringKVSet() { return new BulkSetMapping.Strings<K>(); }\n\tfinal static class Strings<K extends Object>  extends BulkSetMapping<K, String> implements  KeyValueSet.Strings<K> {\n\t    byte[] toBytes(String value) { return DefaultKeyCodec.provider().encode(value);}\n\t}\n    public static <K extends Object> KeyValueSet.Numbers<K> newNumberKVSet() { return new BulkSetMapping.Numbers<K>(); }\n\tfinal static class Numbers<K extends Object>  extends BulkSetMapping<K, Number> implements  KeyValueSet.Numbers<K> {\n\t    byte[] toBytes(Number value) { return String.valueOf(value).getBytes();}\n\t}\n    public static <K extends Object, T extends Serializable> KeyValueSet.Objects<K, T> newObjectKVSet() { return new BulkSetMapping.Objects<K, T>(); }\n\tfinal static class  Objects <K extends Object, T extends Serializable> extends BulkSetMapping<K, T> implements  KeyValueSet.Objects<K, T> {\n\t    byte[] toBytes(T value) { return DefaultCodec.encode(value);}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisAsyncClient.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport java.util.concurrent.Future;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.FaultedConnection;\nimport org.jredis.connector.Connection.Modality;\nimport org.jredis.connector.Connection.Property;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 6, 2009\n * @since   alpha.0\n * \n */\n\npublic class JRedisAsyncClient extends JRedisFutureSupport {\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\t/**  */\n\tfinal private Connection\tconnection;\n\t/**  */\n\tfinal protected ConnectionSpec connSpec;\n\n\t// ------------------------------------------------------------------------\n\t// Construct and initialize\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * @param connectionSpec\n\t */\n\tpublic JRedisAsyncClient (ConnectionSpec connectionSpec) {\n\t\t// note: using a shared connection mod\n\t\tconnSpec = Assert.notNull(connectionSpec, \"ConnectionSpec 'connectionSpec'\", ClientRuntimeException.class);\n\t\tconnectionSpec.setConnectionFlag(Connection.Flag.RELIABLE, Boolean.TRUE);  // REVU: TODO: review all these spot mods.\n\t\tconnectionSpec.setConnectionFlag(Connection.Flag.SHARED, Boolean.FALSE);  // REVU: TODO: review all these spot mods.\n\t\tconnectionSpec.setConnectionFlag(Connection.Flag.PIPELINE, Boolean.FALSE);  // REVU: TODO: review all these spot mods.\n\t\tconnectionSpec.setModality(Modality.Asynchronous);\n//\t\tconnection = new AsyncConnection(connectionSpec, true);\n\t\tconnection = createAsyncConnection();\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Internal ops\n\t// ------------------------------------------------------------------------\n\tfinal private Connection createAsyncConnection() {\n\t\tConnection.Factory cfact = (Connection.Factory) connSpec.getConnectionProperty(Property.CONNECTION_FACTORY);\n\t\tConnection \tconn = null;\n\t\ttry {\n\t\t\tconn = Assert.notNull(cfact.newConnection(connSpec), \"connection delegate\", ClientRuntimeException.class);\n\t\t}\n\t\tcatch (ProviderException e) {\n\t\t\tLog.bug(\"Couldn't create the handler delegate.  => \" + e.getLocalizedMessage());\n\t\t\tthrow e;\n\t\t}\n\t\tcatch (ClientRuntimeException e) {\n\t\t\tString msg = String.format(\"%s\\nMake sure your server is running.\", e.getMessage());\n\t\t\tLog.error (\"Error creating connection -> \" + e.getLocalizedMessage());\n\t\t\tconn = new FaultedConnection(connSpec, msg);\n\t\t}\n\t\tLog.debug (\"%s: Using %s\", this.getClass().getSimpleName(), conn);\n\t\treturn conn;\n\t}\n\t// ------------------------------------------------------------------------\n\t// Super overrides\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Requests to server are queued at this point.  Any requests after a {@link Command#QUIT} will\n\t * raise an exception indicating the pipeline is shutting down.  \n\t * @see org.jredis.ri.alphazero.JRedisFutureSupport#queueRequest(org.jredis.protocol.Command, byte[][])\n\t */\n\tprotected  Future<Response> queueRequest (Command cmd, byte[]...args) throws ClientRuntimeException, ProviderException {\n\t\treturn connection.queueRequest(cmd, args);\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisChunkedPipeline.java",
    "content": "/*\n *   Copyright 2009-2012 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport java.util.concurrent.Future;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedisFuture;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.connection.ChunkedPipelineConnection;\n\n/**\n * An asynchronous pipeline supporting {@link JRedisFuture} api,\n * utilizing the {@link ChunkedPipelineConnection}, providing \n * maximal throughput as a forwarding pipe to Redis server.\n * \n * Thread safe.  Use only one instance per application.\n * \n *   \n * @author Joubin <alphazero@sensesay.net>\n *\n */\npublic class JRedisChunkedPipeline extends JRedisFutureSupport {\n\n\tfinal private Connection\tconnection;\n\tpublic JRedisChunkedPipeline(ConnectionSpec spec){\n\t\tassert spec != null : \"spec is null\";\n\t\tconnection = new ChunkedPipelineConnection(spec);\n\t}\n\t@Override\n\tprotected Future<Response> queueRequest(Command cmd, byte[]... args)\n\t\t\tthrows ClientRuntimeException, ProviderException \n\t{\n\t\treturn connection.queueRequest(cmd, args);\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisClient.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport java.net.UnknownHostException;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.ProviderException;\nimport org.jredis.Redis;\nimport org.jredis.RedisException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Assert;\n\n\n/**\n * [TODO: check documentation and make necessary changes made during refactoring]\n * \n * A basic client, using {@link SocketConnection} and handler delegate \n * <p>\n * This class is simply an assembly of various other components that address distinct\n * concerns of a JRedis connection, and effectively defines the connection policy\n * and use-case patterns by selecting this set of cooperating elements.\n * <p>\n * This is a <i>simple client</i> object suitable for long-held open connections\n * to a redis server by single threaded applications.  \n * <p>\n * <b>The components that are used ARE NOT thread-safe</b> and assume \n * synchronised/sequential access to the api defined by {@link JRedis}.\n * Both the connection and protocol handler delegates of this class are intended for use\n * by a <b>single</b> thread, or strictly sequential access by a pool of threads.  You can\n * create multiple instances of this class and use dedicated threads for each to create a\n * service (if you wish).\n * <p>\n * Redis protocol is handled by a {@link Protocol} instance obtained from the {@link ProtocolManager}.\n * This class will by default specify the {@link RedisVersion#current_revision}.  \n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Aug 13, 2009\n * @since   alpha.0\n * \n */\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Aug 13, 2009\n * @since   alpha.0\n * \n */\n@Redis(versions={\"1.00\"})\npublic class JRedisClient extends SyncJRedisBase  {\n\t\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\tprivate Connection\tconnection;\n\n\t// ------------------------------------------------------------------------\n\t// Construct and initialize\n\t// ------------------------------------------------------------------------\n\n\tpublic JRedisClient (ConnectionSpec connectionSpec){\n\t\tconnectionSpec.setConnectionFlag(Connection.Flag.RELIABLE, Boolean.TRUE);\n\t\tconnectionSpec.setConnectionFlag(Connection.Flag.SHARED, Boolean.FALSE);\n\t\tConnection syncConnection = createSyncConnection (connectionSpec);\n\t\tsetConnection (syncConnection);\n\t}\n\t/**\n\t * Connects to the localhost:6379 redis server using the password.\n\t * Will select db 0.\n     * @param password used for AUTH\n\t * @throws UnknownHostException \n\t * @throws ClientRuntimeException \n     */\n    public JRedisClient (String password) throws ClientRuntimeException {\n\t\tthis (\"localhost\", 6379, password, 0);\n    }\n\n\t/**\n\t * and using localhost:6379 as its network addressing parameters. \n\t * Database will be selected to db 0\n\t * Assumes no password required.\n\t * @throws UnknownHostException \n\t * @throws ClientRuntimeException \n\t */\n\tpublic JRedisClient ( ) throws ClientRuntimeException {\n\t\tthis (\"localhost\", 6379, null, 0);\n\t}\n\t/**\n\t * \n\t * @param host\n\t * @param port\n\t * @throws UnknownHostException \n\t * @throws ClientRuntimeException \n\t */\n\tpublic JRedisClient(String host, int port) throws ClientRuntimeException {\n//\t\tthis(host, port, null, 0, RedisVersion.current_revision);\n\t\tthis(host, port, null, 0);\n\t}\n\t\n\t\n\t/**\n\t * New JRedisClient for the default protocol version {@link RedisVersion}\n\t * @param host redis server's host\n\t * @param port redis server's port\n\t * @param password to use for AUTHentication (can be null)\n\t * @param database database to select on connect\n\t * @throws ClientRuntimeException\n\t * @throws UnknownHostException \n\t */\n\tpublic JRedisClient (String host, int port, String password, int database) \n\tthrows ClientRuntimeException\n\t{\n\t\tthis(DefaultConnectionSpec.newSpec(host, port, database, getCredentialBytes(password)));\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Super overrides\n\t// ------------------------------------------------------------------------\n\t@Override\n\tprotected Response serviceRequest(Command cmd, byte[]... args)\n\t\t\tthrows RedisException, ClientRuntimeException, ProviderException \n\t{\n\t\treturn connection.serviceRequest(cmd, args);\n\t}\n\t\n\n\t// TODO: what's the use of this?\n\t@Override\n\tprotected final void setConnection (Connection connection)  {\n\t\tthis.connection = Assert.notNull(connection, \"connection on setConnection()\", ClientRuntimeException.class);\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// =========================================================== Resource<T>\n\t/*\n\t * Provides basic Resource support without any state management.  Extensions\n\t * that use context in a simply manner can rely on these methods.  Others may\n\t * wish to override.\n\t */\n\t// ------------------------------------------------------------------------\n\t/* (non-Javadoc)\n\t * @see org.jredis.resource.Resource#getInterface()\n\t */\n\t@Override\n\tpublic JRedis getInterface() {\n\t\treturn this;\n\t}\n\t// ------------------------------------------------------------------------\n\t// Static Utils\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Internal use only - \n\t * @param password\n\t * @return the bytes of password or null if none spec'd\n\t */\n\tprivate static byte[] getCredentialBytes (String password){\n\t\treturn (null != password ? password.getBytes() : null);\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisFutureSupport.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n *\n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.StringTokenizer;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedisFuture;\nimport org.jredis.KeyValueSet;\nimport org.jredis.ObjectInfo;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisType;\nimport org.jredis.Sort;\nimport org.jredis.ZSetEntry;\nimport org.jredis.connector.Connection;\nimport org.jredis.protocol.BulkResponse;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.MultiBulkResponse;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.protocol.ValueResponse;\nimport org.jredis.ri.alphazero.support.Convert;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\nimport org.jredis.ri.alphazero.support.SortSupport;\n\n/**\n *\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 10, 2009\n * @since   alpha.0\n *\n */\npublic abstract class JRedisFutureSupport implements JRedisFuture {\n\t\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\t// ------------------------------------------------------------------------\n\t// Constructors\n\t// ------------------------------------------------------------------------\n\t\n\t// ------------------------------------------------------------------------\n\t// Extension point(s)\n\t/*\n\t * This class provides the convenience of a uniform implementation wide mapping\n\t * of JRedis api semantics to the native protocol level semantics of byte[]s.\n\t *\n\t * Extensions can use the provided extension points to provide or delegate the\n\t * servicing of request calls.\n\t */\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * This method mimics the eponymous {@link Connection#queueRequest(Command, byte[]...)}\n\t * which defines the blocking api semantics of Synchronous connections.  The extending class\n\t * can either directly (a) implement the protocol requirements, or, (b) delegate to a\n\t * {@link Connection} instance, or, (c) utilize a pool of {@link Connection}s.\n\t *\n\t * @param cmd\n\t * @param args\n\t * @return\n\t * @throws ClientRuntimeException\n\t * @throws ProviderException\n\t */\n\tabstract protected  Future<Response> queueRequest (Command cmd, byte[]...args) throws ClientRuntimeException, ProviderException;\n\t// ------------------------------------------------------------------------\n\t// INTERFACE\n\t// ================================================================ Redis\n\t/*\n\t * Support of all the JRedisFuture interface methods.\n\t *\n\t * This class uses the UTF-8 character set for all conversions due to its\n\t * use of the Convert and Codec support classes.\n\t *\n\t * All calls are forwarded to an abstract queueRequest method that the\n\t * extending classes are expected to implement.\n\t */\n\t// ------------------------------------------------------------------------\n\n\n\t@Override\n\tpublic <K extends Object> FutureStatus bgsave() {\n\t\treturn new FutureStatus(this.queueRequest(Command.BGSAVE));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> FutureString bgrewriteaof() {\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.BGREWRITEAOF);\n\t\treturn new FutureString(futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> FutureStatus ping() {\n\t\treturn new FutureStatus(this.queueRequest(Command.PING));\n\t}\n\n\t@Override\n\tpublic <K extends Object> FutureStatus flushall() {\n\t\treturn new FutureStatus(this.queueRequest(Command.FLUSHALL));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureStatus flushdb() {\n\t\treturn new FutureStatus(this.queueRequest(Command.FLUSHDB));\n\t}\n\n//\tpublic <K extends Object> FutureStatus select(int index) {\n//\t\tthis.queueRequest(Command.SELECT, Convert.toBytes(index));\n//\t\treturn this;\n//\t}\n\t@Override\n\tpublic <K extends Object> Future<ResponseStatus>  slaveof(String host, int port) {\n\t\tbyte[] hostbytes = null;\n\t\tif((hostbytes = JRedisSupport.getKeyBytes(host)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid host => [\"+host+\"]\");\n\n\t\tbyte[] portbytes = null;\n\t\tif((portbytes = Convert.toBytes(port)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid port => [\"+port+\"]\");\n\n\t\treturn new FutureStatus(this.queueRequest(Command.SLAVEOF, hostbytes, portbytes));\n\t}\n\tpublic <K extends Object> Future<ResponseStatus>  slaveofnone() {\n\t\treturn new FutureStatus(this.queueRequest(Command.SLAVEOF, \"no\".getBytes(), \"one\".getBytes()));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> FutureStatus rename(K oldkey, K newkey) {\n\t\tbyte[] oldkeydata = null;\n\t\tif((oldkeydata = JRedisSupport.getKeyBytes(oldkey)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+oldkey+\"]\");\n\n\t\tbyte[] newkeydata = null;\n\t\tif((newkeydata = JRedisSupport.getKeyBytes(newkey)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+newkey+\"]\");\n\n\t\treturn new FutureStatus(this.queueRequest(Command.RENAME, oldkeydata, newkeydata));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<Boolean> renamenx(K oldkey, K newkey){\n\t\tbyte[] oldkeydata = null;\n\t\tif((oldkeydata = JRedisSupport.getKeyBytes(oldkey)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+oldkey+\"]\");\n\n\t\tbyte[] newkeydata = null;\n\t\tif((newkeydata = JRedisSupport.getKeyBytes(newkey)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+newkey+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.RENAMENX, oldkeydata, newkeydata);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\tpublic <K extends Object> FutureLong rpush(K key, byte[] value)  {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t\n\t\tif(value == null)\n\t\t\tthrow new IllegalArgumentException (\"null value\");\n\t\t\n\t\treturn new FutureLong(this.queueRequest(Command.RPUSH, keybytes, value));\n\t}\n\n\tpublic <K extends Object> FutureLong rpushx(K key, byte[] value) {\n\t\tbyte[] keybytes = null;\n\t\tif ((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tif (value == null)\n\t\t\tthrow new IllegalArgumentException (\"null value\");\n\n\t\treturn new FutureLong(this.queueRequest(Command.RPUSHX, keybytes, value));\n\t}\n\n\tpublic <K extends Object> FutureLong lpushx(K key, byte[] value) {\n\t\tbyte[] keybytes = null;\n\t\tif ((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tif (value == null)\n\t\t\tthrow new IllegalArgumentException (\"null value\");\n\n\t\treturn new FutureLong(this.queueRequest(Command.LPUSHX, keybytes, value));\n\t}\n\n\tpublic <K extends Object> FutureLong linsert(K key, boolean after, byte[] oldvalue, byte[] newvalue) {\n\t\tbyte[] keybytes = null;\n\t\tif ((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n    byte[][] bulk = new byte[4][];\n    bulk[0] = keybytes;\n    bulk[1] = (after ? \"AFTER\" : \"BEFORE\").getBytes();\n    bulk[2] = oldvalue;\n    bulk[3] = newvalue;\n\t\treturn new FutureLong(this.queueRequest(Command.LINSERT, bulk));\n\t}\n\n\tpublic <K extends Object> FutureLong linsertAfter(K key, byte[] oldvalue, byte[] newvalue) {\n    return linsert(key, true, oldvalue, newvalue);\n  }\n\n\tpublic <K extends Object> FutureLong linsertBefore(K key, byte[] oldvalue, byte[] newvalue) {\n    return linsert(key, false, oldvalue, newvalue);\n  }\n\n\t@Override\n\tpublic <K extends Object> FutureByteArray rpoplpush (String srcList, String destList)  {\n\t\tbyte[] srckeybytes = null;\n\t\tif((srckeybytes = JRedisSupport.getKeyBytes(srcList)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid src key => [\"+srcList+\"]\");\n\t\tbyte[] destkeybytes = null;\n\t\tif((destkeybytes = JRedisSupport.getKeyBytes(destList)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid dest key => [\"+destList+\"]\");\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.RPOPLPUSH, srckeybytes, destkeybytes);\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> FutureLong rpush(K key, String value) {\n//\t\trpush(key, DefaultCodec.encode(value));\n\t\treturn rpush(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureLong rpush(K key, Number value) {\n\t\treturn rpush(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> FutureLong rpush (K key, T value)\n\t{\n\t\treturn rpush(key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> sadd(K key, byte[] member)\n\t{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SADD, keybytes, member);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> sadd (K key, String value) {\n\t\treturn sadd (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> sadd (K key, Number value) {\n\t\treturn sadd (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Boolean> sadd (K key, T value)\n\t{\n\t\treturn sadd (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> zadd(K key, double score, byte[] member)\n\t{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ZADD, keybytes,  Convert.toBytes(score), member);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> zadd (K key, double score, String value) {\n\t\treturn zadd (key, score, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> zadd (K key, double score, Number value) {\n\t\treturn zadd (key, score, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Boolean> zadd (K key, double score, T value)\n\t{\n\t\treturn zadd (key, score, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Double> zincrby(K key, double score, byte[] member)\n\t{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ZINCRBY, keybytes,  Convert.toBytes(score), member);\n\t\treturn new FutureDouble(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Double> zincrby (K key, double score, String value) {\n\t\treturn zincrby (key, score, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Double> zincrby (K key, double score, Number value) {\n\t\treturn zincrby (key, score, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Double> zincrby (K key, double score, T value)\n\t{\n\t\treturn zincrby (key, score, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> FutureStatus save()\n\t{\n\t\treturn new FutureStatus(this.queueRequest(Command.SAVE));\n\t}\n\t\n\t// -------- set\n\n\t@Override\n\tpublic <K> Future<Boolean> setbit(K key, int offset, boolean value) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SETBIT, keybytes,  \n\t\t\t\tConvert.toBytes(offset), Convert.toBytes(value ? 1 : 0));\n\n\t\treturn new FutureBit(futureResponse);\n\t\t\n\t}\n\n\n\t@Override\n\tpublic <K> Future<Boolean> getbit(K key, int offset)  {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.GETBIT, keybytes,  \n\t\t\t\tConvert.toBytes(offset));\n\n\t\treturn new FutureBit(futureResponse);\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> FutureStatus set(K key, byte[] value) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\treturn new FutureStatus(this.queueRequest(Command.SET, keybytes, value));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureStatus set(K key, String value) {\n\t\treturn set(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureStatus set(K key, Number value) {\n\t\treturn set(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> FutureStatus set (K key, T value)\n\t{\n\t\treturn set(key, DefaultCodec.encode(value));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<byte[]> getset(K key, byte[] value) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.GETSET, keybytes, value);\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<byte[]> getset(K key, String value) {\n\t\treturn getset(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<byte[]> getset(K key, Number value) {\n\t\treturn getset(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable>\n\tFuture<byte[]> getset (K key, T value)\n\t{\n\t\treturn getset(key, DefaultCodec.encode(value));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<Boolean> setnx(K key, byte[] value){\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SETNX, keybytes, value);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> setnx(K key, String value) {\n\t\treturn setnx(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> setnx(K key, Number value) {\n\t\treturn setnx(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Boolean> setnx (K key, T value) {\n\t\treturn setnx(key, DefaultCodec.encode(value));\n\t}\n\n\t\n\t@Override\n\tpublic <K extends Object> Future<Long> append (K key, byte[] value){\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.APPEND, keybytes, value);\n\t\treturn new FutureLong(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> append(K key, String value) {\n\t\treturn append(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> append(K key, Number value) {\n\t\treturn append(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Long> append (K key, T value) {\n\t\treturn append(key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> sismember(K key, byte[] member) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SISMEMBER, keybytes, member);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> sismember(K key, String value) {\n\t\treturn sismember(key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> sismember(K key, Number numberValue) {\n\t\treturn sismember (key, String.valueOf(numberValue).getBytes());\n\t}\n\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Boolean> sismember(K key, T object) {\n\t\treturn sismember(key, DefaultCodec.encode(object));\n\t}\n\n\tpublic <K extends Object> Future<Boolean> smove (K srcKey, K destKey, byte[] member) {\n\t\tbyte[] srcKeyBytes = null;\n\t\tif((srcKeyBytes = JRedisSupport.getKeyBytes(srcKey)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+srcKey+\"]\");\n\n\t\tbyte[] destKeyBytes = null;\n\t\tif((destKeyBytes = JRedisSupport.getKeyBytes(destKey)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+destKey+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SMOVE, srcKeyBytes, destKeyBytes, member);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\tpublic <K extends Object> Future<Boolean> smove (K srcKey, K destKey, String stringValue) {\n\t\treturn smove (srcKey, destKey, DefaultCodec.encode(stringValue));\n\t}\n\tpublic <K extends Object> Future<Boolean> smove (K srcKey, K destKey, Number numberValue) {\n\t\treturn smove (srcKey, destKey, String.valueOf(numberValue).getBytes());\n\t}\n\tpublic <K extends Object, T extends Serializable>\n\t\t   Future<Boolean> smove (K srcKey, K destKey, T object) {\n\t\treturn smove (srcKey, destKey, DefaultCodec.encode(object));\n\t}\n\t\t\n\t// ------------------------------------------------------------------------\n\t// Commands operating on hashes\n\t// ------------------------------------------------------------------------\n\t\n\tpublic <K extends Object> Future<Boolean> hset(K key, K field, byte[] value) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] entryBytes = null;\n\t\tif((entryBytes = JRedisSupport.getKeyBytes(field)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+field+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HSET, keyBytes, entryBytes, value);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\tpublic <K extends Object> Future<Boolean> hset(K key, K field, String stringValue) {\n\t\treturn hset (key, field, DefaultCodec.encode(stringValue));\n\t}\n\t\n\tpublic <K extends Object> Future<Long> hincrby(K key, K field, long increment) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] entryBytes = null;\n\t\tif((entryBytes = JRedisSupport.getKeyBytes(field)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+field+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HINCRBY, keyBytes, entryBytes, Convert.toBytes(increment));\n\t\treturn new FutureLong(futureResponse);\n\t}\n\t\n\tpublic <K extends Object> Future<Boolean> hset(K key, K field, Number numberValue) {\n\t\treturn hset (key, field, String.valueOf(numberValue).getBytes());\n\t}\n\tpublic <K extends Object, T extends Serializable>\n\t\tFuture<Boolean> hset(K key, K field, T object) {\n\t\treturn hset (key, field, DefaultCodec.encode(object));\n\t}\n\t\n\tpublic <K extends Object> Future<byte[]> hget(K key, K entry) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] entryBytes = null;\n\t\tif((entryBytes = JRedisSupport.getKeyBytes(entry)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+entry+\"]\");\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HGET, keyBytes, entryBytes);\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\t\n\t\n\tpublic <K extends Object> Future<Boolean> hexists(K key, K entry) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] entryBytes = null;\n\t\tif((entryBytes = JRedisSupport.getKeyBytes(entry)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+entry+\"]\");\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HEXISTS, keyBytes, entryBytes);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\t\n\tpublic <K extends Object> Future<Boolean> hdel(K key, K entry) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] entryBytes = null;\n\t\tif((entryBytes = JRedisSupport.getKeyBytes(entry)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+entry+\"]\");\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HDEL, keyBytes, entryBytes);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\t\n\tpublic <K extends Object> Future<Long> hlen(K key) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HLEN, keyBytes);\n\t\treturn new FutureLong(futureResponse);\n\t}\n\t\n\tpublic <K extends Object> Future<List<byte[]>> hkeys(K key) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HKEYS, keyBytes);\n\t\treturn new FutureKeyList (futureResponse);\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> hvals(K key) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HKEYS, keyBytes);\n\t\treturn new FutureByteArrayList (futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Map<byte[], byte[]>> hgetall(K key) {\n\t\tbyte[] keyBytes = null;\n\t\tif((keyBytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.HGETALL, keyBytes);\n\t\treturn new FutureDataDictionary (futureResponse);\n\t}\n\t\n\t\n\t/* ------------------------------- commands returning int value --------- */\n\n\t@Override\n\tpublic <K extends Object> Future<Long> incr(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.INCR, keybytes);\n\t\treturn new FutureLong (futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> incrby(K key, int delta) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.INCRBY, keybytes, Convert.toBytes(delta));\n\t\treturn new FutureLong (futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> decr(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.DECR, keybytes);\n\t\treturn new FutureLong (futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> decrby(K key, int delta) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.DECRBY, keybytes, Convert.toBytes(delta));\n\t\treturn new FutureLong (futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> llen(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.LLEN, keybytes);\n\t\treturn new FutureLong (futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> scard(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SCARD, keybytes);\n\t\treturn new FutureLong (futureResponse);\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<Long> zcard(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ZCARD, keybytes);\n\t\treturn new FutureLong (futureResponse);\n\t}\n\t\n\tpublic <K extends Object> Future<byte[]> srandmember (K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SRANDMEMBER, keybytes);\n\t\treturn new FutureByteArray (futureResponse);\n\t}\n\n\tpublic <K extends Object> Future<byte[]> spop (K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SPOP, keybytes);\n\t\treturn new FutureByteArray (futureResponse);\n\t}\n\n\t/* ------------------------------- commands returning long value --------- */\n\n\t@Override\n\tpublic <K extends Object> Future<Long> dbsize() {\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.DBSIZE);\n\t\treturn new FutureLong (futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> lastsave() {\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.LASTSAVE);\n\t\treturn new FutureLong (futureResponse);\n\t}\n\n\t/* ------------------------------- commands returning byte[] --------- */\n\n\t@Override\n\tpublic <K extends Object> Future<byte[]> get(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.GET, keybytes);\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<byte[]> lindex(K key, long index) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.LINDEX, keybytes, Convert.toBytes(index));\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<byte[]> lpop(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.LPOP, keybytes);\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<byte[]> rpop(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.RPOP, keybytes);\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\n\n\t/* ------------------------------- commands returning String--------- */\n\n\t@Override\n\tpublic <K extends Object> Future<byte[]> randomkey() {\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.RANDOMKEY);\n\t\treturn new FutureByteArray(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<RedisType> type(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\treturn new FutureRedisType(this.queueRequest(Command.TYPE, keybytes));\n\t}\n\n\t/* ------------------------------- commands returning Maps --------- */\n\n\t@Override\n\tpublic <K extends Object> Future<Map<String, String>> info() {\n\t\treturn new FutureInfo(this.queueRequest(Command.INFO));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<ObjectInfo> debug (K key) {\n\t\tbyte[] keybytes = JRedisSupport.getKeyBytes(key);\n//\t\tif(key.length() == 0)\n//\t\t\tthrow new IllegalArgumentException (\"invalid zero length key => [\"+key+\"]\");\n\n\t\treturn new FutureObjectInfo (this.queueRequest(Command.DEBUG, \"OBJECT\".getBytes(), keybytes));\n\t}\n\t/* ------------------------------- commands returning Lists --------- */\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> mget(String ... keys) {\n\n\t\tif(null == keys || keys.length == 0) throw new IllegalArgumentException(\"no keys specified\");\n\t\tbyte[] keydata = null;\n\t\tbyte[][] keybytes = new byte[keys.length][];\n\t\tint i=0;\n\t\tfor(String k : keys) {\n\t\t\tif((keydata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"] @ index: \" + i);\n\t\t\t\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.MGET, keybytes));\n\t}\n\t\n\t/* MSETs */\n\tprivate FutureStatus mset(byte[][] mappings){\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.MSET, mappings);\n\t\treturn new FutureStatus(futureResponse);\n\t}\n\tpublic <K extends Object> FutureStatus mset(Map<K, byte[]> keyValueMap){\n//\t\tKeyCodec codec = DefaultKeyCodec.provider();\n\t\tbyte[][] mappings = new byte[keyValueMap.size()*2][];\n\t\tint i = 0;\n\t\tfor (Entry<K, byte[]> e : keyValueMap.entrySet()){\n\t\t\tmappings[i++] = JRedisSupport.getKeyBytes(e.getKey());\n\t\t\tmappings[i++] = e.getValue();\n\t\t}\n\t\treturn mset(mappings);\n\t}\n\t\n\tpublic <K extends Object> FutureStatus mset(KeyValueSet.ByteArrays<K> keyValueMap){\n\t\treturn mset(keyValueMap.getMappings());\n\t}\n\tpublic <K extends Object> FutureStatus mset(KeyValueSet.Strings<K> keyValueMap){\n\t\treturn mset(keyValueMap.getMappings());\n\t}\n\n\tpublic <K extends Object> FutureStatus mset(KeyValueSet.Numbers<K> keyValueMap){\n\t\treturn mset(keyValueMap.getMappings());\n\t}\n\n\tpublic <K extends Object, T extends Serializable> FutureStatus mset(KeyValueSet.Objects<K, T> keyValueMap){\n\t\treturn mset(keyValueMap.getMappings());\n\t}\n\n\t/* MSETNXs */\n\tprivate Future<Boolean> msetnx(byte[][] mappings){\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.MSETNX, mappings);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\tpublic <K extends Object> Future<Boolean> msetnx(Map<K, byte[]> keyValueMap){\n//\t\tKeyCodec codec = DefaultKeyCodec.provider();\n\t\tbyte[][] mappings = new byte[keyValueMap.size()*2][];\n\t\tint i = 0;\n\t\tfor (Entry<K, byte[]> e : keyValueMap.entrySet()){\n\t\t\tmappings[i++] = JRedisSupport.getKeyBytes(e.getKey());\n\t\t\tmappings[i++] = e.getValue();\n\t\t}\n\t\treturn msetnx(mappings);\n\t}\n\t\n\tpublic <K extends Object> Future<Boolean> msetnx(KeyValueSet.ByteArrays<K> keyValueMap){\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\tpublic <K extends Object> Future<Boolean> msetnx(KeyValueSet.Strings<K> keyValueMap){\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\n\tpublic <K extends Object> Future<Boolean> msetnx(KeyValueSet.Numbers<K> keyValueMap){\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\n\tpublic <K extends Object,T extends Serializable> Future<Boolean> msetnx(KeyValueSet.Objects<K, T> keyValueMap){\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> smembers(K key) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"null key.\");\n\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.SMEMBERS, keydata));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> keys() {\n\t\treturn this.keys(\"*\");\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> keys(K pattern) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(pattern)) == null)\n\t\t\tthrow new IllegalArgumentException (\"null key.\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.KEYS, keydata);\n\t\treturn new FutureKeyList(futureResponse);\n\t}\n\n\tpublic <K extends Object> Future<Long> keystolist(String pattern, String listname) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(pattern)) == null)\n\t\t\tthrow new IllegalArgumentException (\"null key.\");\n\t\tbyte[] listnamedata = null;\n\t\tif((listnamedata = JRedisSupport.getKeyBytes(listname)) == null)\n\t\t\tthrow new IllegalArgumentException (\"null list name.\");\n\n\t\treturn new FutureLong(this.queueRequest(Command.KEYSTOLIST, keydata, listnamedata));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> lrange(K key, long from, long to) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.LRANGE, keybytes, fromBytes, toBytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<byte[]> substr(K key, long from, long to) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\treturn new FutureByteArray(this.queueRequest(Command.SUBSTR, keybytes, fromBytes, toBytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> zrange(K key, long from, long to) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.ZRANGE, keybytes, fromBytes, toBytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> zrangebyscore(K key, double minScore, double maxScore) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] minScoreBytes = Convert.toBytes(minScore);\n\t\tbyte[] maxScoreBytes = Convert.toBytes(maxScore);\n\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.ZRANGEBYSCORE, keybytes, minScoreBytes, maxScoreBytes));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<List<ZSetEntry>> zrangebyscoreSubset(K key, double minScore, double maxScore) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] minScoreBytes = Convert.toBytes(minScore);\n\t\tbyte[] maxScoreBytes = Convert.toBytes(maxScore);\n\n\t\treturn new FutureZSetList(this.queueRequest(Command.ZRANGEBYSCORE$OPTS, keybytes, minScoreBytes, maxScoreBytes, Command.Option.WITHSCORES.bytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> zremrangebyscore(K key, double minScore, double maxScore) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] minScoreBytes = Convert.toBytes(minScore);\n\t\tbyte[] maxScoreBytes = Convert.toBytes(maxScore);\n\n\t\treturn new FutureLong(this.queueRequest(Command.ZREMRANGEBYSCORE, keybytes, minScoreBytes, maxScoreBytes));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<Long> zcount(K key, double minScore, double maxScore) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] minScoreBytes = Convert.toBytes(minScore);\n\t\tbyte[] maxScoreBytes = Convert.toBytes(maxScore);\n\n\t\treturn new FutureLong(this.queueRequest(Command.ZCOUNT, keybytes, minScoreBytes, maxScoreBytes));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Future<Long> zremrangebyrank(K key, long minRank, long maxRank) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] minScoreBytes = Convert.toBytes(minRank);\n\t\tbyte[] maxScoreBytes = Convert.toBytes(maxRank);\n\n\t\treturn new FutureLong(this.queueRequest(Command.ZREMRANGEBYRANK, keybytes, minScoreBytes, maxScoreBytes));\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> zrevrange(K key, long from, long to) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.ZREVRANGE, keybytes, fromBytes, toBytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<ZSetEntry>> zrangeSubset(K key, long from, long to) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\treturn new FutureZSetList(this.queueRequest(Command.ZRANGE$OPTS, keybytes, fromBytes, toBytes, Command.Option.WITHSCORES.bytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<ZSetEntry>> zrevrangeSubset(K key, long from, long to) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\treturn new FutureZSetList(this.queueRequest(Command.ZREVRANGE$OPTS, keybytes, fromBytes, toBytes, Command.Option.WITHSCORES.bytes));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> Sort sort(final K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t\n\t\tfinal JRedisFutureSupport client = this;\n\t\tSort sortQuery = new SortSupport (keybytes) {\n\n\t\t\t\t@Override \n\t\t\tprotected Future<List<byte[]>> execAsyncSort(byte[]... fullSortCmd) {\n\t\t\t\treturn new FutureByteArrayList(client.queueRequest(Command.SORT, fullSortCmd));\n\t\t\t}\n\t\t\tprotected Future<List<byte[]>> execAsyncSortStore(byte[]... fullSortCmd) {\n\t\t\t\tFuture<Response> fResp = client.queueRequest(Command.SORT$STORE, fullSortCmd);\n//\t\t\t\tnew FutureLong(fResp); // hah?\n\t\t\t\treturn new FutureSortStoreResp(fResp);\n\t\t\t}\n\t\t\tprotected List<byte[]> execSort(byte[]... fullSortCmd) {\n\t\t\t\tthrow new IllegalStateException(\"JRedisFuture does not support synchronous sort.\");\n\t\t\t}\n\t\t\tprotected List<byte[]> execSortStore(byte[]... fullSortCmd) {\n\t\t\t\tthrow new IllegalStateException(\"JRedisFuture does not support synchronous sort.\");\n\t\t\t}\n\t\t};\n\t\treturn sortQuery;\n\t}\n\n\t/* ------------------------------- commands that don't get a response --------- */\n\n\t@Override\n\tpublic <K extends Object> FutureStatus quit()  {\n\t\treturn new FutureStatus(this.queueRequest(Command.QUIT));\n\t}\n\t@Override\n\tpublic FutureStatus flush()  {\n\t\treturn new FutureStatus(this.queueRequest(Command.CONN_FLUSH));\n\t}\n\t/* ------------------------------- commands that don't get a response END --------- */\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> sinter(K set1, K... sets) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(set1)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+set1+\"]\");\n\n\t\tbyte[][] keybytes = new byte[1+sets.length][];\n\t\tint i=0; keybytes[i++] = keydata;\n\t\tfor(K k : sets) {\n\t\t\tif((keydata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\t\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.SINTER, keybytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> sunion(K set1, K... sets) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(set1)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+set1+\"]\");\n\n\t\tbyte[][] keybytes = new byte[1+sets.length][];\n\t\tint i=0; keybytes[i++] = keydata;\n\t\tfor(K k : sets) {\n\t\t\tif((keydata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\t\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.SUNION, keybytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<List<byte[]>> sdiff(K set1, K... sets) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(set1)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+set1+\"]\");\n\n\t\tbyte[][] keybytes = new byte[sets.length+1][];\n\t\tint i=0; keybytes[i++] = keydata;\n\t\tfor(K k : sets) {\n\t\t\tif((keydata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\treturn new FutureByteArrayList(this.queueRequest(Command.SDIFF, keybytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> FutureStatus sinterstore(K dest, K... sets) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(dest)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+dest+\"]\");\n\n\t\tbyte[][] setbytes = new byte[1+sets.length][];\n\t\tint i=0;\n\t\tsetbytes[i++] = keydata;\n\t\tbyte[] setdata =null;\n\t\tfor(K k : sets) {\n\t\t\tif((setdata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tsetbytes[i++] = setdata;\n\t\t}\n\t\t\n\t\treturn new FutureStatus(this.queueRequest(Command.SINTERSTORE, setbytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> FutureStatus sunionstore(K dest, K... sets) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(dest)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+dest+\"]\");\n\n\t\tbyte[][] setbytes = new byte[1+sets.length][];\n\t\tint i=0;\n\t\tsetbytes[i++] = keydata;\n\t\tbyte[] setdata =null;\n\t\tfor(K k : sets) {\n\t\t\tif((setdata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tsetbytes[i++] = setdata;\n\t\t}\n\t\t\n\t\treturn new FutureStatus(this.queueRequest(Command.SUNIONSTORE, setbytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> FutureStatus sdiffstore(K dest, K... sets) {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = JRedisSupport.getKeyBytes(dest)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+dest+\"]\");\n\n\t\tbyte[][] setbytes = new byte[1+sets.length][];\n\t\tint i=0;\n\t\tsetbytes[i++] = keydata;\n\t\tbyte[] setdata =null;\n\t\tfor(K k : sets) {\n\t\t\tif((setdata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tsetbytes[i++] = setdata;\n\t\t}\n\t\t\n\t\treturn new FutureStatus(this.queueRequest(Command.SDIFFSTORE, setbytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> del(K ... keys) {\n\t\tif(null == keys || keys.length == 0) throw new IllegalArgumentException(\"no keys specified\");\n\t\tbyte[] keydata = null;\n\t\tbyte[][] keybytes = new byte[keys.length][];\n\t\tint i=0;\n\t\tfor(K k : keys) {\n\t\t\tif((keydata = JRedisSupport.getKeyBytes(k)) == null)\n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"] @ index: \" + i);\n\t\t\t\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.DEL, keybytes);\n\t\treturn new FutureLong(futureResponse);\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> exists(K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.EXISTS, keybytes);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> FutureLong lpush(K key, byte[] value) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t\n\t\tif(value == null)\n\t\t\tthrow new IllegalArgumentException (\"null value\");\n\t\t\n\t\t\n\t\treturn new FutureLong(this.queueRequest(Command.LPUSH, keybytes, value));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureLong lpush(K key, String value) {\n\t\treturn lpush(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureLong lpush(K key, Number value) {\n\t\treturn lpush(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> FutureLong lpush (K key, T value)\n\t{\n\t\treturn lpush(key, DefaultCodec.encode(value));\n\t}\n\t\n\n\n\t@Override\n\tpublic <K extends Object> Future<Long> lrem(K key, byte[] value, int count) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] countBytes = Convert.toBytes(count);\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.LREM, keybytes, countBytes, value);\n\t\treturn new FutureLong(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> lrem (K listKey, String value, int count){\n\t\treturn lrem (listKey, DefaultCodec.encode(value), count);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> lrem (K listKey, Number numberValue, int count) {\n\t\treturn lrem (listKey, String.valueOf(numberValue).getBytes(), count);\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable>\n\tFuture<Long> lrem (K listKey, T object, int count){\n\t\treturn lrem (listKey, DefaultCodec.encode(object), count);\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> FutureStatus lset(K key, long index, byte[] value) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] indexBytes = Convert.toBytes(index);\n\t\treturn new FutureStatus(this.queueRequest(Command.LSET, keybytes, indexBytes, value));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureStatus lset (K key, long index, String value) {\n\t\treturn lset (key, index, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> FutureStatus lset (K key, long index, Number numberValue){\n\t\treturn lset (key, index, String.valueOf(numberValue).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> FutureStatus lset (K key, long index, T object){\n\t\treturn lset (key, index, DefaultCodec.encode(object));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> move(K key, int dbIndex) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.MOVE, keybytes, Convert.toBytes(dbIndex));\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> srem(K key, byte[] member) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.SREM, keybytes, member);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> srem (K key, String value) {\n\t\treturn srem (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> srem (K key, Number value) {\n\t\treturn srem (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Boolean> srem (K key, T value)\n\t{\n\t\treturn srem (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> zrem(K key, byte[] member) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ZREM, keybytes, member);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> zrem (K key, String value) {\n\t\treturn zrem (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Boolean> zrem (K key, Number value) {\n\t\treturn zrem (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Boolean> zrem (K key, T value)\n\t{\n\t\treturn zrem (key, DefaultCodec.encode(value));\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> Future<Double> zscore(K key, byte[] member) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ZSCORE, keybytes, member);\n\t\treturn new FutureDouble(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Double> zscore (K key, String value) {\n\t\treturn zscore (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Double> zscore (K key, Number value) {\n\t\treturn zscore (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Double> zscore (K key, T value)\n\t{\n\t\treturn zscore (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> zrank(K key, byte[] member) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ZRANK, keybytes, member);\n\t\treturn new FutureLong(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> zrank (K key, String value) {\n\t\treturn zrank (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> zrank (K key, Number value) {\n\t\treturn zrank (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Long> zrank (K key, T value)\n\t{\n\t\treturn zrank (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> zrevrank(K key, byte[] member) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ZREVRANK, keybytes, member);\n\t\treturn new FutureLong(futureResponse);\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> zrevrank (K key, String value) {\n\t\treturn zrevrank (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Future<Long> zrevrank (K key, Number value) {\n\t\treturn zrevrank (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Future<Long> zrevrank (K key, T value)\n\t{\n\t\treturn zrevrank (key, DefaultCodec.encode(value));\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> FutureStatus ltrim(K key, long keepFrom, long keepTo) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(keepFrom);\n\t\tbyte[] toBytes = Convert.toBytes(keepTo);\n\t\treturn new FutureStatus(this.queueRequest(Command.LTRIM, keybytes, fromBytes, toBytes));\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> expire(K key, int ttlseconds) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] ttlbytes = Convert.toBytes(ttlseconds);\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.EXPIRE, keybytes, ttlbytes);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Boolean> expireat(K key, long epochtime) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tlong expiretime = TimeUnit.SECONDS.convert(epochtime, TimeUnit.MILLISECONDS);\n\t\tbyte[] expiretimeBytes = Convert.toBytes(expiretime);\n\t\t\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.EXPIREAT, keybytes, expiretimeBytes);\n\t\treturn new FutureBoolean(futureResponse);\n\t}\n\n\t@Override\n\tpublic <K extends Object> Future<Long> ttl (K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = JRedisSupport.getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.TTL, keybytes);\n\t\treturn new FutureLong(futureResponse);\n\t}\n\n\t// TODO: integrate using KeyCodec and a CodecManager at client spec and init time.\n\t// TODO: (implied) ClientSpec (impls. ConnectionSpec)\n\t// this isn't cooked yet -- lets think more about the implications...\n\t//\n//\tstatic final private Map<String, byte[]>\tkeyByteCache = new ConcurrentHashMap<String, byte[]>();\n\tpublic static final boolean\tCacheKeys\t= false;\n\t\n\tpublic static class FutureResultBase {\n\t\tfinal protected Future<Response> pendingRequest;\n\t\tprotected FutureResultBase(Future<Response> pendingRequest){ this.pendingRequest = pendingRequest;}\n\t\tpublic boolean cancel (boolean mayInterruptIfRunning) {\n\t        return pendingRequest.cancel(mayInterruptIfRunning);\n        }\n        public boolean isCancelled () {\n\t        return pendingRequest.isCancelled();\n        }\n        public boolean isDone () {\n\t        return pendingRequest.isDone();\n        }\n\t}\n\tpublic static class FutureStatus extends FutureResultBase implements Future<ResponseStatus>  {\n\n        protected FutureStatus (Future<Response> pendingRequest) { super(pendingRequest); }\n        public ResponseStatus get () throws InterruptedException, ExecutionException {\n//        \tStatusResponse statusResponse = (StatusResponse) pendingRequest.get();  // HANDLE VIRTUALS HERE\n//        \treturn statusResponse.getStatus();\n        \treturn pendingRequest.get().getStatus();\n        }\n\n        public ResponseStatus get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n//        \tStatusResponse statusResponse = (StatusResponse) pendingRequest.get(timeout, unit);\n//        \treturn statusResponse.getStatus();\n        \treturn pendingRequest.get(timeout, unit).getStatus();\n        }\n\n\t}\n\tpublic static class FutureBoolean extends FutureResultBase implements Future<Boolean>{\n\n        protected FutureBoolean (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Boolean get () throws InterruptedException, ExecutionException {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get();\n        \treturn valResp.getBooleanValue();\n        }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Boolean get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get(timeout, unit);\n        \treturn valResp.getBooleanValue();\n        }\n\t}\n\t\n\tpublic static class FutureBit extends FutureResultBase implements Future<Boolean> {\n\n        protected FutureBit (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Boolean get () throws InterruptedException, ExecutionException {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get();\n        \treturn valResp.getLongValue() == 1;\n        }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Boolean get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get(timeout, unit);\n        \treturn valResp.getLongValue() == 1;\n        }\n\t}\n\t\n\tpublic static class FutureString extends FutureResultBase implements Future<String>{\n\n        protected FutureString (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        public String get () throws InterruptedException, ExecutionException {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get();\n        \treturn valResp.getStringValue();\n        }\n\n        public String get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get(timeout, unit);\n        \treturn valResp.getStringValue();\n        }\n\t}\n\tpublic static class FutureRedisType extends FutureResultBase implements Future<RedisType>{\n\n        protected FutureRedisType (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        private final RedisType getRedisType(ValueResponse resp){\n\t\t\tString stringValue = resp.getStringValue();\n\t\t\treturn RedisType.valueOf(stringValue);\n        }\n        public RedisType get () throws InterruptedException, ExecutionException {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get();\n        \treturn getRedisType(valResp);\n        }\n\n        public RedisType get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get(timeout, unit);\n        \treturn getRedisType(valResp);\n        }\n\t}\n\tpublic static class FutureLong extends FutureResultBase implements Future<Long>{\n\n        protected FutureLong (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Long get () throws InterruptedException, ExecutionException {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get();\n        \treturn valResp.getLongValue();\n        }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Long get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get(timeout, unit);\n        \treturn valResp.getLongValue();\n        }\n\t}\n\tpublic static class FutureDouble extends FutureResultBase implements Future<Double>{\n\n        protected FutureDouble (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Double get () throws InterruptedException, ExecutionException {\n        \tBulkResponse bulkResp = (BulkResponse) pendingRequest.get();\n        \tif(bulkResp.getBulkData() != null)\n        \t\treturn Convert.toDouble(bulkResp.getBulkData());\n        \treturn null;\n        }\n\n        @SuppressWarnings(\"boxing\")\n\t\tpublic Double get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tBulkResponse bulkResp = (BulkResponse) pendingRequest.get(timeout, unit);\n        \tif(bulkResp.getBulkData() != null)\n        \t\treturn Convert.toDouble(bulkResp.getBulkData());\n        \treturn null;\n        }\n\t}\n\tpublic static class FutureByteArray extends FutureResultBase implements Future<byte[]>{\n\n        protected FutureByteArray (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        public byte[] get () throws InterruptedException, ExecutionException {\n        \tBulkResponse resp = (BulkResponse) pendingRequest.get();\n        \treturn resp.getBulkData();\n        }\n\n        public byte[] get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tBulkResponse resp = (BulkResponse) pendingRequest.get(timeout, unit);\n        \treturn resp.getBulkData();\n        }\n\t}\n\tpublic static class FutureSortStoreResp extends FutureResultBase implements Future<List<byte[]>>{\n\t\t\n        protected FutureSortStoreResp (Future<Response> pendingRequest) { super(pendingRequest); }\n\t\t\n        public List<byte[]> get () throws InterruptedException, ExecutionException {\n        \tValueResponse resp = (ValueResponse) pendingRequest.get();\n        \treturn packValueResult(resp.getLongValue());\n        }\n\t\t\n        public List<byte[]> get (long timeout, TimeUnit unit)\n\t\tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tValueResponse resp = (ValueResponse) pendingRequest.get(timeout, unit);\n        \treturn packValueResult(resp.getLongValue());\n        }\n        private static List<byte[]> packValueResult(long number) {\n        \tList<byte[]> list = new ArrayList<byte[]>(1);\n\t\t\tlist.add(Convert.toBytes(number));\n\t\t\t\n        \treturn list;\n        }\n\t}\n\tpublic static class FutureByteArrayList extends FutureResultBase implements Future<List<byte[]>>{\n\n        protected FutureByteArrayList (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        public List<byte[]> get () throws InterruptedException, ExecutionException {\n        \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get();\n        \treturn resp.getMultiBulkData();\n        }\n\n        public List<byte[]> get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get(timeout, unit);\n        \treturn resp.getMultiBulkData();\n        }\n\t}\n\n\tpublic static class FutureDataDictionary extends FutureResultBase implements Future<Map<byte[], byte[]>>{\n\n        protected FutureDataDictionary (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        public Map<byte[], byte[]> get () throws InterruptedException, ExecutionException {\n        \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get();\n        \treturn convert(resp.getMultiBulkData());\n        }\n\n        public Map<byte[], byte[]> get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get(timeout, unit);\n        \treturn convert(resp.getMultiBulkData());\n        }\n        private static final Map<byte[], byte[]> convert (List<byte[]> bulkdata) {\n        \tMap<byte[], byte[]> map = null;\n        \tif(null != bulkdata) {\n        \t\tmap = new HashMap<byte[], byte[]>(bulkdata.size()/2);\n        \t\tfor(int i=0; i<bulkdata.size(); i+=2){\n//        \t\t\tmap.put(DefaultCodec.toStr(bulkdata.get(i)), bulkdata.get(i+1));\n        \t\t\tmap.put(bulkdata.get(i), bulkdata.get(i+1));\n        \t\t}\n        \t}\n        \treturn map;\n        }\n\t}\n\n\tpublic static class FutureKeyList extends FutureResultBase implements Future<List<byte[]>>{\n\n        protected FutureKeyList (Future<Response> pendingRequest) { super(pendingRequest); }\n\n//        private List<String>  getResultList (BulkResponse resp) {\n//    \t\tStringTokenizer tokenizer = new StringTokenizer(new String(resp.getBulkData()), \" \");\n//    \t\tList<String>  list = new ArrayList <String>(12);\n//    \t\twhile (tokenizer.hasMoreTokens()){\n//    \t\t\tlist.add(tokenizer.nextToken());\n//    \t\t}\n//    \t\treturn list;\n//        }\n        public List<byte[]> get () throws InterruptedException, ExecutionException {\n\n        \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get();\n        \tList<byte[]> multibulkdata = resp.getMultiBulkData();\n//        \tList<String> list = null;\n//        \tif(null != multibulkdata)\n//        \t\tlist = DefaultCodec.toStr(multibulkdata);\n        \treturn multibulkdata;\n        }\n\n        public List<byte[]> get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n            \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get(timeout, unit);\n            \tList<byte[]> multibulkdata = resp.getMultiBulkData();\n//            \tList<String> list = null;\n//            \tif(null != multibulkdata)\n//            \t\tlist = DefaultCodec.toStr(multibulkdata);\n            \treturn multibulkdata;\n        }\n\t}\n\tpublic static class FutureInfo extends FutureResultBase implements Future<Map<String, String>>{\n\n        protected FutureInfo (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        private Map<String, String>  getResultMap (BulkResponse resp) {\n    \t\tStringTokenizer tokenizer = new StringTokenizer(new String(resp.getBulkData()), \"\\r\\n\");\n    \t\tMap<String, String>  infomap = new HashMap<String, String>(48);\n    \t\twhile (tokenizer.hasMoreTokens()){\n    \t\t\tfinal String info = tokenizer.nextToken();\n    \t\t\t// ignore comments \"# heading\"\n    \t\t\tif(info.startsWith(\"#\"))\n    \t\t\t\tcontinue;\n    \t\t\tint c = info.indexOf(':');\n    \t\t\tString _key =info.substring(0, c);\n    \t\t\tString _value = info.substring(c+1);\n    \t\t\tinfomap.put(_key, _value);\n    \t\t}\n    \t\treturn infomap;\n        }\n        public Map<String, String> get () throws InterruptedException, ExecutionException {\n        \tBulkResponse resp = (BulkResponse) pendingRequest.get();\n        \treturn getResultMap(resp);\n        }\n\n        public Map<String, String> get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tBulkResponse resp = (BulkResponse) pendingRequest.get(timeout, unit);\n        \treturn getResultMap(resp);\n        }\n\t}\n\tpublic static class FutureObjectInfo extends FutureResultBase implements Future<ObjectInfo>{\n\n        protected FutureObjectInfo (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        private final ObjectInfo getObjectInfo(ValueResponse resp){\n\t\t\tString stringValue = resp.getStringValue();\n\t\t\treturn ObjectInfo.valueOf(stringValue);\n        }\n        public ObjectInfo get () throws InterruptedException, ExecutionException {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get();\n        \treturn getObjectInfo(valResp);\n        }\n\n        public ObjectInfo get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tValueResponse valResp = (ValueResponse) pendingRequest.get(timeout, unit);\n        \treturn getObjectInfo(valResp);\n        }\n\t}\n\tpublic static class FutureZSetList extends FutureResultBase implements Future<List<ZSetEntry>>{\n\n        protected FutureZSetList (Future<Response> pendingRequest) { super(pendingRequest); }\n\n        public List<ZSetEntry> get () throws InterruptedException, ExecutionException {\n        \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get();\n        \treturn convert(resp.getMultiBulkData());\n        }\n\n        public List<ZSetEntry> get (long timeout, TimeUnit unit)\n        \tthrows InterruptedException, ExecutionException, TimeoutException\n        {\n        \tMultiBulkResponse resp = (MultiBulkResponse) pendingRequest.get(timeout, unit);\n        \treturn convert(resp.getMultiBulkData());\n        }\n        private static final List<ZSetEntry> convert (List<byte[]> mbulkdata) {\n        \tList<ZSetEntry> zset = null;\n        \tif(mbulkdata.size() > 0){\n        \t\tzset = new ArrayList<ZSetEntry>(mbulkdata.size()/2);\n        \t\tfor(int i=0; i<mbulkdata.size(); i+=2){\n        \t\t\tzset.add(new ZSetEntryImpl(mbulkdata.get(i),  mbulkdata.get(i+1)));\n        \t\t}\n        \t}\n        \treturn zset;\n        }\n\t}\n\t// ------------------------------------------------------------------------\n\t// Diagnostics commands\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @Redis ECHO\n\t * @param msg\n\t * @return\n\t */\n\tpublic <K extends Object> Future<byte[]> echo (byte[] msg) {\n\t\tif(msg == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid value for echo => [null]\");\n\n\t\tFuture<Response> futureResponse = this.queueRequest(Command.ECHO, msg);\n\t\treturn new FutureByteArray(futureResponse);\n\t\t\n\t}\n\tpublic <K extends Object> Future<byte[]> echo (String msg) {\n\t\treturn echo(DefaultCodec.encode(msg));\n\t}\n\tpublic <K extends Object> Future<byte[]> echo (Number msg) {\n\t\treturn echo(String.valueOf(msg).getBytes());\n\t}\n\tpublic <K extends Object, T extends Serializable>\n\t\tFuture<byte[]> echo (T msg) {\n\t\t\treturn echo (DefaultCodec.encode(msg));\n\t}\n\t\n\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisPipeline.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.JRedisFuture;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.connection.AsyncPipelineConnection;\n\n/**\n * Asynchronous Redis client implementing {@link JRedisFuture} and using \n * an {@link AsyncPipelineConnection} for command processing.\n * <p>\n * TODO: details the usage and characteristics.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Sep 21, 2009\n * @since   alpha.0\n * \n */\n\n//@Redis(versions={\"1.00\"})\npublic class JRedisPipeline extends JRedisFutureSupport {\n\t\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\t/**  */\n\tfinal private Connection\tconnection;\n\n\t// ------------------------------------------------------------------------\n\t// Construct and initialize\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * @param connectionSpec\n\t */\n\tpublic JRedisPipeline (ConnectionSpec connectionSpec) {\n\t\t// note: using a non shared connection mod\n\t\tconnection = new AsyncPipelineConnection(connectionSpec);\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Super overrides\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Requests to server are queued at this point.  Any requests after a {@link Command#QUIT} will\n\t * raise an exception indicating the pipeline is shutting down.  \n\t * @see org.jredis.ri.alphazero.JRedisFutureSupport#queueRequest(org.jredis.protocol.Command, byte[][])\n\t */\n\tprotected  Future<Response> queueRequest (Command cmd, byte[]...args) throws ClientRuntimeException, ProviderException {\n\t\treturn connection.queueRequest(cmd, args);\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// public interface\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Provides a synchronous semantics interface ({@link JRedis}) to this pipeline.\n\t * Note that this is <b>not a thread-safe mechanism</b>.  If you need a pipeline\n\t * connection with support for concurrent synchronous semantics, use a {@link JRedisPipelineService}.\n\t *  \n\t * @return the {@link JRedis} interface for this pipeline.\n\t */\n\tpublic JRedis sync () {\n\t\treturn new JRedisSupport() {\n\t\t\t@Override\n            protected Response serviceRequest (Command cmd, byte[]... args) throws RedisException, ClientRuntimeException, ProviderException {\n\t\t\t\tResponse response = null;\n\t\t\t\ttry {\n\t                response = JRedisPipeline.this.queueRequest(cmd, args).get();\n                }\n                catch (InterruptedException e) {\n\t                throw new ClientRuntimeException(\"Interrupted!\", e);\n                }\n                catch (ExecutionException e) {\n                \tThrowable cause = e.getCause();\n                \tif(cause instanceof RedisException)\n                \t\tthrow (RedisException) cause;\n                \telse if(cause instanceof ProviderException)\n                \t\tthrow (ProviderException) cause;\n                \telse if(cause instanceof ClientRuntimeException) \n                \t\tthrow (ClientRuntimeException)cause;\n                \telse throw new ClientRuntimeException(\"Exception in pipeline exec of requested command\", cause);\n                }\n                return response;\n            }\n\t\t};\n\t}\n\t/**\n\t * \n\t * @param timeout\n\t * @param unit\n\t * @return\n\t */\n\tpublic JRedis sync (final long timeout, final TimeUnit unit) {\n\t\treturn new JRedisSupport() {\n\t\t\t@Override\n            protected Response serviceRequest (Command cmd, byte[]... args) throws RedisException, ClientRuntimeException, ProviderException {\n\t\t\t\tResponse response = null;\n\t\t\t\ttry {\n\t                response = JRedisPipeline.this.queueRequest(cmd, args).get(timeout, unit);\n                }\n                catch (InterruptedException e) {\n\t                throw new ClientRuntimeException(\"Interrupted!\", e);\n                }\n                catch (TimeoutException e) {\n\t                throw new ClientRuntimeException(\"timedout waiting for response\");\n                }\n                catch (ExecutionException e) {\n                \tThrowable cause = e.getCause();\n                \tif(cause instanceof RedisException)\n                \t\tthrow (RedisException) cause;\n                \telse if(cause instanceof ProviderException)\n                \t\tthrow (ProviderException) cause;\n                \telse if(cause instanceof ClientRuntimeException) \n                \t\tthrow (ClientRuntimeException)cause;\n                \telse throw new ClientRuntimeException(\"Exception in pipeline exec of requested command\", cause);\n                }\n                return response;\n            }\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisPipelineService.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.connection.SyncPipelineConnection;\n\n/**\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 6, 2009\n * @since   alpha.0\n * \n */\n\npublic class JRedisPipelineService extends SyncJRedisBase {\n\n\t// ------------------------------------------------------------------------\n\t// Consts\n\t// ------------------------------------------------------------------------\n\n\t\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\t/** connection spec shared by all connections in pool */\n\t@SuppressWarnings(\"unused\")\n    private final ConnectionSpec \tconnectionSpec;\n\t\n\tprivate final Connection connection;\n\n\t// ------------------------------------------------------------------------\n\t// Construct and initialize\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @param host\n\t * @param port\n\t * @param password\n\t * @param database\n\t * @param connectionCount\n\t */\n\tpublic JRedisPipelineService (String host, int port, String password, int database) {\n\t\tthis(DefaultConnectionSpec.newSpec(host, port, database, (password != null ? password.getBytes() : null)));\n\t}\n\t\n\t/**\n\t * @param connectionSpec\n\t * @param connectionCount\n\t */\n\tpublic JRedisPipelineService (ConnectionSpec connectionSpec) {\n\t\tthis.connectionSpec = connectionSpec;\n\t\tconnectionSpec.setConnectionFlag(Connection.Flag.SHARED, Boolean.TRUE);\n\t\tconnection = new SyncPipelineConnection(connectionSpec);\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// super overrides.\n\t// ------------------------------------------------------------------------\n\t/* (non-Javadoc)\n\t * @see org.jredis.ri.alphazero.SynchJRedisBase#setConnection(org.jredis.connector.Connection)\n\t */\n\t@Override\n\tprotected final void setConnection (Connection connection) {\n\t\tthrow new RuntimeException(\"who called me?\");\n\t}\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.ri.alphazero.JRedisSupport#serviceRequest(org.jredis.protocol.Command, byte[][])\n\t */\n\t@Override\n\tprotected Response serviceRequest (Command cmd, byte[]... args) throws RedisException, ClientRuntimeException, ProviderException {\n\t\treturn connection.serviceRequest(cmd, args);\n\t}\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.resource.Resource#getInterface()\n\t */\n\tpublic JRedis getInterface () {\n\t\treturn this;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisService.java",
    "content": "///*\n// *   Copyright 2009 Joubin Houshyar\n// * \n// *   Licensed under the Apache License, Version 2.0 (the \"License\");\n// *   you may not use this file except in compliance with the License.\n// *   You may obtain a copy of the License at\n// *    \n// *   http://www.apache.org/licenses/LICENSE-2.0\n// *    \n// *   Unless required by applicable law or agreed to in writing, software\n// *   distributed under the License is distributed on an \"AS IS\" BASIS,\n// *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *   See the License for the specific language governing permissions and\n// *   limitations under the License.\n// */\n//\n//package org.jredis.ri.alphazero;\n//\n//import java.util.concurrent.Semaphore;\n//import org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\n//import org.jredis.ProviderException;\n//import org.jredis.RedisException;\n//import org.jredis.connector.Connection;\n//import org.jredis.connector.ConnectionSpec;\n//import org.jredis.protocol.Command;\n//import org.jredis.protocol.Response;\n//import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n//import org.jredis.ri.alphazero.support.Assert;\n//import org.jredis.ri.alphazero.support.Log;\n//\n///**\n// * This class utilizes a (configurable) number of {@link Connection}s in a pool\n// * and can be utilized in multi-threaded usage contexts, such as web containers,\n// * etc.  \n// * <p>\n// * The service uses an internal pool of connections (see {@link JRedisService#default_connection_count}.  If\n// * the number of service requests being processed reaches that limit, then any further calls will block until\n// * a connection becomes available.  \n// * <p>\n// *\n// * @author  Joubin Houshyar (alphazero@sensesay.net)\n// * @version alpha.0, Apr 21, 2009\n// * @since   alpha.0\n// * \n// */\n//\n//public class JRedisService extends SynchJRedisBase {\n//\n//\t// ------------------------------------------------------------------------\n//\t// Consts\n//\t// ------------------------------------------------------------------------\n//\t/** Default value: 5 */\n//\tpublic static final int \tdefault_connection_count = 5;\n//\t\n//\t// ------------------------------------------------------------------------\n//\t// Properties\n//\t// ------------------------------------------------------------------------\n//\n//\t/** counting semaphore for limiting concurrent access to pool to the count */\n//\tprivate Semaphore   \t\t\tconnPoolAccess;\n//\t/** in use flag for the connections */\n//\tprivate boolean \t\t\t\tconnInUse[];\n//\t/** the connections */\n//\tprivate Connection \t\t\t\tconns[];\n//\t\n//\t/** connection spec shared by all connections in pool */\n//\tprivate final ConnectionSpec \tconnectionSpec;\n//\t/** number of connections in pool */\n//\tprivate final int\t\t\t\tconnCount;\n//\n//\t// ------------------------------------------------------------------------\n//\t// Construct and initialize\n//\t// ------------------------------------------------------------------------\n//\t\n//\t/**\n//\t * @param host\n//\t * @param port\n//\t */\n//\tpublic JRedisService (String host, int port) {\n//\t\tthis(host, port, null, 0, default_connection_count);\n//\t}\n//\t\n//\t/**\n//\t * @param host\n//\t * @param port\n//\t * @param password\n//\t * @param database\n//\t * @param connectionCount\n//\t */\n//\tpublic JRedisService (String host, int port, String password, int database, int connectionCount) {\n//\t\tbyte[] credentials = password != null ? password.getBytes() : null;\n//\t\tconnectionSpec = DefaultConnectionSpec.newSpec(host, port, database, credentials);\n//\t\tconnCount = connectionCount;\n//\t\tinitialize();\n//\t}\n//\t\n//\t/**\n//\t * @param connectionSpec\n//\t * @param connectionCount\n//\t */\n//\tpublic JRedisService (ConnectionSpec connectionSpec, int connectionCount) {\n//\t\tthis.connectionSpec = connectionSpec;\n//\t\t// regardless of user spec, service has to assume shared connections\n//\t\tconnectionSpec.setConnectionFlag(Connection.Flag.SHARED, true);\n//\t\tconnCount = connectionCount;\n//\t\t\n//\t\tinitialize();\n//\t}\n//\t\n//\t/**\n//\t * Initialize the connection pool using the connection spec.\n//\t */\n//\tprivate final void initialize () {\n//\t\tconnPoolAccess = new Semaphore(connCount);\n//\t\tconns = new Connection[connCount];\n//\t\tconnInUse = new boolean [connCount];\n//\t\tConnection conn = null;\n//\t\tconnectionSpec.setConnectionFlag(Connection.Flag.RELIABLE, true);\n//\t\tconnectionSpec.setConnectionFlag(Connection.Flag.SHARED, true);\n//\t\tfor(int i=0; i< connCount;i++) {\n//\t\t\ttry {\n//\t\t\t\tconn = Assert.notNull(createSynchConnection(connectionSpec), \"Connection \" + i, ClientRuntimeException.class);\n//\t\t\t\tconns[i] = conn;\n//\t\t\t\tconnInUse[i] = false;\n//\t\t\t} \n//\t\t\tcatch (Exception e) {\n//\t\t\t\t// TODO: remove this stacktrace\n//\t\t\t\te.printStackTrace();\n//\t\t\t\tthrow new ClientRuntimeException(\"Could not create connection for service\", e);\n//\t\t\t}\t\t\n//\t\t}\n//\t}\n//\n//\t// ------------------------------------------------------------------------\n//\t// super overrides.\n//\t// ------------------------------------------------------------------------\n//\t/* (non-Javadoc)\n//\t * @see org.jredis.ri.alphazero.SynchJRedisBase#setConnection(org.jredis.connector.Connection)\n//\t */\n//\t@Override\n//\tprotected void setConnection(Connection connection) {\n//\t\tthrow new RuntimeException(\"who called me?\");\n//\t}\n//\n//\t\n//\t/* (non-Javadoc)\n//\t * @see org.jredis.ri.alphazero.JRedisSupport#serviceRequest(org.jredis.protocol.Command, byte[][])\n//\t */\n//\t@Override\n//\tprotected Response serviceRequest(Command cmd, byte[]... args)\n//\t\t\tthrows RedisException, ClientRuntimeException, ProviderException \n//\t{\n//\t\tResponse response = null;\n//\t\t\n//\t\ttry {\n//\t\t\t// we're using a counting semaphore to remain within\n//\t\t\t// bounds of the connection count\n//\t\t\t// if more than cnt requests are being serviced, we block here\n//\t\t\tconnPoolAccess.acquire();\n//\t\t\t\n//\t\t\tint i = 0;\n//\t\t\ttry {\n//\t\t\t\t// bare bones connection pool - mark the first available\n//\t\t\t\t// connection as inUse and then use it\n//\t\t\t\t// this is faster than using the synch collections of JDK and sufficient\n//\t\t\t\tsynchronized(connInUse){\t// Note: could use finer grained sync on conns[i] in loop instead ..\n//\t\t\t\t\tfor(; i<connInUse.length;i++){\n//\t\t\t\t\t\tif(connInUse[i]==false) {\n//\t\t\t\t\t\t\tconnInUse[i] = true;\n//\t\t\t\t\t\t\tbreak;\n//\t\t\t\t\t\t}\n//\t\t\t\t\t}\n//\t\t\t\t}\n//\t\t\t\t\n//\t\t\t\t// This shouldn't happen -- but lets make sure, hey?\n//\t\t\t\tif(i>=connCount) \n//\t\t\t\t\tthrow new ProviderException(\"BUG: JRedisService connection pool manager - index exceeds bounds!\");\n//\t\t\t\t\n//\t\t\t\tresponse = conns[i].serviceRequest(cmd, args);\n//\t\t\t}\n//\t\t\tfinally {\n//\t\t\t\t// return the connection to the pool\n//\t\t\t\tsynchronized(connInUse){\n//\t\t\t\t\tif(connInUse[i] != true) \n//\t\t\t\t\t\tthrow new ProviderException(\"BUG: JRedisService connection pool manager - connection should have been marked in use!\");\n//\t\t\t\t\tconnInUse[i] = false;\n//\t\t\t\t}\n//\t\t\t\t\n//\t\t\t\t// release the bounds sem.\n//\t\t\t\tconnPoolAccess.release();\n//\t\t\t}\n//\t\t} \n//\t\tcatch (InterruptedException e) {\n//\t\t\t// TODO: need meaningful action here\n//\t\t\t// its not clear what can be done since the interrupt is occurring on the\n//\t\t\t// user (calling) thread and is not connection specific, and the situation\n//\t\t\t// is ambiguous.  We can note it for now.\n//\t\t\te.printStackTrace();\n//\t\t\tLog.log(\"Thread <%s> was interrupted in JRedisService.serviceRequest\", Thread.currentThread().getName());\n//\t\t}\n//\t\treturn response;\n//\t}\n//\t// ------------------------------------------------------------------------\n//\t// Interface\n//\t// =========================================================== Resource<T>\n//\t/*\n//\t * Provides basic Resource support without any state management.  Extensions\n//\t * that use context in a simply manner can rely on these methods.  Others may\n//\t * wish to override.\n//\t */\n//\t// ------------------------------------------------------------------------\n//\t\n//\t/* (non-Javadoc)\n//\t * @see org.jredis.resource.Resource#getInterface()\n//\t */\n////\t@Override\n//\tpublic JRedis getInterface() {\n//\t\treturn this;\n//\t}\n//}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/JRedisSupport.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.StringTokenizer;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.KeyValueSet;\nimport org.jredis.ObjectInfo;\nimport org.jredis.ProviderException;\nimport org.jredis.Redis;\nimport org.jredis.RedisException;\nimport org.jredis.RedisType;\nimport org.jredis.Sort;\nimport org.jredis.ZSetEntry;\nimport org.jredis.connector.Connection;\nimport org.jredis.protocol.BulkResponse;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.MultiBulkResponse;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ValueResponse;\nimport org.jredis.ri.RI.Release;\nimport org.jredis.ri.RI.Version;\nimport org.jredis.ri.alphazero.semantics.DefaultKeyCodec;\nimport org.jredis.ri.alphazero.support.Convert;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\nimport org.jredis.ri.alphazero.support.SortSupport;\n\n/**\n * \n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 10, 2009\n * @since   alpha.0\n *\n */\npublic abstract class JRedisSupport implements JRedis {\n\t\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\t// ------------------------------------------------------------------------\n\t// Constructors\n\t// ------------------------------------------------------------------------\n\t\n\t// ------------------------------------------------------------------------\n\t// Extension point(s)\n\t/*\n\t * This class provides the convenience of a uniform implementation wide mapping\n\t * of JRedis api semantics to the native protocol level semantics of byte[]s.\n\t * \n\t * Extensions can use the provided extension points to provide or delegate the\n\t * servicing of request calls.  \n\t */\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * This method mimics the eponymous {@link Connection#serviceRequest(Command, byte[]...)}\n\t * which defines the blocking api semantics of Synchronous connections.  The extending class\n\t * can either directly (a) implement the protocol requirements, or, (b) delegate to a\n\t * {@link Connection} instance, or, (c) utilize a pool of {@link Connection}s.  \n\t * \n\t * @param cmd\n\t * @param args\n\t * @return\n\t * @throws RedisException\n\t * @throws ClientRuntimeException\n\t * @throws ProviderException\n\t */\n\tprotected abstract Response serviceRequest (Command cmd, byte[]...args) throws RedisException, ClientRuntimeException, ProviderException; \n\t// ------------------------------------------------------------------------\n\t// INTERFACE\n\t// ================================================================ Redis\n\t/*\n\t * Support of all the JRedis interface methods.\n\t * \n\t * This class uses the UTF-8 character set for all conversions due to its\n\t * use of the Convert and Codec support classes.\n\t * \n\t * All calls are forwarded to an abstract serviceRequest method that the\n\t * extending classes are expected to implement.  \n\t * \n\t * Implementation note:\n\t * The methods in this class use redundant code in marshalling request params\n\t * and in unmarshalling the response data.  We certainly can use a few helper\n\t * functions to reduce the redundancy, but given that such methods would be\n\t * repeatedly called, it was decided to effectively inline these statements in \n\t * each method body.  \n\t */\n\t// ------------------------------------------------------------------------\n\n\n\t@Override\n\tpublic <K> boolean setbit(K key, int offset, boolean value) throws ProviderException, ClientRuntimeException, RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* ValueRespose */\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SETBIT, keybytes, Convert.toBytes(offset), Convert.toBytes(value ? 1 : 0));\n\t\t\treturn valResponse.getLongValue() == 1;\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t}\n\n\n\t@Override\n\tpublic <K> boolean getbit(K key, int offset) throws ProviderException, ClientRuntimeException, RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* ValueRespose */\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.GETBIT, keybytes, Convert.toBytes(offset));\n\t\t\treturn valResponse.getLongValue() == 1;\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t}\n\n\n\t//\t@Override\n//\tpublic <K extends Object> JRedis auth(K key) throws RedisException {\n//\t\tbyte[] keydata = null;\n//\t\tif((keydata = getKeyBytes(key)) == null) \n//\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n//\n//\t\tthis.serviceRequest(Command.AUTH, keydata);\n//\t\treturn this;\n//\t}\n\t@Override\n\tpublic <K extends Object> void bgsave() throws RedisException {\n\t\tthis.serviceRequest(Command.BGSAVE);\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> String bgrewriteaof() throws RedisException {\n\t\t/* boolean ValueRespose */\n\t\tString value = null;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.BGREWRITEAOF);\n\t\t\tvalue = valResponse.getStringValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> JRedis ping() throws RedisException {\n\t\tthis.serviceRequest(Command.PING);\n\t\treturn this;\n\t}\n\n\t@Override\n\tpublic <K extends Object> JRedis flushall() throws RedisException {\n\t\tthis.serviceRequest(Command.FLUSHALL).getStatus();\n\t\treturn this;\n\t}\n\t@Override\n\tpublic <K extends Object> JRedis flushdb() throws RedisException {\n\t\tthis.serviceRequest(Command.FLUSHDB).getStatus();\n\t\treturn this;\n\t}\n//\t@Override\n//\tpublic <K extends Object> JRedis select(int index) throws RedisException {\n//\t\tthis.serviceRequest(Command.SELECT, Convert.toBytes(index));\n//\t\treturn this;\n//\t}\n\t\n\tpublic <K extends Object> void slaveof(String host, int port) throws RedisException{\n\t\tbyte[] hostbytes = null;\n\t\tif((hostbytes = getKeyBytes(host)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid host => [\"+host+\"]\");\n\n\t\tbyte[] portbytes = null;\n\t\tif((portbytes = Convert.toBytes(port)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid port => [\"+port+\"]\");\n\n\t\tthis.serviceRequest(Command.SLAVEOF, hostbytes, portbytes);\n\t}\n\t\n\tpublic <K extends Object> void slaveofnone() throws RedisException{\n\t\tthis.serviceRequest(Command.SLAVEOF, \"no\".getBytes(), \"one\".getBytes());\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> void rename(K oldkey, K newkey) throws RedisException {\n\t\tbyte[] oldkeydata = null;\n\t\tif((oldkeydata = getKeyBytes(oldkey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+oldkey+\"]\");\n\n\t\tbyte[] newkeydata = null;\n\t\tif((newkeydata = getKeyBytes(newkey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+newkey+\"]\");\n\n\t\tthis.serviceRequest(Command.RENAME, oldkeydata, newkeydata);\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> boolean renamenx(K oldkey, K newkey) throws RedisException{\n\t\tbyte[] oldkeydata = null;\n\t\tif((oldkeydata = getKeyBytes(oldkey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+oldkey+\"]\");\n\n\t\tbyte[] newkeydata = null;\n\t\tif((newkeydata = getKeyBytes(newkey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+newkey+\"]\");\n\n\t\t/* boolean ValueRespose */\n\t\tboolean value = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.RENAMENX, oldkeydata, newkeydata);\n\t\t\tvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\t@Override\n\tpublic <K extends Object> byte[] rpoplpush(K srcList, K destList) \n\tthrows RedisException \n\t{\n\t\tbyte[] srckeybytes = null;\n\t\tif((srckeybytes = getKeyBytes(srcList)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid src key => [\"+srcList+\"]\");\n\t\tbyte[] destkeybytes = null;\n\t\tif((destkeybytes = getKeyBytes(destList)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid dest key => [\"+destList+\"]\");\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.RPOPLPUSH, srckeybytes, destkeybytes);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t\t\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> void rpush(K key, byte[] value) \n\tthrows RedisException \n\t{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t\n\t\tif(value == null) \n\t\t\tthrow new IllegalArgumentException (\"null value for list op\");\n\t\t\n\t\tthis.serviceRequest(Command.RPUSH, keybytes, value);\n\t}\n\t@Override\n\tpublic <K extends Object> void rpush(K key, String value) throws RedisException {\n//\t\trpush(key, DefaultCodec.encode(value));\n\t\trpush(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> void rpush(K key, Number value) throws RedisException {\n\t\trpush(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> void rpush (K key, T value) throws RedisException\n\t{\n\t\trpush(key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean sadd(K key, byte[] member) \n\tthrows RedisException \n\t{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t/* boolean ValueRespose */\n\t\tboolean res = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SADD, keybytes, member);\n\t\t\tres = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn res;\n\t}\n\t@Override\n\tpublic <K extends Object> boolean sadd (K key, String value) throws RedisException {\n\t\treturn sadd (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> boolean sadd (K key, Number value) throws RedisException {\n\t\treturn sadd (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> boolean sadd (K key, T value) throws RedisException\n\t{\n\t\treturn sadd (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean zadd(K key, double score, byte[] member) \n\tthrows RedisException \n\t{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t/* boolean ValueRespose */\n\t\tboolean res = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.ZADD, keybytes, Convert.toBytes(score), member);\n\t\t\tres = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn res;\n\t}\n\t@Override\n\tpublic <K extends Object> boolean zadd (K key, double score, String value) throws RedisException {\n\t\treturn zadd (key, score, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> boolean zadd (K key, double score, Number value) throws RedisException {\n\t\treturn zadd (key, score, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> boolean zadd (K key, double score, T value) throws RedisException\n\t{\n\t\treturn zadd (key, score, DefaultCodec.encode(value));\n\t}\n\n\t@SuppressWarnings(\"boxing\")\n\t@Override\n\tpublic <K extends Object> Double zincrby(K key, double score, byte[] member) \n\tthrows RedisException \n\t{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t/* Double BulkResponse */\n\t\tDouble resvalue = null;\n\t\ttry {\n\t\t\tBulkResponse bulkResponse = (BulkResponse) this.serviceRequest(Command.ZINCRBY, keybytes, Convert.toBytes(score), member);\n\t\t\tif (bulkResponse.getBulkData() != null)\n\t\t\t\tresvalue = Convert.toDouble(bulkResponse.getBulkData());\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> Double zincrby (K key, double score, String value) throws RedisException {\n\t\treturn zincrby (key, score, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Double zincrby (K key, double score, Number value) throws RedisException {\n\t\treturn zincrby (key, score, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Double zincrby (K key, double score, T value) throws RedisException\n\t{\n\t\treturn zincrby (key, score, DefaultCodec.encode(value));\n\t}\n\n\t\n\t@Override\n\tpublic <K extends Object> void save() \n\tthrows RedisException \n\t{\n\t\tthis.serviceRequest(Command.SAVE);\n\t}\n\t\n\t// -------- set \n\n\t@Override\n\tpublic <K extends Object> void set(K key, byte[] value) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tthis.serviceRequest(Command.SET, keybytes, value);\n\t}\n\t@Override\n\tpublic <K extends Object> void set(K key, String value) throws RedisException {\n\t\tset(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> void set(K key, Number value) throws RedisException {\n\t\tset(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> void set (K key, T value) throws RedisException\n\t{\n\t\tset(key, DefaultCodec.encode(value));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> byte[] getset(K key, byte[] value) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.GETSET, keybytes, value);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\t@Override\n\tpublic <K extends Object> byte[] getset(K key, String value) throws RedisException {\n\t\treturn getset(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> byte[] getset(K key, Number value) throws RedisException {\n\t\treturn getset(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> \n\tbyte[] getset (K key, T value) throws RedisException\n\t{\n\t\treturn getset(key, DefaultCodec.encode(value));\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> boolean setnx(K key, byte[] value) throws RedisException{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SETNX, keybytes, value);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> boolean setnx(K key, String value) throws RedisException {\n\t\treturn setnx(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> boolean setnx(K key, Number value) throws RedisException {\n\t\treturn setnx(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> boolean setnx (K key, T value) throws RedisException {\n\t\treturn setnx(key, DefaultCodec.encode(value));\n\t}\n\n\t\n\t@Override\n\tpublic <K extends Object> long append(K key, byte[] value) throws RedisException{\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tlong resvalue = -1;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.APPEND, keybytes, value);\n\t\t\tresvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> long append(K key, String value) throws RedisException {\n\t\treturn append(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> long append(K key, Number value) throws RedisException {\n\t\treturn append(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> long append (K key, T value) throws RedisException {\n\t\treturn append(key, DefaultCodec.encode(value));\n\t}\n\n\tprivate boolean msetnx(byte[][] mappings) throws RedisException {\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.MSETNX, mappings);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> boolean msetnx(Map<K, byte[]> keyValueMap) throws RedisException {\n//\t\tKeyCodec<Object> codec = DefaultKeyCodec.provider();\n\t\tbyte[][] mappings = new byte[keyValueMap.size()*2][];\n\t\tint i = 0;\n\t\tfor (Entry<K, byte[]> e : keyValueMap.entrySet()){\n\t\t\tmappings[i++] = getKeyBytes(e.getKey());\n\t\t\tmappings[i++] = e.getValue();\n\t\t}\n\t\treturn msetnx(mappings);\n\t}\n\t@Override\n\tpublic <K extends Object> boolean msetnx(KeyValueSet.ByteArrays<K> keyValueMap) throws RedisException {\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\t@Override\n\tpublic <K extends Object> boolean msetnx(KeyValueSet.Strings<K> keyValueMap) throws RedisException{\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\t@Override\n\tpublic <K extends Object> boolean msetnx(KeyValueSet.Numbers<K> keyValueMap) throws RedisException{\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> boolean msetnx(KeyValueSet.Objects<K, T> keyValueMap) throws RedisException{\n\t\treturn msetnx(keyValueMap.getMappings());\n\t}\n\n\t\n\t@Override\n\tpublic <K extends Object> boolean sismember(K key, byte[] member) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* boolean ValueRespose */\n\t\tboolean value = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SISMEMBER, keybytes, member);\n\t\t\tvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean sismember(K key, String value) throws RedisException {\n\t\treturn sismember(key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean sismember(K key, Number numberValue) throws RedisException {\n\t\treturn sismember (key, String.valueOf(numberValue).getBytes());\n\t}\n\n\t@Override\n\tpublic <K extends Object, T extends Serializable> boolean sismember(K key, T object) throws RedisException {\n\t\treturn sismember(key, DefaultCodec.encode(object));\n\t}\n\n\tpublic <K extends Object> boolean smove (K srcKey, K destKey, byte[] member) throws RedisException {\n\t\tbyte[] srcKeyBytes = null;\n\t\tif((srcKeyBytes = getKeyBytes(srcKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+srcKey+\"]\");\n\n\t\tbyte[] destKeyBytes = null;\n\t\tif((destKeyBytes = getKeyBytes(destKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+destKey+\"]\");\n\n\t\t/* boolean ValueRespose */\n\t\tboolean value = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SMOVE, srcKeyBytes, destKeyBytes, member);\n\t\t\tvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\tpublic <K extends Object> boolean smove (K srcKey, K destKey, String stringValue) throws RedisException {\n\t\treturn smove (srcKey, destKey, DefaultCodec.encode(stringValue));\n\t}\n\tpublic <K extends Object> boolean smove (K srcKey, K destKey, Number numberValue) throws RedisException {\n\t\treturn smove (srcKey, destKey, String.valueOf(numberValue).getBytes());\n\t}\n\tpublic <K extends Object, T extends Serializable> \n\tboolean smove (K srcKey, K destKey, T object) throws RedisException {\n\t\treturn smove (srcKey, destKey, DefaultCodec.encode(object));\n\t}\n\t\t   \n\t// ------------------------------------------------------------------------\n\t// Commands operating on hashes\n\t// ------------------------------------------------------------------------\n\t\n\tpublic <K extends Object> boolean hset(K hashKey, K hashField, byte[] value)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tbyte[] hashFieldBytes = null;\n\t\tif((hashFieldBytes = getKeyBytes(hashField)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+hashField+\"]\");\n\n\t\t/* boolean ValueRespose */\n\t\tboolean response = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.HSET, hashKeyBytes, hashFieldBytes, value);\n\t\t\tresponse = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn response;\n\t}\n\tpublic <K extends Object> boolean hset(K key, K field, String stringValue)  throws RedisException {\n\t\treturn hset (key, field, DefaultCodec.encode(stringValue));\n\t}\n\tpublic <K extends Object> boolean hset(K key, K field, Number numberValue)  throws RedisException {\n\t\treturn hset (key, field, String.valueOf(numberValue).getBytes());\n\t}\n\tpublic <K extends Object, T extends Serializable> \n\tboolean hset(K key, K field, T object)  throws RedisException {\n\t\treturn hset (key, field, DefaultCodec.encode(object));\n\t}\n\t\n\tpublic <K extends Object> byte[] hget(K hashKey, K hashField)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tbyte[] hashFieldBytes = null;\n\t\tif((hashFieldBytes = getKeyBytes(hashField)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+hashField+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.HGET, hashKeyBytes, hashFieldBytes);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\t\n\tpublic <K extends Object> boolean hexists(K hashKey, K hashField)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tbyte[] hashFieldBytes = null;\n\t\tif((hashFieldBytes = getKeyBytes(hashField)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+hashField+\"]\");\n\n\t\tboolean resp = false;\n\t\ttry {\n\t\t\tValueResponse response = (ValueResponse) this.serviceRequest(Command.HEXISTS, hashKeyBytes, hashFieldBytes);\n\t\t\tresp = response.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\t@Override\n\tpublic <K extends Object> boolean hdel(K hashKey, K hashField)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tbyte[] hashFieldBytes = null;\n\t\tif((hashFieldBytes = getKeyBytes(hashField)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid field => [\"+hashField+\"]\");\n\n\t\tboolean resp = false;\n\t\ttry {\n\t\t\tValueResponse response = (ValueResponse) this.serviceRequest(Command.HDEL, hashKeyBytes, hashFieldBytes);\n\t\t\tresp = response.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\t@Override\n\tpublic <K extends Object> long hlen(K hashKey)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tlong resp = 0;\n\t\ttry {\n\t\t\tValueResponse response = (ValueResponse) this.serviceRequest(Command.HLEN, hashKeyBytes);\n\t\t\tresp = response.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\t@Redis(versions=\"1.3.n\")\n\t@Override\n\tpublic <K extends Object> List<byte[]> hkeys(K hashKey)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tList<byte[]> multibulkData = null;\n\t\ttry {\n\t\t\tMultiBulkResponse response = (MultiBulkResponse) this.serviceRequest(Command.HKEYS, hashKeyBytes);\n//\t\t\tif(null != response.getMultiBulkData()) resp = DefaultCodec.toStr(response.getMultiBulkData());\n\t\t\tmultibulkData = response.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multibulkData;\n\t}\n\n\t@Redis(versions=\"1.3.n\")\n\t@Override\n\tpublic <K extends Object> List<byte[]> hvals(K hashKey)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tList<byte[]> resp = null;\n\t\ttry {\n\t\t\tMultiBulkResponse response = (MultiBulkResponse) this.serviceRequest(Command.HVALS, hashKeyBytes);\n\t\t\tresp = response.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\n\t@Redis(versions=\"1.3.n\")\n\t@Override\n\tpublic <K extends Object> Map<byte[], byte[]> hgetall(K hashKey)  throws RedisException {\n\t\tbyte[] hashKeyBytes = null;\n\t\tif((hashKeyBytes = getKeyBytes(hashKey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+hashKey+\"]\");\n\n\t\tMap<byte[], byte[]> resp = null;\n\t\ttry {\n\t\t\tMultiBulkResponse response = (MultiBulkResponse) this.serviceRequest(Command.HGETALL, hashKeyBytes);\n\t\t\tList<byte[]> bulkdata = response.getMultiBulkData();\n\t\t\tif(null != bulkdata) {\n\t\t\t\tresp = new HashMap<byte[], byte[]>(bulkdata.size()/2);\n\t\t\t\tfor(int i=0; i<bulkdata.size(); i+=2){\n\t\t\t\t\tresp.put(bulkdata.get(i), bulkdata.get(i+1));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\n\t\n\t/* ------------------------------- commands returning int value --------- */\n\n\t@Override\n\tpublic <K extends Object> long incr(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* ValueRespose */\n\t\tlong value = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.INCR, keybytes);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long incrby(K key, int delta) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* ValueRespose */\n\t\tlong value = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.INCRBY, keybytes, Convert.toBytes(delta));\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long decr(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* ValueRespose */\n\t\tlong value = Long.MAX_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.DECR, keybytes);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long decrby(K key, int delta) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* ValueRespose */\n\t\tlong value = Long.MAX_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.DECRBY, keybytes, Convert.toBytes(delta));\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long llen(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t/* ValueRespose */ /* int since max size is 1GB, an integer 1,073,741,824 */\n\t\tlong value = Integer.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.LLEN, keybytes);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long scard(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\tlong value = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SCARD, keybytes);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> long zcard(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\tlong value = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.ZCARD, keybytes);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\t\n\tpublic <K extends Object> byte[] srandmember (K setkey) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(setkey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+setkey+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.SRANDMEMBER, keybytes);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\n\tpublic <K extends Object> byte[] spop (K setkey) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(setkey)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+setkey+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.SPOP, keybytes);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\n\t/* ------------------------------- commands returning long value --------- */\n\n\t@Override\n\tpublic <K extends Object> long dbsize() throws RedisException {\n\t\tlong value = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.DBSIZE);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\t@Override\n\tpublic <K extends Object> long lastsave() throws RedisException {\n\t\tlong value = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.LASTSAVE);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/* ------------------------------- commands returning byte[] --------- */\n\n\t@Override\n\tpublic <K extends Object> byte[] get(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.GET, keybytes);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> byte[] lindex(K key, long index) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.LINDEX, keybytes, Convert.toBytes(index));\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\t@Override\n\tpublic <K extends Object> byte[] lpop(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.LPOP, keybytes);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> byte[] rpop(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.RPOP, keybytes);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\n\n\t/* ------------------------------- commands returning String--------- */\n\n\t@Override\n\tpublic byte[] randomkey() throws RedisException {\n\t\t/* ValueRespose */\n\t\tbyte[] bulkData = null;\n//\t\tString stringValue = null;\n\t\ttry {\n\t\t\tBulkResponse valResponse = (BulkResponse) this.serviceRequest(Command.RANDOMKEY);\n\t\t\tbulkData = valResponse.getBulkData();\n//\t\t\tif (null != bulkData) {\n//\t\t\t  stringValue = new String(bulkData);\n//\t\t\t}\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n//\t\treturn stringValue;\n\t\treturn bulkData;\n\t}\n\t@Override\n\tpublic <K extends Object> RedisType type(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tRedisType\ttype = null;\n\t\t/* ValueRespose */\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.TYPE, keybytes);\n\t\t\tString stringValue = valResponse.getStringValue();\n\t\t\ttype = RedisType.valueOf(stringValue);\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn type;\n\t}\n\n\t@Override\n\tpublic <K extends Object> ObjectInfo debug (K key) throws RedisException {\n\t\t\n\t\tbyte[] keybytes = getKeyBytes(key);\n//\t\tif(key.length() == 0)\n//\t\t\tthrow new IllegalArgumentException (\"invalid zero length key => [\"+key+\"]\");\n\n\t\tObjectInfo\tobjectInfo = null;\n\t\t/* ValueRespose */\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.DEBUG, \"OBJECT\".getBytes(), keybytes);\n\t\t\tString stringValue = valResponse.getStringValue();\n\t\t\tobjectInfo = ObjectInfo.valueOf(stringValue);\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn objectInfo;\n\t}\n\t/* ------------------------------- commands returning Maps --------- */\n\n\t@Override\n\tpublic <K extends Object> Map<String, String> info() throws RedisException {\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.INFO);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\n\t\tStringTokenizer tokenizer = new StringTokenizer(new String(bulkData), \"\\r\\n\");\n\t\tMap<String, String>  infomap = new HashMap<String, String>(48);\n\t\twhile (tokenizer.hasMoreTokens()){\n\t\t\tString info = tokenizer.nextToken();\n\t\t\tSystem.out.format(\"line:<%s>\\n\", info);\n\t\t\t// ignore comments \"# heading\"\n\t\t\tif(info.startsWith(\"#\"))\n\t\t\t\tcontinue;\n\t\t\tint c = info.indexOf(':');\n\t\t\tString key =info.substring(0, c);\n\t\t\tString value = info.substring(c+1);\n\t\t\tinfomap.put(key, value);\n\t\t}\n\t\treturn infomap;\n\t}\n\n\tprivate void mset(byte[][] mappings) throws RedisException {\n\t\tthis.serviceRequest(Command.MSET, mappings);\n\t}\n\tpublic <K extends Object> void mset(Map<K, byte[]> keyValueMap) throws RedisException {\n//\t\tKeyCodec<Object> codec = DefaultKeyCodec.provider();\n\t\tbyte[][] mappings = new byte[keyValueMap.size()*2][];\n\t\tint i = 0;\n\t\tfor (Entry<K, byte[]> e : keyValueMap.entrySet()){\n\t\t\tmappings[i++] = getKeyBytes(e.getKey());\n\t\t\tmappings[i++] = e.getValue();\n\t\t}\n\t\tmset(mappings);\n\t}\n\tpublic <K extends Object> void mset(KeyValueSet.ByteArrays<K> keyValueMap) throws RedisException {\n\t\tmset(keyValueMap.getMappings());\n\t}\n\tpublic <K extends Object> void mset(KeyValueSet.Strings<K> keyValueMap) throws RedisException{\n\t\tmset(keyValueMap.getMappings());\n\t}\n\tpublic <K extends Object> void mset(KeyValueSet.Numbers<K> keyValueMap) throws RedisException{\n\t\tmset(keyValueMap.getMappings());\n\t}\n\tpublic <K extends Object, T extends Serializable> void mset(KeyValueSet.Objects<K, T> keyValueMap) throws RedisException{\n\t\tmset(keyValueMap.getMappings());\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> mget(K...keys) throws RedisException {\n\n\t\tif(null == keys || keys.length == 0) throw new IllegalArgumentException(\"no keys specified\");\n\t\tbyte[] keydata = null;\n\t\tbyte[][] keybytes = new byte[keys.length][];\n\t\tint i=0;\n\t\tfor(K k : keys) {\n\t\t\tif((keydata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"] @ index: \" + i);\n\t\t\t\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\t\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.MGET, keybytes);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> smembers(K key) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(key)) == null) \n\t\t\tthrow new RedisException (Command.KEYS, \"ERR Invalid key.\");\n\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.SMEMBERS, keydata);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\t@Override\n\tpublic <K extends Object> List<byte[]> keys() throws RedisException {\n\t\treturn this.keys(\"*\");\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> keys(K pattern) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(pattern)) == null) \n\t\t\tthrow new RedisException (Command.KEYS, \"ERR Invalid key.\");\n\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.KEYS, keydata);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n//\t\treturn DefaultCodec.toStr(multiBulkData);\n\t\treturn multiBulkData;\n\t\t/*\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.KEYS, keydata);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\n\t\tStringTokenizer tokenizer = new StringTokenizer(new String(bulkData), \" \");\n\t\tList<String>  keyList = new ArrayList <String>(12);\n\t\twhile (tokenizer.hasMoreTokens()){\n\t\t\tkeyList.add(tokenizer.nextToken());\n\t\t}\n\t\treturn keyList;\n\t\t*/\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> lrange(K key, long from, long to) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse multiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.LRANGE, keybytes, fromBytes, toBytes);\n\t\t\tmultiBulkData = multiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> byte[] substr(K key, long from, long to) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse bulkResponse = (BulkResponse) this.serviceRequest(Command.SUBSTR, keybytes, fromBytes, toBytes);\n\t\t\tbulkData = bulkResponse.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> zrangebyscore (K key, double minScore, double maxScore) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(minScore);\n\t\tbyte[] toBytes = Convert.toBytes(maxScore);\n\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.ZRANGEBYSCORE, keybytes, fromBytes, toBytes);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<ZSetEntry> zrangebyscoreSubset (K key, double minScore, double maxScore) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null)\n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(minScore);\n\t\tbyte[] toBytes = Convert.toBytes(maxScore);\n\n\t\tList<ZSetEntry> list= null;\n\t\ttry {\n\t\t\tMultiBulkResponse multiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.ZRANGEBYSCORE$OPTS, keybytes, fromBytes, toBytes, Command.Option.WITHSCORES.bytes);\n\t\t\tList<byte[]> bulkData = multiBulkResponse.getMultiBulkData();\n\t\t\tif(null != bulkData){\n\t\t\t\tlist = new ArrayList<ZSetEntry>(bulkData.size()/2);\n\t\t\t\tfor(int i=0; i<bulkData.size(); i+=2){\n\t\t\t\t\tlist.add(new ZSetEntryImpl(bulkData.get(i), bulkData.get(i+1)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn list;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long zremrangebyscore (K key, double minScore, double maxScore) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(minScore);\n\t\tbyte[] toBytes = Convert.toBytes(maxScore);\n\n\t\tlong resp = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valueResponse = (ValueResponse) this.serviceRequest(Command.ZREMRANGEBYSCORE, keybytes, fromBytes, toBytes);\n\t\t\tresp = valueResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a numeric ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long zcount (K key, double minScore, double maxScore) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(minScore);\n\t\tbyte[] toBytes = Convert.toBytes(maxScore);\n\n\t\tlong resp = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valueResponse = (ValueResponse) this.serviceRequest(Command.ZCOUNT, keybytes, fromBytes, toBytes);\n\t\t\tresp = valueResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a numeric ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\n\t@Override\n\tpublic <K extends Object> long zremrangebyrank (K key, long minRank, long maxRank) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(minRank);\n\t\tbyte[] toBytes = Convert.toBytes(maxRank);\n\n\t\tlong resp = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valueResponse = (ValueResponse) this.serviceRequest(Command.ZREMRANGEBYRANK, keybytes, fromBytes, toBytes);\n\t\t\tresp = valueResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a numeric ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resp;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> zrange(K key, long from, long to) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.ZRANGE, keybytes, fromBytes, toBytes);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> zrevrange(K key, long from, long to) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.ZREVRANGE, keybytes, fromBytes, toBytes);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\t@Override\n\tpublic <K extends Object> List<ZSetEntry> zrangeSubset(K key, long from, long to) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\tList<ZSetEntry> list= null;\n\t\ttry {\n\t\t\tMultiBulkResponse multiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.ZRANGE$OPTS, keybytes, fromBytes, toBytes, Command.Option.WITHSCORES.bytes);\n\t\t\tList<byte[]> bulkData = multiBulkResponse.getMultiBulkData();\n\t\t\tif(null != bulkData){\n\t\t\t\tlist = new ArrayList<ZSetEntry>(bulkData.size()/2);\n\t\t\t\tfor(int i=0; i<bulkData.size(); i+=2){\n\t\t\t\t\tlist.add(new ZSetEntryImpl(bulkData.get(i), bulkData.get(i+1)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn list;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<ZSetEntry> zrevrangeSubset(K key, long from, long to) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(from);\n\t\tbyte[] toBytes = Convert.toBytes(to);\n\n\t\tList<ZSetEntry> list= null;\n\t\ttry {\n\t\t\tMultiBulkResponse multiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.ZREVRANGE$OPTS, keybytes, fromBytes, toBytes, Command.Option.WITHSCORES.bytes);\n\t\t\tList<byte[]> bulkData = multiBulkResponse.getMultiBulkData();\n\t\t\tif(null != bulkData){\n\t\t\t\tlist = new ArrayList<ZSetEntry>(bulkData.size()/2);\n\t\t\t\tfor(int i=0; i<bulkData.size(); i+=2){\n\t\t\t\t\tlist.add(new ZSetEntryImpl(bulkData.get(i), bulkData.get(i+1)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn list;\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> Sort sort(final K key) {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tfinal JRedisSupport client = this;\n//\t\tSort sortQuery = new SortSupport (key, keybytes) {\n\t\tSort sortQuery = new SortSupport (keybytes) {\n\t\t\t@Override \n\t\t\tprotected List<byte[]> execSort(byte[]... fullSortCmd) \n\t\t\tthrows IllegalStateException, RedisException {\n\t\t\t\t\n\t\t\t\tList<byte[]> multiBulkData= null;\n\t\t\t\ttry {\n\t\t\t\t\tMultiBulkResponse multiBulkResponse = (MultiBulkResponse) client.serviceRequest(Command.SORT, fullSortCmd);\n\t\t\t\t\tmultiBulkData = multiBulkResponse.getMultiBulkData();\n\t\t\t\t}\n\t\t\t\tcatch (ClassCastException e){\n\t\t\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t\t\t}\n\t\t\t\treturn multiBulkData;\n\t\t\t}\n\n\t\t\tprotected List<byte[]> execSortStore(byte[]... fullSortCmd) \n\t\t\tthrows IllegalStateException, RedisException {\n\t\t\t\t\n\t\t\t\tList<byte[]> multiBulkData= new ArrayList<byte[]>(1);\n\t\t\t\ttry {\n\t\t\t\t\tValueResponse valueResp = (ValueResponse) client.serviceRequest(Command.SORT$STORE, fullSortCmd);\n\t\t\t\t\tlong resSize = valueResp.getLongValue();\n\t\t\t\t\tmultiBulkData.add(Convert.toBytes(resSize));\n\t\t\t\t}\n\t\t\t\tcatch (ClassCastException e){\n\t\t\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t\t\t}\n\t\t\t\treturn multiBulkData;\n\t\t\t}\n\n\t\t\t@Override\n\t        protected Future<List<byte[]>> execAsyncSort (byte[]... fullSortCmd) {\n\t\t\t\tthrow new IllegalStateException(\"JRedis does not support asynchronous sort.\");\n\t        }\n\t\t\t@Override\n\t        protected Future<List<byte[]>> execAsyncSortStore (byte[]... fullSortCmd) {\n\t\t\t\tthrow new IllegalStateException(\"JRedis does not support asynchronous sort.\");\n\t        }\n\t\t};\n\t\treturn sortQuery;\n\t}\n\n\t/* ------------------------------- commands that don't get a response --------- */\n\n\t@Override\n\tpublic <K extends Object> void quit()  {\n\t\ttry {\n\t\t\tthis.serviceRequest(Command.QUIT);\n\t\t}\n\t\tcatch (RedisException e) { /* NotConnectedException is OK */\n\t\t\te.printStackTrace();\n\t\t\tthrow new ProviderException (\"Quit raised an unexpected RedisException -- Bug\");\n\t\t}\n//\t\treturn true;\n\t}\n//\t@Override\n//\tpublic <K extends Object> void shutdown() {\n//\t\ttry {\n//\t\t\tthis.serviceRequest(Command.SHUTDOWN);\n//\t\t}\n//\t\tcatch (RedisException e) { /* NotConnectedException is OK */\n//\t\t\te.printStackTrace();\n//\t\t\tthrow new ProviderException (\"Shutdown raised an unexpected RedisException -- Bug\");\n//\t\t}\n////\t\treturn true;\n//\t}\n\t@Override\n\tpublic <K extends Object> List<byte[]> sinter(K set1, K... sets) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(set1)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+set1+\"]\");\n\n\t\tbyte[][] keybytes = new byte[1+sets.length][];\n\t\tint i=0; keybytes[i++] = keydata;\n\t\tfor(K k : sets) {\n\t\t\tif((keydata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\t\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.SINTER, keybytes);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> sunion(K set1, K... sets) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(set1)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+set1+\"]\");\n\n\t\tbyte[][] keybytes = new byte[1+sets.length][];\n\t\tint i=0; keybytes[i++] = keydata;\n\t\tfor(K k : sets) {\n\t\t\tif((keydata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\t\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.SUNION, keybytes);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> List<byte[]> sdiff(K set1, K... sets) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(set1)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+set1+\"]\");\n\n\t\tbyte[][] keybytes = new byte[1+sets.length][];\n\t\tint i=0; keybytes[i++] = keydata;\n\t\tfor(K k : sets) {\n\t\t\tif((keydata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\t\t\n\t\tList<byte[]> multiBulkData= null;\n\t\ttry {\n\t\t\tMultiBulkResponse MultiBulkResponse = (MultiBulkResponse) this.serviceRequest(Command.SDIFF, keybytes);\n\t\t\tmultiBulkData = MultiBulkResponse.getMultiBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a MultiBulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn multiBulkData;\n\t}\n\n\t@Override\n\tpublic <K extends Object> void sinterstore(K dest, K... sets) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(dest)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+dest+\"]\");\n\n\t\tbyte[][] setbytes = new byte[1+sets.length][];\n\t\tint i=0; \n\t\tsetbytes[i++] = keydata;\n\t\tbyte[] setdata =null;\n\t\tfor(K k : sets) {\n\t\t\tif((setdata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tsetbytes[i++] = setdata;\n\t\t}\n\t\t\n\t\tthis.serviceRequest(Command.SINTERSTORE, setbytes);\n\t}\n\n\t@Override\n\tpublic <K extends Object> void sunionstore(K dest, K... sets) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(dest)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+dest+\"]\");\n\n\t\tbyte[][] setbytes = new byte[1+sets.length][];\n\t\tint i=0; \n\t\tsetbytes[i++] = keydata;\n\t\tbyte[] setdata =null;\n\t\tfor(K k : sets) {\n\t\t\tif((setdata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tsetbytes[i++] = setdata;\n\t\t}\n\t\t\n\t\tthis.serviceRequest(Command.SUNIONSTORE, setbytes);\n\t}\n\n\t@Override\n\tpublic <K extends Object> void sdiffstore(K dest, K... sets) throws RedisException {\n\t\tbyte[] keydata = null;\n\t\tif((keydata = getKeyBytes(dest)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+dest+\"]\");\n\n\t\tbyte[][] setbytes = new byte[1+sets.length][];\n\t\tint i=0; \n\t\tsetbytes[i++] = keydata;\n\t\tbyte[] setdata =null;\n\t\tfor(K k : sets) {\n\t\t\tif((setdata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"]\");\n\t\t\tsetbytes[i++] = setdata;\n\t\t}\n\t\t\n\t\tthis.serviceRequest(Command.SDIFFSTORE, setbytes);\n\t}\n\n\t@Override\n\tpublic <K extends Object> long del(K ...keys ) throws RedisException {\n\t\t\n\t\tif(null == keys || keys.length == 0) throw new IllegalArgumentException(\"no keys specified\");\n\t\tbyte[] keydata = null;\n\t\tbyte[][] keybytes = new byte[keys.length][];\n\t\tint i=0;\n\t\tfor(K k : keys) {\n\t\t\tif((keydata = getKeyBytes(k)) == null) \n\t\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+k+\"] @ index: \" + i);\n\t\t\t\n\t\t\tkeybytes[i++] = keydata;\n\t\t}\n\n\t\tlong resvalue = -1;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.DEL, keybytes);\n\t\t\tresvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> boolean exists(K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.EXISTS, keybytes);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> void lpush(K key, byte[] value) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t\n\t\tif(value == null) \n\t\t\tthrow new IllegalArgumentException (\"null value for list op\");\n\t\t\n\t\t\n\t\tthis.serviceRequest(Command.LPUSH, keybytes, value);\n\t}\n\t@Override\n\tpublic <K extends Object> void lpush(K key, String value) throws RedisException {\n\t\tlpush(key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> void lpush(K key, Number value) throws RedisException {\n\t\tlpush(key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> void lpush (K key, T value) throws RedisException\n\t{\n\t\tlpush(key, DefaultCodec.encode(value));\n\t}\n\t\n\n\n\t@Override\n\tpublic <K extends Object> long lrem(K key, byte[] value, int count) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] countBytes = Convert.toBytes(count);\n\n\t\tlong remcnt = 0;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.LREM, keybytes, countBytes, value);\n\t\t\tremcnt = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn remcnt;\n\t}\n\t@Override\n\tpublic <K extends Object> long lrem (K listKey, String value, int count) throws RedisException{\n\t\treturn lrem (listKey, DefaultCodec.encode(value), count);\n\t}\n\t@Override\n\tpublic <K extends Object> long lrem (K listKey, Number numberValue, int count) throws RedisException {\n\t\treturn lrem (listKey, String.valueOf(numberValue).getBytes(), count);\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> \n\tlong lrem (K listKey, T object, int count) throws RedisException{\n\t\treturn lrem (listKey, DefaultCodec.encode(object), count);\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> void lset(K key, long index, byte[] value) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] indexBytes = Convert.toBytes(index);\n\t\tthis.serviceRequest(Command.LSET, keybytes, indexBytes, value);\n\t}\n\t@Override\n\tpublic <K extends Object> void lset (K key, long index, String value) throws RedisException {\n\t\tlset (key, index, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> void lset (K key, long index, Number numberValue) throws RedisException{\n\t\tlset (key, index, String.valueOf(numberValue).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> void lset (K key, long index, T object) throws RedisException{\n\t\tlset (key, index, DefaultCodec.encode(object));\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean move(K key, int dbIndex) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\t\t\n\t\tbyte[] toBytes = Convert.toBytes(dbIndex);\n\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.MOVE, keybytes, toBytes);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> boolean srem(K key, byte[] member) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.SREM, keybytes, member);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> boolean srem (K key, String value) throws RedisException {\n\t\treturn srem (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> boolean srem (K key, Number value) throws RedisException {\n\t\treturn srem (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> boolean srem (K key, T value) throws RedisException\n\t{\n\t\treturn srem (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean zrem(K key, byte[] member) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.ZREM, keybytes, member);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> boolean zrem (K key, String value) throws RedisException {\n\t\treturn zrem (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> boolean zrem (K key, Number value) throws RedisException {\n\t\treturn zrem (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> boolean zrem (K key, T value) throws RedisException\n\t{\n\t\treturn zrem (key, DefaultCodec.encode(value));\n\t}\n\n\t@SuppressWarnings(\"boxing\")\n\t@Override\n\tpublic <K extends Object> Double zscore(K key, byte[] member) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tDouble resvalue = null;\n\t\ttry {\n\t\t\tBulkResponse bulkResponse = (BulkResponse) this.serviceRequest(Command.ZSCORE, keybytes, member);\n\t\t\tif (bulkResponse.getBulkData() != null)\n\t\t\t\tresvalue = Convert.toDouble(bulkResponse.getBulkData());\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> Double zscore (K key, String value) throws RedisException {\n\t\treturn zscore (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> Double zscore (K key, Number value) throws RedisException {\n\t\treturn zscore (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> Double zscore (K key, T value) throws RedisException\n\t{\n\t\treturn zscore (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> long zrank(K key, byte[] member) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tlong resvalue = -1;\n\t\ttry {\n\t\t\tValueResponse bulkResponse = (ValueResponse) this.serviceRequest(Command.ZRANK, keybytes, member);\n\t\t\tresvalue = bulkResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> long zrank (K key, String value) throws RedisException {\n\t\treturn zrank (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> long zrank (K key, Number value) throws RedisException {\n\t\treturn zrank (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> long zrank (K key, T value) throws RedisException\n\t{\n\t\treturn zrank (key, DefaultCodec.encode(value));\n\t}\n\n\t@Override\n\tpublic <K extends Object> long zrevrank(K key, byte[] member) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tlong resvalue = -1;\n\t\ttry {\n\t\t\tValueResponse bulkResponse = (ValueResponse) this.serviceRequest(Command.ZREVRANK, keybytes, member);\n\t\t\tresvalue = bulkResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t@Override\n\tpublic <K extends Object> long zrevrank (K key, String value) throws RedisException {\n\t\treturn zrevrank (key, DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> long zrevrank (K key, Number value) throws RedisException {\n\t\treturn zrevrank (key, String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> long zrevrank (K key, T value) throws RedisException\n\t{\n\t\treturn zrevrank (key, DefaultCodec.encode(value));\n\t}\n\n\n\t@Override\n\tpublic <K extends Object> void ltrim(K key, long keepFrom, long keepTo) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] fromBytes = Convert.toBytes(keepFrom);\n\t\tbyte[] toBytes = Convert.toBytes(keepTo);\n\t\tthis.serviceRequest(Command.LTRIM, keybytes, fromBytes, toBytes);\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean expire(K key, int ttlseconds) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tbyte[] ttlbytes = Convert.toBytes(ttlseconds);\n\t\t\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.EXPIRE, keybytes, ttlbytes);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\n\t@Override\n\tpublic <K extends Object> boolean expireat(K key, long epochtime) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\tlong expiretime = TimeUnit.SECONDS.convert(epochtime, TimeUnit.MILLISECONDS);\n\t\tbyte[] expiretimeBytes = Convert.toBytes(expiretime);\n\t\t\n\t\tboolean resvalue = false;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.EXPIREAT, keybytes, expiretimeBytes);\n\t\t\tresvalue = valResponse.getBooleanValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn resvalue;\n\t}\n\t\n\t@Override\n\tpublic <K extends Object> long ttl (K key) throws RedisException {\n\t\tbyte[] keybytes = null;\n\t\tif((keybytes = getKeyBytes(key)) == null) \n\t\t\tthrow new IllegalArgumentException (\"invalid key => [\"+key+\"]\");\n\n\t\t\n\t\tlong value = Long.MIN_VALUE;\n\t\ttry {\n\t\t\tValueResponse valResponse = (ValueResponse) this.serviceRequest(Command.TTL, keybytes);\n\t\t\tvalue = valResponse.getLongValue();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a ValueResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn value;\n\t}\n\t@Override\n\tpublic <K extends Object> byte[] echo (byte[] value) throws RedisException {\n\t\tif(value ==null) \n\t\t\tthrow new IllegalArgumentException (\"invalid echo value => [null]\");\n\n\t\tbyte[] bulkData= null;\n\t\ttry {\n\t\t\tBulkResponse response = (BulkResponse) this.serviceRequest(Command.ECHO, value);\n\t\t\tbulkData = response.getBulkData();\n\t\t}\n\t\tcatch (ClassCastException e){\n\t\t\tthrow new ProviderException(\"Expecting a BulkResponse here => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn bulkData;\n\t}\n\t@Override\n\tpublic <K extends Object> byte[] echo(String value) throws RedisException {\n\t\treturn echo(DefaultCodec.encode(value));\n\t}\n\t@Override\n\tpublic <K extends Object> byte[] echo(Number value) throws RedisException {\n\t\treturn echo(String.valueOf(value).getBytes());\n\t}\n\t@Override\n\tpublic <K extends Object, T extends Serializable> \n\tbyte[] echo (T value) throws RedisException\n\t{\n\t\treturn echo(DefaultCodec.encode(value));\n\t}\n\t// ------------------------------------------------------------------------\n\t// Transactional commands\n\t// ------------------------------------------------------------------------\n\t/**\n\t * one option is to return a subclass of JRedis (e.g. JRedisCommandSequence)\n\t * and have that interface declare discard and multi.  Benefit is being able\n\t * to associate state with the transaction.\n\t * @throws RedisException\n\t */\n\t@Version(major=2, minor=0, release=Release.ALPHA)\n\tpublic <K extends Object> JRedis multi() throws RedisException {\n\t\tthrow new ProviderException(\"NOT IMPLEMENTED\");\n//\t\t// works\n//\t\tthis.serviceRequest(Command.MULTI);\n//\t\treturn this;\n\t}\n\t/**\n\t * @throws RedisException\n\t */\n\t@Version(major=2, minor=0, release=Release.ALPHA)\n\tpublic <K extends Object> JRedis discard () throws RedisException {\n\t\tthrow new ProviderException(\"NOT IMPLEMENTED\");\n//\t\t// works\n//\t\tthis.serviceRequest(Command.DISCARD);\n//\t\treturn this;\n\t}\n\t// ------------------------------------------------------------------------\n\t// utility\n\t// ------------------------------------------------------------------------\n\t\n\t// TODO: integrate using KeyCodec and a CodecManager at client spec and init time.\n\t// TODO: (implied) ClientSpec (impls. ConnectionSpec)\n\t// this isn't cooked yet -- lets think more about the implications...\n\t// \n//\tstatic final private Map<String, byte[]>\tkeyByteCache = new ConcurrentHashMap<String, byte[]>();\n\tpublic static boolean\tCacheKeys\t= false;\n\t\n\tpublic static <K extends Object> byte[] getKeyBytes(K key) throws IllegalArgumentException {\n\t\treturn DefaultKeyCodec.provider().encode(key);\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/Pair.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\n/**\n * Generic immutable 2-tuple data struct.\n *  \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Mar 20, 2010\n * @since   alpha.0\n * \n */\n\nclass Pair<T1, T2> {\n\tpublic final T1 t1;\n\tpublic final T2 t2;\n\tpublic Pair(T1 t1, T2 t2){\n\t\tthis.t1 = t1;\n\t\tthis.t2 = t2;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/RedisVersion.java",
    "content": "///*\n// *   Copyright 2009 Joubin Houshyar\n// * \n// *   Licensed under the Apache License, Version 2.0 (the \"License\");\n// *   you may not use this file except in compliance with the License.\n// *   You may obtain a copy of the License at\n// *    \n// *   http://www.apache.org/licenses/LICENSE-2.0\n// *    \n// *   Unless required by applicable law or agreed to in writing, software\n// *   distributed under the License is distributed on an \"AS IS\" BASIS,\n// *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *   See the License for the specific language governing permissions and\n// *   limitations under the License.\n// */\n//\n//package org.jredis.ri.alphazero;\n//\n///**\n// * TODO: think about depcrecating this -- there really would be only one version\n// * of Redis.\n// * <p>\n// * [TODO: document me!]\n// *\n// * @author  Joubin Houshyar (alphazero@sensesay.net)\n// * @version alpha.0, Apr 12, 2009\n// * @since   alpha.0\n// * \n// */\n////public enum RedisVersion {\n////\tcurrent_revision (\"0.09\"),\n////\tbeta_0_09 (\"0.09\");\n////\tpublic String id;\n////\tpublic String getId() { return id; }\n////\tprivate RedisVersion(String id) {\n////\t\tthis.id = id;\n////\t}\n////\n////}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/SyncJRedisBase.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.FaultedConnection;\nimport org.jredis.connector.Connection.Property;\nimport org.jredis.resource.Context;\nimport org.jredis.resource.Resource;\nimport org.jredis.resource.ResourceException;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 15, 2009\n * @since   alpha.0\n * \n */\n\npublic abstract class SyncJRedisBase extends JRedisSupport implements Resource<JRedis> {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t// ------------------------------------------------------------------------\n\t// Constructors\n\t// ------------------------------------------------------------------------\n\t// ------------------------------------------------------------------------\n\t// Inner ops\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * This extension point is really only necessary to allow this class to\n\t * set the {@link FaultedConnection} when necessary, in course of the\n\t * {@link SyncJRedisBase#createSyncConnection(String)}\n\t * method operation.  \n\t * \n\t * @param connection\n\t */\n\tprotected abstract void setConnection (Connection connection) ;\n\n\t/**\n\t * Creates a {@link Connection} with {@link Connection.Modality#Synchronous} semantics\n\t * suitable for use by synchronous (blocking) JRedis clients.\n\t *  \n\t * @param connSpec connection's specification\n\t * @param redisVersion redis protocol compliance\n\t * @return\n\t */\n\tprotected Connection createSyncConnection(ConnectionSpec connSpec){\n\t\tConnection.Factory cfact = (Connection.Factory) connSpec.getConnectionProperty(Property.CONNECTION_FACTORY);\n\t\tConnection \tconn = null;\n\t\ttry {\n\t\t\tconn = Assert.notNull(cfact.newConnection(connSpec), \"connection delegate\", ClientRuntimeException.class);\n\t\t}\n\t\tcatch (ProviderException e) {\n\t\t\tLog.bug(\"Couldn't create the handler delegate.  => \" + e.getLocalizedMessage());\n\t\t\tthrow e;\n\t\t}\n\t\tcatch (ClientRuntimeException e) {\n\t\t\tString msg = String.format(\"%s\\nMake sure your server is running.\", e.getMessage());\n\t\t\tLog.error (\"Error creating connection -> \" + e.getLocalizedMessage());\n\t\t\tsetConnection(new FaultedConnection(connSpec, msg));\n\t\t}\n\t\tLog.debug (\"%s: Using %s\", this.getClass().getSimpleName(), conn);\n\t\treturn conn;\n\t}\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// =========================================================== Resource<T>\n\t/*\n\t * Provides basic Resource support without any state management.  Extensions\n\t * that use context in a simply manner can rely on these methods.  Others may\n\t * wish to override.\n\t */\n\t// ------------------------------------------------------------------------\n\t\n\tprivate Context context;\n\n\t@Override\n\tpublic final Context getContext() throws ResourceException {\n\t\treturn context;\n\t}\n\n\t@Override\n\tpublic final void setContext(Context context) throws ResourceException {\n\t\tthis.context = context;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/ZSetEntryImpl.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport org.jredis.ZSetEntry;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Mar 20, 2010\n * @since   alpha.0\n * \n */\n\nclass ZSetEntryImpl extends Pair<byte[], byte[]> implements ZSetEntry {\n\n    public ZSetEntryImpl (byte[] valueBytes, byte[] scoreBytes) {\n    \tsuper(valueBytes, scoreBytes);\n    }\n\t/* (non-Javadoc) @see org.jredis.ZSetEntry#getScore() */\n\tpublic double getScore () { return DefaultCodec.toDouble(t2); }\n\n\t/* (non-Javadoc) @see org.jredis.ZSetEntry#getValue() */\n\tpublic byte[] getValue () { return t1;}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/_specification.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 15, 2009\n * @since   alpha.0\n * \n */\n\npublic interface _specification {\n\n\t/** specification level */\n\tpublic interface Version {\n\t\tlong\tmajor\t= 0xA;\n\t    long \tminor\t= 0x0;\n\t}\n\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/AsyncConnection.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport java.io.InputStream;\nimport java.util.Queue;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.LinkedBlockingQueue;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.NotConnectedException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Request;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.protocol.ConcurrentSyncProtocol;\nimport org.jredis.ri.alphazero.protocol.VirtualResponse;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.FastBufferedInputStream;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 6, 2009\n * @since   alpha.0\n * \n */\n\npublic class AsyncConnection extends ConnectionBase implements Connection {\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t\n\tprivate RequestProcessor\t   processor;\n\t\n\t/**  */\n\tprivate Thread \t\t\t\t\tprocesserThread;\n\n\t/**  */\n\tprivate BlockingQueue<PendingRequest>\tpendingQueue;\n\tBlockingQueue<PendingRequest> getPendingQueue() { return pendingQueue; }\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructors\n\t// ------------------------------------------------------------------------\n\tpublic AsyncConnection (\n\t\t\tConnectionSpec connectionSpec\n\t\t)\n\t\tthrows ClientRuntimeException, ProviderException \n\t{\n\t\tsuper (connectionSpec.setModality(Modality.Asynchronous));\n//\t\tsuper (connectionSpec); // should be - really need an assert\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Extension\n\t// ------------------------------------------------------------------------\n\t/**\n     * \n     */\n    protected void initializeComponents () {\n    \tsuper.initializeComponents();\n    \t\n//    \tserviceLock = new Object();\n    \t\n    \tpendingQueue = new LinkedBlockingQueue<PendingRequest>();\n    \tprocessor = new RequestProcessor();\n    \tprocesserThread = new Thread(processor, \"request-processor\");\n    \tprocesserThread.start();\n    }\n    /**\n     * Pipeline must use a concurrent protocol handler.\n     *  \n     * @see org.jredis.ri.alphazero.connection.ConnectionBase#newProtocolHandler()\n     */\n    @Override\n    protected Protocol newProtocolHandler () {\n\t\treturn new ConcurrentSyncProtocol();\n    }\n    \n    /**\n     * Just make sure its a {@link FastBufferedInputStream}.\n     */\n    @SuppressWarnings(\"boxing\")\n\t@Override\n\tprotected final InputStream newInputStream (InputStream socketInputStream) throws IllegalArgumentException {\n    \t\n    \tInputStream in = super.newInputStream(socketInputStream);\n    \tif(!(in instanceof FastBufferedInputStream)){\n    \t\tLog.log(String.format(\"WARN: input was: %s\\n\", in.getClass().getCanonicalName()));\n    \t\tin = new FastBufferedInputStream (in, spec.getSocketProperty(Connection.Socket.Property.SO_RCVBUF));\n    \t}\n    \treturn in;\n    }\n    \n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ======================================================= ProtocolHandler\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc)\n\t * @see org.jredis.connector.Connection#getModality()\n\t */\n\tpublic final Modality getModality() {\n\t\treturn Connection.Modality.Asynchronous;\n\t}\n\t\n\t/* (non-Javadoc)\n     * @see org.jredis.ri.alphazero.connection.ConnectionBase#queueRequest(org.jredis.protocol.Command, byte[][])\n     */\n    @Override\n    public Future<Response> queueRequest (Command cmd, byte[]... args)\n    \tthrows ClientRuntimeException, ProviderException \n    {\n\t\tif(!isConnected()) \n\t\t\tthrow new NotConnectedException (\"Not connected!\");\n\t\t\n\t\tPendingRequest pending = new PendingRequest(cmd, args);\n\t\tpendingQueue.add(pending);\n\t\treturn pending;\n    }\n    \n\t// ------------------------------------------------------------------------\n\t// Inner Class\n\t// ------------------------------------------------------------------------\n    public final class RequestProcessor implements Runnable {\n\n    \t/**\n    \t * Keeps processing the {@link PendingRequest}s in the pending {@link Queue}\n\t\t * until a QUIT is encountered in the pending queue.  Thread will stop after\n\t\t * processing the QUIT response (which is expected to be a {@link VirtualResponse}.\n    \t * <p>\n    \t * TODO: not entirely clear what is the best way to handle exceptions.\n    \t * <p>\n    \t * TODO: socket Reconnect in the context of pipelining is non-trivial, and maybe\n    \t * not even practically possible.  (e.g. request n is sent but pipe breaks on\n    \t * some m (m!=n) response.  non trivial.\n    \t */\n\n        public void run () {\n\t\t\tLog.log(\"AsyncConnection processor thread <%s> started.\", Thread.currentThread().getName());\n        \t/** Response handler thread specific protocol handler -- optimize fencing */\n        \tProtocol protocol = Assert.notNull (newProtocolHandler(), \"the delegate protocol handler\", ClientRuntimeException.class);\n        \tPendingRequest pending = null;\n        \tfinal BlockingQueue<PendingRequest>\t_pendingQueue = getPendingQueue();\n        \twhile(true){\n\t\t\t\ttry {\n\t                pending = _pendingQueue.take();\n\t\t\t\t\ttry {\n\t\t\t\t\t\tRequest request = Assert.notNull(protocol.createRequest (pending.cmd, pending.args), \"request object from handler\", ProviderException.class);\n\t\t\t\t\t\trequest.write(getOutputStream());\n\t\t\t\t\t\t\n\t\t\t\t\t\tpending.response = protocol.createResponse(pending.cmd);\n\t\t\t\t\t\tpending.response.read(getInputStream());\n\t\t\t\t\t\t\n\t\t\t\t\t\tpending.completion.signal();\n\t\t\t\t\t\tif(pending.response.getStatus().isError()) {\n\t\t\t\t\t\t\tLog.error (\"(Asynch) Error response for \" + pending.cmd.code + \" => \" + pending.response.getStatus().message());\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tcatch (ProviderException bug){\n\t\t\t\t\t\tLog.error (\"ProviderException: \" + bug.getLocalizedMessage());\n\t\t\t\t\t\tbug.printStackTrace();\n\t\t\t\t\t\tpending.setCRE(bug);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (ClientRuntimeException cre) {\n\t\t\t\t\t\tLog.error (\"ClientRuntimeException: \" + cre.getLocalizedMessage());\n\t\t\t\t\t\tcre.printStackTrace();\n\t\t\t\t\t\tpending.setCRE(cre);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RuntimeException e){\n\t\t\t\t\t\tLog.error(\"Unexpected RuntimeException \", e);\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t\tpending.setCRE(new ProviderException(\"Unexpected runtime exception in response handler\"));\n\t\t\t\t\t\tpending.setResponse(null);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// redis (1.00) simply shutsdown connection even if pending responses\n\t\t\t\t\t// are expected, so quit is NOT sent.  we simply close connection on this\n\t\t\t\t\t// end. \n\t\t\t\t\tif(pending.cmd == Command.QUIT) {\n\t\t\t\t\t\tAsyncConnection.this.disconnect();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n                }\n                catch (InterruptedException e1) {\n\t                e1.printStackTrace();\n                }\n        \t}\n\t\t\tLog.log(\"AsyncConnection processor thread <%s> stopped.\", Thread.currentThread().getName());\n        }\n    }\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/AsyncPipelineConnection.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.connector.ConnectionSpec;\n\n/**\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Sep 7, 2009\n * @since   alpha.0\n * \n */\n\npublic class AsyncPipelineConnection extends PipelineConnectionBase{\n\n    // ------------------------------------------------------------------------\n    // Properties\n    // ------------------------------------------------------------------------\n    // ------------------------------------------------------------------------\n    // Constructor(s)\n    // ------------------------------------------------------------------------\n\t/**\n     * @param spec\n     * @throws ClientRuntimeException\n     */\n    public AsyncPipelineConnection (ConnectionSpec spec) throws ClientRuntimeException {\n\t    super(spec.setModality(Modality.Asynchronous));\n    }\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/ChunkedPipelineConnection.java",
    "content": "/*\n *   Copyright 2009-2012 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport static org.jredis.ri.alphazero.protocol.ProtocolBase.ASCII_ZERO;\nimport static org.jredis.ri.alphazero.protocol.ProtocolBase.COUNT_BYTE;\nimport static org.jredis.ri.alphazero.protocol.ProtocolBase.CRLF;\nimport static org.jredis.ri.alphazero.protocol.ProtocolBase.CRLF_LEN;\nimport static org.jredis.ri.alphazero.protocol.ProtocolBase.SIZE_BYTE;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.Queue;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\nimport java.util.concurrent.atomic.AtomicReferenceFieldUpdater;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.LockSupport;\nimport java.util.concurrent.locks.ReentrantLock;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.NotConnectedException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.Command.ResponseType;\nimport org.jredis.ri.alphazero.protocol.ConcurrentSyncProtocol;\nimport org.jredis.ri.alphazero.protocol.ProtocolBase;\nimport org.jredis.ri.alphazero.protocol.VirtualResponse;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Convert;\nimport org.jredis.ri.alphazero.support.FastBufferedInputStream;\nimport org.jredis.ri.alphazero.support.Log;\n//import org.jredis.ri.alphazero.support.Concurrent2LockQueue.Node;\n\n/**\n * WIP NOTES: \n * <p>\n * intended to replace existing pipeline per further tests.  This\n * pipeline: \n * \n * <li>- provides maximal throughput for asynchronous feedsto Redis server.</li>\n * <li>- it is thread-safe.</li>\n *  \n * <p>\n * Design:\n * <p>\n * We're basically delegating output throttling concerns to the OS\n * and the TCP/IP layer using blocking write semantics. The TCP layer\n * will write MTU sized packets, regardless of actual user data, so\n * clearly the more we pack per packet, the higher will be the throughput \n * of the connector.\n * \n * @author Joubin <alphazero@sensesay.net>\n *\n */\npublic class ChunkedPipelineConnection \n\textends ConnectionBase // TODO: doesn't need the ThreadLocals -- re-think super via ConnectionSpec settings.\n{\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/**  */\n\tprivate ResponseHandler\t    \trespHandler;\n\n\t/**  */\n\tprivate Thread \t\t\t\t\trespHandlerThread;\n\n\t/**  */\n\tBlockingQueue<PendingCPRequest[]>\tpendingResponseQueue;\n\t\n\n\t/** synchronization object used to serialize request queuing  */\n\tprivate Lock requestlock;\n\n\t/** \n\t * flag (default false) indicates if a pending QUIT command is being processed.  \n\t * If true, any calls to queueRequests will result in a raise runtime exception\n\t */\n\tprivate boolean\t\t\t\t\tpendingQuit = false;\n\n\t/** used by the Pipeline to indicate its state.  Set to true on connect and false on Quit/Close */\n\tprivate AtomicBoolean\t\t\tisActive;\n\n\t/** counted down on notifyConnect */\n\tprivate CountDownLatch\t\t    connectionEstablished;\n\n\t/** MTU multiples to use as upper bound of the size of the chunk buffer */\n\tprivate static final int MTU_FACTOR = 2; // TODO: ConnectionSpec me.\n\t\n\t/** Assuming TCP MTU of 1500 - ~tcp header overhead rounded to nearest power of 8  */\n\tstatic final int MTU_SIZE = 1488;\n\t\n\t/** chunk buffer size */\n\tstatic final int CHUNK_BUFF_SIZE = Math.min(MTU_SIZE * MTU_FACTOR, 0xFFFF);\n\t\n\t/** minimum request size in bytes -- using PING e.g. 14 b */\n\tstatic final int MIN_REQ_SIZE = 14; \n\t\n\t/** Chunk Queue size (slots) */\n\tstatic final int CHUNK_Q_SIZE = CHUNK_BUFF_SIZE / MIN_REQ_SIZE;\n\t\n\t/** chunk buffer */\n\tprivate byte[] chunkbuff;\n\t\n\t/**  chunk [hi:idx | lo:off] control long word */\n\tprivate int ctl_word;\n\t\n\t/** Chunk Queue of requests in Chunk buffer */\n\tprivate PendingCPRequest[] chunkqueue;\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructor(s)\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @param spec\n\t * @throws ClientRuntimeException\n\t */\n\t//\tprotected\n\tpublic ChunkedPipelineConnection (ConnectionSpec spec) throws ClientRuntimeException {\n\t\tsuper(spec.setModality(Modality.Asynchronous));\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Extension\n\t// ------------------------------------------------------------------------\n\t/**\n\t * \n\t */\n\t@SuppressWarnings(\"boxing\")\n\t@Override\n\tprotected void initializeComponents () {\n\n\t\tspec.setConnectionFlag(Flag.PIPELINE, true);\n\t\tspec.setConnectionFlag(Flag.RELIABLE, true);\n\t\tspec.setConnectionFlag(Flag.SHARED, true);\n\n\t\tchunkbuff = new byte[CHUNK_BUFF_SIZE];\n\t\tchunkqueue = new PendingCPRequest[CHUNK_Q_SIZE];\n\n\t\tctl_word = 0;\n\n\t\trequestlock = new ReentrantLock(false);\n\t\t\n\t\tsuper.initializeComponents(); // REVU: this is a bit oddly placed .. \n\n\n\t\tisActive = new AtomicBoolean(false);\n\t\tconnectionEstablished = new CountDownLatch(1);\n\n\t\tpendingResponseQueue = new Concurrent2LockQueue<PendingCPRequest[]>();\n\t\t\n\t\trespHandler = new ResponseHandler();\n\t\trespHandlerThread = new Thread(respHandler, \"response-handler\");\n\t\trespHandlerThread.start();\n\n\t\tisActive.set(false); // REVU: ? superstitious ?\n\t}\n\n\t@Override\n\tprotected void notifyConnected () {\n\t\tsuper.notifyConnected();\n\t\tLog.log(\"Pipeline <%s> connected\", this);\n\t\tisActive.set(true);\n\t\tconnectionEstablished.countDown();\n\t}\n\t@Override\n\tprotected void notifyDisconnected () {\n\t\tsuper.notifyDisconnected();\n\t\tLog.log(\"Pipeline <%s> disconnected\", this);\n\t\tisActive.set(true);\n\t\tconnectionEstablished.countDown();\n\t}\n\n\t/**\n\t * Pipeline must use a concurrent protocol handler.\n\t *  \n\t * @see org.jredis.ri.alphazero.connection.ConnectionBase#newProtocolHandler()\n\t */\n\t@Override\n\tprotected Protocol newProtocolHandler () {\n\t\treturn new ConcurrentSyncProtocol();\n\t\t//\t\treturn new SynchProtocol();\n\t}\n\n//\t    @Override\n//\t    protected OutputStream newOutputStream(OutputStream socketOutputStream) {\n//\t    \treturn new BufferedOutputStream(socketOutputStream, MTU_SIZE);\n//\t    }\n\n\t/**\n\t * Just make sure its a {@link FastBufferedInputStream}.\n\t */\n\t@SuppressWarnings(\"boxing\")\n\t@Override\n\tprotected final InputStream newInputStream (InputStream socketInputStream) throws IllegalArgumentException {\n\n\t\tInputStream in = super.newInputStream(socketInputStream);\n\t\tif(!(in instanceof FastBufferedInputStream)){\n\t\t\tSystem.out.format(\"WARN: input was: %s\\n\", in.getClass().getCanonicalName());\n\t\t\tin = new FastBufferedInputStream (in, spec.getSocketProperty(Connection.Socket.Property.SO_RCVBUF));\n\t\t}\n\t\treturn in;\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface: Connection\n\t// ------------------------------------------------------------------------\n\n\n\t/**\n\t * This is a true asynchronous method.  The actual request write to server \n\t * possibly does occur in this method if the connection determines it is \n\t * optimal to flush the pipeline buffer, or, if you explicitly had requested\n\t * flush via {@link Command#CONN_FLUSH}. \n\t * <p>\n\t * Other item of note is that once a QUIT request has been queued, no further\n\t * requests are accepted and a ClientRuntimeException is thrown.\n\t * \n\t * @see org.jredis.ri.alphazero.connection.ConnectionBase#queueRequest(org.jredis.protocol.Command, byte[][])\n\t */\n\n\t@Override\n\tpublic final Future<Response> queueRequest (Command cmd, byte[]... args) \n\tthrows ClientRuntimeException, ProviderException \n\t{\n\t\tif(!isConnected()) \n\t\t\tthrow new NotConnectedException (\"Not connected!\");\n\n\t\tif(pendingQuit) \n\t\t\tthrow new ClientRuntimeException(\"Pipeline shutting down: Quit in progess; no further requests are accepted.\");\n\n\t\tProtocol\t\tprotocol = Assert.notNull(getProtocolHandler(), \"thread protocol handler\", ProviderException.class);\n\t\t//\t\tLog.log(\"protocol %d@%s\", protocol.hashCode(), protocol.getClass());\n\n\t\tfinal boolean sendreq = \n\t\t\tcmd.responseType != ResponseType.VIRTUAL && \n\t\t\tcmd.responseType != ResponseType.NOP;\n\n\t\t/* setup send buffer if necessary */\n\t\tint\t\treqbyteslen = 0;\n\t\tif(sendreq) {\n\t\t\treqbyteslen = ProtocolHelper.calcReqBuffSize(cmd, args);\n\t\t}\n\n\t\t/* PendingCPRequest provides transparent hook to force flush on future get(..) */\n\t\tfinal PendingCPRequest \tqueuedRequest = new PendingCPRequest(this, cmd);\n\n\t\t/* possibly silly optimization, pulled out of sync block */\n\t\tfinal OutputStream out = getOutputStream();\n\t\tfinal boolean isflush = cmd == Command.CONN_FLUSH;\n\t\tfinal boolean exceeds = reqbyteslen > CHUNK_BUFF_SIZE;\n\t\tfinal boolean isquit = cmd == Command.QUIT;\n\n\t\t/* auth is used on connector initialization and must be sent asap */ \n\t\tfinal boolean doflush = \n\t\t\tcmd == Command.AUTH \t|| \n\t\t\tcmd == Command.SELECT \t|| \n\t\t\tisquit\t\t\t\t\t||\n\t\t\tisflush;\n\n\t\ttry {\n\t\t\trequestlock.lock();\n\t\t\t\n\t\t\t/* ======== CRITICAL BLOCK ====== */\n\t\t\t\n\t\t\t/* 4 byte control word is [ idx | off ] */\n\t\t\t/* chunk_ctl_word is contended and must be accessed only inside of critical block */\n\t\t\tfinal int __ctl_word = ctl_word;\t// REVU: opportunity ..\n\t\t\tint idx = __ctl_word >> 16;\n\t\t\tint off = __ctl_word & 0x0000FFFF;\n\n\t\t\tboolean overflows = exceeds || off + reqbyteslen > CHUNK_BUFF_SIZE ? true : false;\n\t\t\t\n\t\t\tif(overflows) {\n\t\t\t\tout.write(chunkbuff, 0, off);\n\t\t\t\tout.flush();\n\t\t\t\toff = 0;\n\t\t\t\t\n\t\t\t\tpendingResponseQueue.add(chunkqueue);\n\t\t\t\tchunkqueue = new PendingCPRequest[CHUNK_Q_SIZE];\n\t\t\t\tidx = 0;\n\t\t\t}\n\n\t\t\tif(sendreq){\n\t\t\t\tif(exceeds) {\n\t\t\t\t\t/* can optimize and dispense with new byte[] -- only for large payloads */\n\t\t\t\t\t/* chunkqueue should be empty and idx 0 : assert for now */\n\t\t\t\t\tout.write(protocol.createRequestBuffer(cmd, args));\n\t\t\t\t\tout.flush();\n\t\t\t\t\tchunkqueue[0] = queuedRequest;\n\t\t\t\t\tfinal PendingCPRequest[] oneoffitem =  new PendingCPRequest[1];\n\t\t\t\t\toneoffitem[0] = queuedRequest;\n\t\t\t\t\tpendingResponseQueue.add(oneoffitem);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// REVU: next optimization step !\n\t\t\t\t\t// NOTE: this 'new' here is not necessary and is only because of copy/paste from\n\t\t\t\t\t// ProtocolBase (see ProtocolHelper.writeReq..().\n\t\t\t\t\tProtocolHelper.writeRequestToBuffer(new ProtocolHelper.Buffer(chunkbuff, off), cmd, args);\n\t\t\t\t\toff+=reqbyteslen;\n\t\t\t\t\tchunkqueue[idx] = queuedRequest;\n\t\t\t\t\tidx++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(doflush) {\n\t\t\t\tif(!isquit){\n\t\t\t\t\tif(off>0){\n\t\t\t\t\t\tout.write(chunkbuff, 0, off);\n\t\t\t\t\t\tout.flush();\n\t\t\t\t\t\toff = 0;\n\t\t\t\t\t\tpendingResponseQueue.add(chunkqueue);\n\t\t\t\t\t\tchunkqueue = new PendingCPRequest[CHUNK_Q_SIZE];\n\t\t\t\t\t\tidx = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpendingQuit = true;\n\t\t\t\t\tisActive.set(false);\n\t\t\t\t\tfinal PendingCPRequest[] oneoffitem =  new PendingCPRequest[1];\n\t\t\t\t\toneoffitem[0] = queuedRequest;\n\t\t\t\t\tpendingResponseQueue.add(oneoffitem);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t/* update 4 byte control word [ idx | off ] */\n\t\t\tctl_word = (idx << 16) | (off | 0x0); \n\t\t\t\n\t\t\t/* ==END=== CRITICAL BLOCK ====== */\n\t\t\t/* REVU: both of these exceptions require setting fault on the cached pendings */\n\t\t} catch (IOException e) {\n\t\t\tLog.error(\"IOException cmd:%s isConnected:%b\", cmd.code, isConnected());\n\t\t\tthis.onConnectionFault(String.format(\"IOFault (cmd: %s)\", cmd.code), true);\n\t\t} catch (ArrayIndexOutOfBoundsException e){\n\t\t\tLog.error(\"on %s\", cmd.code);\n\t\t\tthrow new ProviderException(\"BUG - recheck assumptions ..\", e);\n\t\t} finally {\n\t\t\trequestlock.unlock();\n\t\t}\n\t\t\n\t\treturn queuedRequest;\n\t}\n\n\tvoid onResponseHandlerError (ClientRuntimeException cre, PendingRequest request) {\n\t\tLog.error(\"Pipeline response handler encountered an error: \" + cre.getMessage());\n\n\t\t// signal fault\n\t\tonConnectionFault(cre.getMessage(), false);\n\t\t\n\t\t// set execution error for future object\n\t\trequest.setCRE(cre);\n\n//\t\tPendingCPRequest pending = null;\n\t\twhile(true){\n\t\t\ttry {\n//\t\t\t\tpending = pendingResponseQueue.remove();\n\t\t\t\tPendingCPRequest[] items = null;\n\t\t\t\titems = pendingResponseQueue.remove();\n\t\t\t\tfor(PendingCPRequest item : items){\n\t\t\t\t\tif(item == null) { break; }\n\t\t\t\t\titem.setCRE(cre);\n\t\t\t\t\tLog.error(\"set pending %s response to error with CRE\", item.cmd);\n\t\t\t\t}\n//\t\t\t\tpending.setCRE(cre);\n//\t\t\t\tLog.error(\"set pending %s response to error with CRE\", pending.cmd);\n\t\t\t}\n\t\t\tcatch (NoSuchElementException empty){ break; }\n\t\t}\n\t}\n\t\n\t// ========================================================================\n\t// Inner Class\n\t// ========================================================================\n\t\n\t/**\n\t * This was pretty much based on Maged M. Michael, and Michael L. Scott's\n\t * 2 Lock concurrent queue as described in their paper, \"Simple, Fast, \n\t * and Practical Non-Blocking and Blocking Concurrent Algorithms\" \n\t * ({michael, scott}@cs.rochester.edu).  \n\t * \n\t * For the specific use case of {@link ChunkedPipelineConnection}, \n\t * we will have 1:1 producer-consumer concurrency and can do\n\t * away with the 2 locks of their algorithm and get better performance.\n\t * \n\t * This class partially supports the {@link BlockingQueue} for the\n\t * purposes of the pipeline.  It is not intended for general use.\n\t *\n\t * @author  joubin (alphazero@sensesay.net)\n\t * @date    Dec 9, 2009 (original)\n\t * @date    Jan 23, 2012 (this version)\n\t * \n\t */\n\tfinal static class Concurrent2LockQueue<E> implements BlockingQueue<E>{\n\n\t\t/**\n\t\t * @param <E>\n\t\t */\n\t\tprivate static final class Node<E> {\n\t\t\tprivate volatile E \t\t\titem;\n\t\t\tprivate volatile Node<E>\tnext;\n\n\t\t\t@SuppressWarnings(\"unchecked\")\n\t        private static final\n\t\t\tAtomicReferenceFieldUpdater<Node, Node>\n\t\t\tnextUpdater = \n\t\t\t\tAtomicReferenceFieldUpdater.newUpdater\n\t\t\t\t(Node.class, Node.class, \"next\");\n\n\t\t\t@SuppressWarnings(\"unchecked\")\n\t        private static final\n\t\t\tAtomicReferenceFieldUpdater<Node, Object>\n\t\t\titemUpdater = \n\t\t\t\tAtomicReferenceFieldUpdater.newUpdater\n\t\t\t\t(Node.class, Object.class, \"item\");\n\n\t\t\tprivate Node(E x, Node<E> n) { item = x; next = n; }\n\t\t\t\n\t\t\tprivate final E getItem() { return item; }\n\t\t\tprivate final void setItem(E update) { itemUpdater.set(this, update); }\n\t\t\tprivate final void setNext(Node<E> update) { nextUpdater.set(this, update); }\n\t\t\tprivate final Node<E> getNext() { return next; }\n\t\t}\n\n\t\t// --------------------------------------------------------------\n\t\t// Properties\n\t\t// --------------------------------------------------------------\n\t\tprivate transient volatile Node<E> head = new Node<E>(null, null);\n\t\tprivate transient volatile Node<E> tail = head;\n\n\t    public Concurrent2LockQueue () {}\n\n\t\t// --------------------------------------------------------------\n\t\t// INTERFACE: BlockingQueue<E>\n\t\t// --------------------------------------------------------------\n\t    \n\t    /* (non-Javadoc) @see java.util.concurrent.BlockingQueue#offer(java.lang.Object) */\n\t    public final boolean offer(E item) {\n\t    \tif(null == item) throw new NullPointerException(\"item\");\n\t    \tfinal Node<E> n = new Node<E>(item, null);\n\n\t    \tNode<E> t = tail;\n\t\t\tt.setNext(n);\n\t\t\ttail = n;\n\n\t    \treturn true;\n\t    }\n\t    \n\t\t/* (non-Javadoc) @see java.util.concurrent.BlockingQueue#poll(long, java.util.concurrent.TimeUnit) */\n\t\t@Override final\n\t\tpublic E poll(long timeout, TimeUnit unit) throws InterruptedException {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t\n\t    /* (non-Javadoc) @see java.util.Queue#poll() */\n\t    public final E poll () {\n\t    \tE item = null;\n\n\t\t\tfinal Node<E> h = head;\n\t\t\tfinal Node<E> newhead = h.getNext();\n\t\t\tif(newhead != null) {\n\t\t\t\titem = newhead.getItem();\n\t\t\t\thead = newhead;\n\t\t\t\tnewhead.setItem(null);\n\t\t\t\th.setNext(null);\n\t\t\t} \n\n\t    \treturn item;\n\t    }\n\t    \n\t    /* (non-Javadoc) @see java.util.Queue#peek() */\n\t    @Override final\n\t    public E peek () {\n\t    \tE item = null;\n\n\t\t\tfinal Node<E> h = head;\n\t\t\tfinal Node<E> f = h.getNext();\n\t\t\tif(f != null) {\n\t\t\t\titem = f.getItem();\n\t\t\t}\n\n\t    \treturn item;\n\t    }\n\t    \n\t\t/* (non-Javadoc) @see java.util.concurrent.BlockingQueue#take() */\n\t\t@Override final\n\t\tpublic E take() throws InterruptedException {\n\t\t\tE\titem = null;\n\t\t\twhile(true){\n\t\t\t\titem = poll();\n\t\t\t\tif(item != null) \n\t\t\t\t\tbreak;\n\t\t\t\tLockSupport.parkNanos(1L); // magic number -- let's configure this.\n\t\t\t\tif(Thread.interrupted()){\n\t\t\t\t\tLog.error(\"%s interrupted!\", Thread.currentThread().getName());\n\t\t\t\t\tthrow new InterruptedException();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn item;\n\t\t}\n\t\t\n\t\t/* (non-Javadoc) @see java.util.Queue#remove() */\n\t\t@Override final\n\t\tpublic E remove() {\n\t\t\tfinal E item = poll();\n\t\t\tif(item == null) \n\t\t\t\tthrow new NoSuchElementException();\n\t\t\treturn item;\n\t\t}\n\n\t\t/* (non-Javadoc) @see java.util.concurrent.BlockingQueue#add(java.lang.Object) */\n\t\t@Override final\n\t\tpublic boolean add(E e) {\n\t\t\treturn this.offer(e);\n\t\t}\n\n\t\t/* -- NOT SUPPORTED -- BEGIN */\n\t\t\n\t\t@Override final\n\t\tpublic E element() {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic boolean addAll(Collection<? extends E> c) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic void clear() {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic boolean contains(Object o) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic boolean containsAll(Collection<?> c) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final public boolean isEmpty() {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic Iterator<E> iterator() {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic boolean remove(Object o) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic boolean removeAll(Collection<?> c) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic boolean retainAll(Collection<?> c) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic int size() {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic Object[] toArray() {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic <T> T[] toArray(T[] a) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic int drainTo(Collection<? super E> c) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic int drainTo(Collection<? super E> c, int maxElements) {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic void put(E e) throws InterruptedException {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t@Override final\n\t\tpublic int remainingCapacity() {\n\t\t\tthrow new RuntimeException(\"not supported\");\n\t\t}\n\t\t/* -- NOT SUPPORTED -- END */\n\t}\n\t\n\t// ========================================================================\n\t// Inner Class\n\t// ========================================================================\n\t\n\t/**\n\t * A not so KISSy reproduction of necessary {@link Protocol} support\n\t * from {@link ProtocolBase}.  Stays here until update of the interface\n\t * to allow for sharing of the codebase.\n\t * @author Joubin <alphazero@sensesay.net>\n\t *\n\t */\n\tfinal static class ProtocolHelper {\n\t\t/* hackedy hack -- to go bye bye soon  */\n\t\tstatic class Buffer {\n\t\t\tbyte[] b = null;\n\t\t\tprivate int off = 0;\n\t\t\tBuffer(int size){\n\t\t\t\tb = new byte[size];\n\t\t\t}\n\t\t\tBuffer(byte[] b, int off){\n\t\t\t\tthis.b = b;\n\t\t\t\tthis.off = off;\n\t\t\t}\n\t\t\tvoid write (byte[] d){\n\t\t\t\tfinal int dlen = d.length;\n\t\t\t\tSystem.arraycopy(d, 0, b, off, dlen);\n\t\t\t\toff+=dlen;\n\t\t\t}\n\t\t\tvoid write (byte d){\n\t\t\t\tb[off] = d;\n\t\t\t\toff++;\n\t\t\t}\n\t\t\tbyte[] getBytes() {\n\t\t\t\treturn b;\n\t\t\t}\n\t\t}\n\t\tpublic static int calcReqBuffSize (Command cmd, byte[] ... args) throws IllegalArgumentException {\n\t\t\tbyte[] cmdLenBytes = Convert.toBytes(cmd.bytes.length);\n\t\t\tbyte[] lineCntBytes = Convert.toBytes(args.length+1);\n\n\t\t\tint bsize = 1 + lineCntBytes.length + CRLF_LEN + 1 + cmdLenBytes.length + CRLF_LEN + cmd.bytes.length + CRLF_LEN;\n\t\t\tfor(int i=0;i<args.length; i++){\n\t\t\t\tbyte[] argLenBytes = Convert.toBytes(Assert.notNull(args[i], i, ProviderException.class).length);\n\t\t\t\tint _bsize = 1 + argLenBytes.length + CRLF_LEN + args[i].length + CRLF_LEN;\n\t\t\t\tbsize += _bsize;\n\t\t\t}\n\t\t\treturn bsize;\n\t\t}\n\t\tstatic public byte[] writeRequestToBuffer(final Buffer buffer, final Command cmd, final byte[]...args) throws ProviderException, IllegalArgumentException {\n\t\t\t//    \t\tBuffer buffer = null;\n\t\t\tbyte[] cmdLenBytes = Convert.toBytes(cmd.bytes.length);\n\t\t\tbyte[] lineCntBytes = Convert.toBytes(args.length+1);\n\n\t\t\tbuffer.write(COUNT_BYTE);  \t\t\n\t\t\tbuffer.write(lineCntBytes);\t\t\n\t\t\tbuffer.write(CRLF);\t\t\t\t\n\t\t\tbuffer.write(SIZE_BYTE);\t\t\n\t\t\tbuffer.write(cmdLenBytes);\t\t\n\t\t\tbuffer.write(CRLF);\t\t\t\t\n\t\t\tbuffer.write(cmd.bytes);\t\t\n\t\t\tbuffer.write(CRLF);\n\n\t\t\tswitch (cmd.requestType) {\n\n\t\t\tcase NO_ARG:\n\t\t\t\tbreak;\n\n\t\t\t\t// TODO: check w/ antirez if in fact nulls are now generally accepted\n\t\t\t\t// that is the only diff here.\n\t\t\tcase BULK_SET:\n\t\t\t\tString errmsg = \"Only MSET, MSETNX, LINSERT bulk commands are supported\";\n\t\t\t\tAssert.isTrue(cmd == Command.MSET || cmd == Command.MSETNX || cmd == Command.LINSERT, errmsg, NotSupportedException.class);\n\n\t\t\t\t// THIS IS CLEARLY BROKEN ... SO MUCH FOR COMPREHSIVE TESTS ...\n\t\t\t\tbuffer.write(COUNT_BYTE);\n\t\t\t\tbuffer.write(lineCntBytes);\n\t\t\t\tbuffer.write(CRLF);\n\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\tbuffer.write(cmdLenBytes);\n\t\t\t\tbuffer.write(CRLF);\n\t\t\t\tbuffer.write(cmd.bytes);\n\t\t\t\tbuffer.write(CRLF);\n\n\t\t\t\tfor(int s=0; s<args.length; s++){\n\t\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\t\tif (args[s] != null) {\n\t\t\t\t\t\tbuffer.write(Convert.toBytes(args[s].length));\n\t\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\t\tbuffer.write(args[s]);\n\t\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuffer.write(ASCII_ZERO);\n\t\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tfor(int i=0;i<args.length; i++){\n\t\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\t\tbuffer.write(Convert.toBytes(Assert.notNull(args[i], i, ProviderException.class).length));\n\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\tbuffer.write(args[i]);\n\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\t}\n\t\t\treturn buffer.getBytes();\n\t\t}\n\n\t}\n\t\n\t// ========================================================================\n\t// Inner Class\n\t// ========================================================================\n\t\n\t/**\n\t * ChunkedPipeline specific of {@link PendingRequest}.  This class\n\t * maintains a reference to the pipeline to allow for transparent \n\t * invokation of {@value Command#CONN_FLUSH}.\n\t * \n\t * @author Joubin <alphazero@sensesay.net>\n\t */\n\tfinal static class PendingCPRequest extends PendingRequest {\n\n\t\tprivate final ChunkedPipelineConnection pipeline;\n\t\t\n\t\tPendingCPRequest(ChunkedPipelineConnection pipeline, Command cmd) {\n\t\t\tsuper(cmd);\n\t\t\tthis.pipeline = pipeline;\n\t\t}\n\t\t@Override final\n\t\tpublic Response get() \n\t\tthrows InterruptedException, ExecutionException {\n\t\t\trequestFlush();\n\t\t\treturn super.get();\n\t\t}\n\t\t@Override final\n\t\tpublic Response get(long timeout, TimeUnit unit)\n\t\tthrows InterruptedException, ExecutionException, TimeoutException \n\t\t{\n\t\t\trequestFlush();\n\t\t\treturn super.get(timeout, unit);\n\t\t}\n\t\tfinal private void requestFlush() {\n\t\t\tif(cmd != Command.QUIT) {\n\t\t\t\tpipeline.queueRequest(Command.CONN_FLUSH);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnew Exception().printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\t\n\t// ========================================================================\n\t// Inner Class\n\t// ========================================================================\n\t\n\t/**\n\t * Provides the response processing logic as a {@link Runnable}.\n\t * <p>\n\t * TODD: Needs to have a more regulated operating cycle.  Right now its just\n\t * infinite loop until something goes boom.  Not good.\n\t * \n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, Oct 18, 2009\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic final class ResponseHandler implements Runnable, Connection.Listener {\n\n//\t\tprivate final AtomicBoolean work_flag;\n\t\tprivate volatile boolean work_flag; // REVU: checked in every loop - no need for atomic.\n\t\tprivate final AtomicBoolean alive_flag;\n\t\tprivate final AtomicReference<Thread> thread;\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Constructor\n\t\t// ------------------------------------------------------------------------\n\n\t\t// REVU: this is a complete mess -- TODO: \n\t\t/**\n\t\t * Adds self to the listeners of the enclosing {@link Connection} instance.\n\t\t */\n\t\tpublic ResponseHandler () {\n\t\t\tChunkedPipelineConnection.this.addListener(this);\n//\t\t\tthis.work_flag = new AtomicBoolean(true); \n\t\t\tthis.work_flag = true;\n\t\t\tthis.alive_flag = new AtomicBoolean(false);\n\t\t\tthis.thread = new AtomicReference<Thread>(null);\n\t\t} \n\n\t\t// ------------------------------------------------------------------------\n\t\t// INTERFACE: Runnable\n\t\t// ------------------------------------------------------------------------\n\t\t/**\n\t\t * Keeps processing the {@link PendingRequest}s in the pending {@link Queue}\n\t\t * until a QUIT is encountered in the pending queue.  Thread will stop after\n\t\t * processing the QUIT response (which is expected to be a {@link VirtualResponse}.\n\t\t * <p>\n\t\t * TODO: not entirely clear what is the best way to handle exceptions.\n\t\t * <p>\n\t\t * TODO: socket Reconnect in the context of pipelining is non-trivial, and maybe\n\t\t * not even practically possible.  (e.g. request n is sent but pipe breaks on\n\t\t * some m (m!=n) response.  non trivial.  Perhaps its best to assume broken connection\n\t\t * means faulted server, specially given the fact that a pipeline has a heartbeat\n\t\t * so the issue can not be timeout.\n\t\t */\n\t\t@Override\n\t\tpublic void run () {\n\t\t\tthread.compareAndSet(null, Thread.currentThread());\n\t\t\talive_flag.compareAndSet(false, true);\n\t\t\t/** Response handler thread specific protocol handler -- optimize fencing */\n\t\t\tProtocol protocol = Assert.notNull (newProtocolHandler(), \"the delegate protocol handler\", ClientRuntimeException.class);\n\n\t\t\tLog.log(\"Pipeline <%s> thread for <%s> started.\", Thread.currentThread().getName(), ChunkedPipelineConnection.this.toString());\n\t\t\tPendingCPRequest pending = null;\n\t\t\t//\t\t\twhile(work_flag.get()){\n\t\t\twhile(work_flag){\n\t\t\t\tResponse response = null;\n\t\t\t\ttry {\n\t\t\t\t\tPendingCPRequest[] items = null;\n\t\t\t\t\titems = pendingResponseQueue.take();\n\t\t\t\t\tfor(PendingCPRequest item : items) {\n\t\t\t\t\t\tif(item == null) { break; }\n\t\t\t\t\t\tpending = item;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// TODO: here -- simplify REVU: ?\n\t\t\t\t\t\t\tresponse = protocol.createResponse(pending.cmd);\n\t\t\t\t\t\t\tresponse.read(getInputStream());\n\t\t\t\t\t\t\tpending.response = response;\n\t\t\t\t\t\t\tpending.completion.signal();\n\t\t\t\t\t\t\tif(response.getStatus().isError()) {\n\t\t\t\t\t\t\t\tLog.error (\"(Asynch) Error response for \" + pending.cmd.code + \" => \" + response.getStatus().message());\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// TODO: REVU: this in context of both connection and (general) errors. \n\t\t\t\t\t\tcatch (ProviderException bug){\n\t\t\t\t\t\t\tLog.bug (\"ProviderException: \" + bug.getMessage());\n\t\t\t\t\t\t\tonResponseHandlerError(bug, pending);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (ClientRuntimeException cre) {\n\t\t\t\t\t\t\tLog.problem (\"ClientRuntimeException: \" + cre.getMessage());\n\t\t\t\t\t\t\tonResponseHandlerError(cre, pending);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (RuntimeException e){\n\t\t\t\t\t\t\tLog.problem (\"Unexpected (and not handled) RuntimeException: \" + e.getMessage());\n\t\t\t\t\t\t\tonResponseHandlerError(new ClientRuntimeException(\"Unexpected (and not handled) RuntimeException\", e), pending);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// REVU: this should be noted on the API spec : TODO:\n\t\t\t\t\t\t/* QUITs are not sent in pipelines to Redis as it immediately will \n\t\t\t\t\t\t * drop the connection and there goes the pending stuff. */\n\t\t\t\t\t\tif(pending.cmd == Command.QUIT) {\n\t\t\t\t\t\t\tChunkedPipelineConnection.this.disconnect();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// REVU: why the general catch -- related to coherence issues of the volatile flags\n\t\t\t\t// TODO: review and clean this shit up\n\t\t\t\t//\t\t\t\tcatch (InterruptedException e1) {\n\t\t\t\tcatch (Throwable e1) {\n\t\t\t\t\tLog.log(\"Pipeline thread interrupted.\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tLog.log(\"Pipeline <%s> thread for <%s> stopped.\", Thread.currentThread().getName(), ChunkedPipelineConnection.this);\n\t\t\talive_flag.compareAndSet(true, false);\n\t\t}\n\n\t\t// REVU: TODO: \n\t\tfinal private void stopHandler() {\n\t\t\tLog.log(\"%s stopping handler thread\", this);\n//\t\t\twork_flag.set(false);\n\t\t\twork_flag = false;\n\t\t\tthread.get().interrupt();\n\t\t\t//        \tPipelineConnectionBase.this.respHandlerThread.interrupt();\n\t\t}\n\t\tfinal private void shutdownHandler() {\n\t\t\t/*\n\t\t\t * It is not expected that shutdown would get called before\n\t\t\t * stop, but if it has, this makes sure we first go through\n\t\t\t * the stop sequence.\n\t\t\t */\n//\t\t\tif(work_flag.get() != false || alive_flag.get() != false)\n\t\t\tif(work_flag != false || alive_flag.get() != false)\n\t\t\t\tstopHandler();\n\t\t\talive_flag.set(false);\n\t\t\tChunkedPipelineConnection.this.removeListener(this);\n\t\t\tLog.log(\"%s response handler has shutdown\", this);\n\t\t}\n\t\t// ------------------------------------------------------------------------\n\t\t// INTERFACE: Connection.Listener\n\t\t/* \n\t\t * hooks for integrating the response handler thread's state with the \n\t\t * wrapping connection's state through event callbacks. \n\t\t */\n\t\t// ------------------------------------------------------------------------\n\n\t\t// REVU: clean this shit up. TODO:\n\t\t/**\n\t\t * @see org.jredis.connector.Connection.Listener#onEvent(org.jredis.connector.Connection.Event)\n\t\t */\n\t\t@Override\n\t\tpublic void onEvent (Event event) {\n\t\t\tif(event.getSource() != ChunkedPipelineConnection.this) {\n\t\t\t\tString msg = String.format(\"event source [%s] is not this pipeline [%s]\", event.getSource(), ChunkedPipelineConnection.this);\n\t\t\t\tLog.bug(msg);\n\t\t\t\tthrow new ProviderException(msg);\n\t\t\t}\n\t\t\t//        \t(new Exception()).printStackTrace();\n\t\t\tLog.log(\"Pipeline.ResponseHandler: onEvent %s source: %s\", event.getType().name(), event.getSource());\n\t\t\tswitch (event.getType()){\n\t\t\tcase CONNECTED:\n\t\t\t\t// (re)start\n\t\t\t\tbreak;\n\t\t\tcase DISCONNECTED:\n\t\t\t\t// should be stopped now\n\t\t\t\tbreak;\n\t\t\tcase CONNECTING:\n\t\t\t\t// no op\n\t\t\t\tbreak;\n\t\t\tcase FAULTED:\n\t\t\tcase DISCONNECTING:\n\t\t\t\tstopHandler();\n\t\t\t\tbreak;\n\t\t\tcase SHUTDOWN:\n\t\t\t\tshutdownHandler();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/ConnectionBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_BANDWIDTH;\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_CONN_TIME;\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_LATENCY;\nimport static org.jredis.connector.Connection.Socket.Property.SO_RCVBUF;\nimport static org.jredis.connector.Connection.Socket.Property.SO_SNDBUF;\nimport static org.jredis.connector.Connection.Socket.Property.SO_TIMEOUT;\nimport static org.jredis.ri.alphazero.support.Assert.notNull;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.InetSocketAddress;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.Connection.Event.Type;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.protocol.DefaultProtocolFactory;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Convert;\nimport org.jredis.ri.alphazero.support.FastBufferedInputStream;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * This abstract class is responsible for managing the socket connection, and, defining\n * the template of the Connection for concrete extensions.  Given that, it basically\n * manages all the details of dealing with {@link Socket}, and maintains the reference to\n * the handler.  \n * <p>\n * Further, it provides the default {@link NotSupportedException} response for the \n * {@link Connection}'s methods that the extending classes of various {@link Connection.Modality}\n * are expected to support.  (They would simply implement the method that they support.)\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 20, 2009-2011\n * @since   alpha.0\n * \n */\n\npublic abstract class ConnectionBase implements Connection{\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t\n\t/** \n\t * Thread specific protocol handler -- optimize fencing \n\t * Protocol specific matters are delegated to an instance of {@link Protocol} \n\t */\n\tThreadLocal<Protocol> thrdProtocol = new ThreadLocal<Protocol>();\n\t\n\t/** Connection specs used to create this {@link Connection} */\n\tfinal protected ConnectionSpec  \tspec;\n\t\n\tprivate boolean \t\t\tisConnected = false;\n\t/** socket reference -- a new instance obtained in {@link ConnectionBase#newSocketConnect()} */\n\tprivate java.net.Socket\t\tsocket;\n\tprivate InputStream\t\t    instream;\n\tprivate OutputStream\t    outstream;\n\t\n\t/** Connector Listeners */\n\tfinal private Set<Connection.Listener> listeners = new HashSet<Connection.Listener>();\n\n//\t/** Keep-alive heartbeat daemon thread  */\n//\tprivate HeartbeatJinn\t\t\theartbeat;\n\n\t/** address of the socket connection */\n\tprivate final InetSocketAddress  \tsocketAddress;\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructors\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * Will create and initialize a socket per the connection spec.\n\t * @See {@link ConnectionSpec}\n\t * @param spec\n\t * @param connectImmediately will connect the socket immediately if true\n\t * @throws ClientRuntimeException if connection attempt to specified host is not possible and\n\t * connect immediate was requested.\n\t */\n\tprotected ConnectionBase (ConnectionSpec spec) \n\t\tthrows ClientRuntimeException\n\t{\n\t\ttry {\n\t\t\tthis.spec = notNull(spec, \"ConnectionSpec init parameter\", ClientRuntimeException.class);\n\t\t\tsocketAddress = new InetSocketAddress(spec.getAddress(), spec.getPort());\n\t\t\tinitializeComponents();\n\t\t}\n\t\tcatch (IllegalArgumentException e) { \n\t\t\tthrow new ClientRuntimeException \n\t\t\t\t(\"invalid connection spec parameters: \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new ProviderException(\"Unexpected error on initialize -- BUG\", e);\n\t\t} \n\n\t\tif (spec.getConnectionFlag(Flag.CONNECT_IMMEDIATELY)) {\n\t\t\tconnect ();\n\t\t}\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ============================================================ Connection\n\t/*\n\t * These are the extension points for the concrete connection classes.\n\t */\n\t// ------------------------------------------------------------------------\n\n\t@Override\n\tpublic ConnectionSpec getSpec () {\n\t\treturn this.spec;\n\t}\n\t\n\t@Override\n\tpublic Response serviceRequest(Command cmd, byte[]... args)\n\t\t\tthrows RedisException, ClientRuntimeException, ProviderException \n\t{\n\t\tthrow new NotSupportedException (\n\t\t\t\t\"Response.serviceRequest(Command cmd, \" +\n\t\t\t\t\"byte[]...) is not supported.\");\n\t}\n\n\t@Override\n\tpublic Future<Response> queueRequest(Command cmd, byte[]... args) \n\t\tthrows ClientRuntimeException, ProviderException \n\t{\n\t\tthrow new NotSupportedException (\n\t\t\t\t\"Response.serviceRequest(RequestListener requestListener, \" +\n\t\t\t\t\"Object , Command, byte[]...) is not supported.\");\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Event management\n\n\t/**\n\t * Optional\n\t * @param connListener\n\t * @return\n\t */\n\tfinal public boolean addListener(Listener connListener){\n\t\treturn listeners.add(connListener);\n\t}\n\n\t/**\n\t * Optional\n\t * @param connListener\n\t * @return\n\t */\n\tfinal public boolean removeListener(Listener connListener){\n\t\treturn listeners.remove(connListener);\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Internal ops : Extension points\n\t// ------------------------------------------------------------------------\n\t/**\n     * Extension point: child classes may override for additional components:\n     * <pre>\n     * In the extended class:\n     * <code>\n     * protected void initializeComponents() {\n     *    super.initializeComponents();\n     *    // my components here ...\n     *    //\n     * }\n     * </code>\n     * </pre>\n     */\n    protected void initializeComponents () {\n//\t\tsetProtocolHandler (Assert.notNull (newProtocolHandler(), \"the delegate protocol handler\", ClientRuntimeException.class));\n\t\tif(spec.getConnectionFlag(Connection.Flag.RELIABLE)){\n\t\t\tLog.log(\"WARNING: heartbeat is disabled.\");\n//\t    \theartbeat = new HeartbeatJinn(this, this.spec.getHeartbeat(), \" [\" + this + \"] heartbeat\");\n//\t    \theartbeat.start();\n\t\t}\n    }\n\n    /**\n     * Extension point -- callback on this method when {@link ConnectionBase} has connected to server.\n     * <b>It is important to note that the extension must call super.notifyConnected</b> if reliable service (using\n     * heartbeats) is required!.\n     */\n    protected void notifyConnected () {\n    \tnotifyListeners(new Event(this, Type.CONNECTED));\n    }\n    /**\n     * Extension point -- callback on this method when {@link ConnectionBase} has disconnected from server.\n     * <b>It is important to note that the extension must call super.notifyDisconnected</b> if reliable service (using\n     * heartbeats) is required!.\n     */\n    protected void notifyDisconnected () {\n    \tnotifyListeners(new Event(this, Type.DISCONNECTED));\n    }\n    \n    protected void notifyFaulted (String info) {\n    \tnotifyListeners(new Event(this, Type.FAULTED, info));\n    }\n    protected void notifyShuttingDown () {\n    \tnotifyListeners(new Event(this, Type.SHUTDOWN));\n    }\n    /**\n     * Extension point:  child classes may override to return specific {@link Protocol} implementations per their requirements.\n     * @return\n     */\n    protected Protocol newProtocolHandler () {\n    \tProtocol.Factory protfac = (Protocol.Factory) spec.getConnectionProperty(Property.PROTOCOL_FACTORY); \n    \tif(protfac == null) protfac = new DefaultProtocolFactory();\n    \treturn protfac.newProtocol(spec);\n//\n//    \treturn (new DefaultProtocolFactory()).newProtocol(spec);\n    }\n    \n    /**\n     * Extension point: override to return stream per requirement.  Base implementation uses {@link FastBufferedInputStream} by default,\n     * with buffer size matching the SO_RCVBUF property of the {@link Connection}'s {@link ConnectionSpec}\n     * @param socketInputStream\n     * @return\n     */\n    @SuppressWarnings(\"boxing\")\n\tprotected InputStream newInputStream(InputStream socketInputStream) { \n    \treturn  new FastBufferedInputStream(socketInputStream, spec.getSocketProperty(SO_RCVBUF));\n    }\n    \n    /**\n     * Extension point: override to return stream per requirement.  Base implementation simply returns the input param\n     * @param socketOutputStream\n     * @return\n     */\n    protected OutputStream newOutputStream(OutputStream socketOutputStream) { return socketOutputStream; }\n    \n\t// ------------------------------------------------------------------------\n\t// Inner ops: event management\n\t// ------------------------------------------------------------------------\n\tfinal protected void notifyListeners(Connection.Event e) {\n\t\tfor(Connection.Listener l : listeners)\n\t\t\tl.onEvent(e);\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Inner ops: socket and connection management\n\t// ------------------------------------------------------------------------\n\t/** @return connected status*/\n\tprotected final boolean isConnected () { return isConnected; }\n\t\n\t\n\t/**\n\t * Attempt reconnect.  Must be in a (previously) connected state when called.\n\t * @throws IllegalStateException if not (logically) connected.\n\t */\n\tprotected final void reconnect () {\n\t\tLog.log(\"RedisConnection - reconnecting\");\n\t\tint attempts = 0;\n\n\t\twhile(true){\n\t\t\ttry {\n\t\t\t\tdisconnect();\n\t\t\t\tconnect ();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcatch (RuntimeException e){\n\t\t\t\tLog.error(\"while attempting reconnect: \" + e.getMessage());\n\t\t\t\tif(++attempts == spec.getReconnectCnt()) {\n\t\t\t\t\tLog.problem(\"Retry limit exceeded attempting reconnect.\");\n\t\t\t\t\t\n\t\t\t\t\tString faultmsg = String.format(\"Reconnect retry limit exceeded.  Failed to reconnect to the server after %d reconnect attempts\", attempts);\n\t\t\t\t\tonConnectionFault(faultmsg, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Will throw a {@link ClientRuntimeException} if raiseEx is true\n\t * @throws IllegalStateException\n\t */\n\tprotected final void onConnectionFault (String fault, boolean raiseEx) throws ClientRuntimeException {\n\t\tnotifyFaulted(fault);\n\t\tLog.problem(\"Shutting down due to connection FAULT: %s - %s\", fault, this);\n//\t\tnotifyShuttingDown();\n\t\tshutdown(); // REVU: best to add a pending shutdown flag ..\n \t\tif(raiseEx) \n \t\t\tthrow new ClientRuntimeException(fault);\n\t}\n\n\t/**\n\t * @throws IOException\n\t * @throws IllegalStateException\n\t */\n\tprotected final void connect () throws IllegalStateException, ClientRuntimeException {\n\t\t// we're not connected\n\t\tAssert.isTrue (!isConnected(), IllegalStateException.class);\n\n\t\t// create new socket and connect\n\t\t//\n\t\ttry {\n\t\t\tnewSocketConnect();\n\t\t} \n\t\tcatch (IOException e) {\n\t\t\tString faultmsg = String.format(\"Socket connect failed [cause: %s] -- make sure the server is running at %s:%d\", e, spec.getAddress().getHostName(), spec.getPort());\n\t\t\tonConnectionFault(faultmsg, true);\n//\t\t\tthrow new ClientRuntimeException(\n//\t\t\t\t\"Socket connect failed -- make sure the server is running at \" + spec.getAddress().getHostName(), e);\n\t\t}\n\t\t\n\t\t// get the streams\n\t\t//\n\t\ttry {\n\t\t\tinitializeSocketStreams ();\n\t\t} \n\t\tcatch (IOException e) {\n\t\t\tthrow new ClientRuntimeException(\"Error obtaining connected socket's streams \", e);\n\t\t}\n\t\t\n\t\tisConnected = true;\n\t\t\n\t\ttry {\n\t        initializeOnConnect();\n        }\n        catch (RedisException e) {\n        \t// either authorize or db select is using invalid parameters\n        \t// which is user error\n        \tthrow new IllegalArgumentException(\"Failed to connect -- check credentials and/or database settings for the connection spec\", e);\n        }\n\t\t\n\t\tLog.debug (\"CONNECTED | conn: %s\", toString());\n\t\tnotifyConnected();\n\t}\n\n\t/**\n\t * @throws IllegalStateException\n\t */\n\tprotected final void disconnect () throws IllegalStateException {\n\t\tAssert.isTrue (isConnected(), IllegalStateException.class); // REVU: client threads will keep banging on faulted pipelines ...\n\t\t\n\t\tsocketClose();\n\t\tisConnected = false;\n\n\t\tnotifyDisconnected();\n\t\tLog.debug (\"DISCONNECTED | conn: %s\", toString());\n\t}\n\t\n\t/**\n\t * @throws IllegalStateException\n\t */\n\tprotected final void shutdown () throws IllegalStateException {\n\t\tnotifyShuttingDown();\n\t\t/* client threads can be banging on a connection and queued up\n\t\t * on a lock, so isConnected() may have been true\n\t\t * before they acquired it.  \n\t\t */\n\t\tif(isConnected)\n\t\t\tdisconnect();\n\t}\n\t\n\t/**\n\t * Instantiates a new {@link Socket}, sets its properties and flags using the {@link ConnectionBase#spec}\n\t * and finally connects to the {@link ConnectionBase#socketAddress}.\n\t * <p>\n\t * Note that if the platform default send and receive buffers are larger than that specified, this method\n\t * will <b>not</b> use the (smaller) values defined in the spec.\n\t * <p>\n\t * Further note that method will not check connection state. \n\t * \n\t * @throws IOException thrown by the socket object.\n\t */\n\t@SuppressWarnings(\"boxing\")\n\tprivate final void newSocketConnect () \n\t\tthrows IOException \n\t{\n\t\tsocket = new java.net.Socket ();\n\t\t\n\t\tsocket.setKeepAlive (\n\t\t\t\tspec.getSocketFlag (Connection.Socket.Flag.SO_KEEP_ALIVE));\n\t\t\n\t\tsocket.setPerformancePreferences(\n\t\t\t\tspec.getSocketProperty (SO_PREF_CONN_TIME),\n\t\t\t\tspec.getSocketProperty (SO_PREF_LATENCY),\n\t\t\t\tspec.getSocketProperty (SO_PREF_BANDWIDTH)); \n\n\t\tsocket.setSoTimeout(\n\t\t\t\tspec.getSocketProperty(SO_TIMEOUT));\n\n\t\tif(socket.getSendBufferSize() < spec.getSocketProperty(SO_SNDBUF))\n\t\t\tsocket.setSendBufferSize(spec.getSocketProperty(SO_SNDBUF));\n\t\t\n\t\tif(socket.getReceiveBufferSize() < spec.getSocketProperty(SO_RCVBUF))\n\t\t\tsocket.setReceiveBufferSize(spec.getSocketProperty(SO_RCVBUF));\n\t\t\n\t\tsocket.connect(socketAddress);\n\t\t\n//\t\tLog.log(\"RedisConnection - socket connected to %s:%d\", socketAddress.getHostName(), port);\n\t}\n\n\t/**\n\t * \n\t */\n\tprivate final void socketClose () {\n\t\ttry {\n\t\t\tif(null != socket) socket.close();\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tLog.error(\"[IO] on closeSocketConnect -- socketClose() continues ...\" + e.getLocalizedMessage());\n\t\t}\n\t\tfinally {\n\t\t\tsocket = null;\n\t\t\tinstream = null;\n\t\t\toutstream = null;\n\t\t}\n\t}\n\t\n\t/**\n\t * @throws IllegalStateException if socket is null\n\t * @throws IOException thrown by socket instance stream accessors\n\t */\n\tprotected final void initializeSocketStreams() throws IllegalArgumentException, IOException {\n\t\tinstream = newInputStream (Assert.notNull(socket.getInputStream(), \"socket input stream\", IllegalArgumentException.class));\n\t\tAssert.notNull(instream, \"input stream provided by extended class\", IllegalArgumentException.class);\n\t\toutstream = newOutputStream (Assert.notNull(socket.getOutputStream(), \"socket output stream\", IllegalArgumentException.class));\n\t}\n\t\n\t/**\n\t * @throws RedisException \n\t * @throws ClientRuntimeException \n\t * @throws ProviderException \n     * \n     */\n    protected final void initializeOnConnect () throws ProviderException, ClientRuntimeException, RedisException{\n    \tswitch (spec.getModality()){\n\t\t\tcase Asynchronous:\n\t\t\t\tinitializeAsyncConnection();\n\t\t\t\tbreak;\n\t\t\tcase Synchronous:\n\t\t\t\tinitializeSyncConnection();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new ProviderException(\"Modality \" + spec.getModality().name() + \" is not supported.\");\n    \t}\n    }\n\n    /**\n     * @throws ProviderException\n     * @throws ClientRuntimeException\n     * @throws RedisException\n     */\n    protected final void initializeSyncConnection () throws ProviderException, ClientRuntimeException, RedisException{\n\t\tif(null!=spec.getCredentials()) {\n\t\t\tthis.serviceRequest(Command.AUTH, spec.getCredentials());\n\t\t}\n\t\tif(spec.getDatabase() != 0) {\n\t\t\tthis.serviceRequest(Command.SELECT, Convert.toBytes(spec.getDatabase()));\n\t\t}\n    }\n    /**\n     * @throws ProviderException\n     * @throws ClientRuntimeException\n     * @throws RedisException\n     */\n    protected final void initializeAsyncConnection () throws ProviderException, ClientRuntimeException, RedisException{\n    \ttry {\n    \t\tif(null!=spec.getCredentials()) {\n    \t\t\tthis.queueRequest(Command.AUTH, spec.getCredentials()).get();\n    \t\t}\n    \t\tif(spec.getDatabase() != 0) {\n    \t\t\tthis.queueRequest(Command.SELECT, Convert.toBytes(spec.getDatabase())).get();\n    \t\t}\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n\t        throw new ClientRuntimeException(\"Interrupted while initializing asynchronous connection\", e);\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n\t        if(e.getCause() != null){\n\t        \tif(e.getCause() instanceof RedisException)\n\t        \t\tthrow (RedisException) e.getCause();\n\t        \telse if(e.getCause() instanceof ProviderException)\n\t        \t\tthrow (ProviderException) e.getCause();\n\t        \telse if(e.getCause() instanceof ClientRuntimeException)\n\t        \t\tthrow (ClientRuntimeException) e.getCause();\n\t        }\n\t        throw new ProviderException(\"Exception while initializing asynchronous connection\", e);\n        }\n    }\n\t\n    @SuppressWarnings(\"boxing\")\n\t@Override\n    public String toString() {\n//    \tString selfdesc = String.format(\"%s@%d\", getClass().getSimpleName(), hashCode());\n    \treturn String.format(\"Connection: %-12s %s:%d db:%d | %s@%d\", spec.getModality().name().toUpperCase(), spec.getAddress(), spec.getPort(), spec.getDatabase(), getClass().getSimpleName(), hashCode());\n    }\n\t// ------------------------------------------------------------------------\n\t// Property accessors\n\t// ------------------------------------------------------------------------\n\t\n//\tfinal protected void setProtocolHandler(Protocol protocolHandler) {\n//\t\tnew Exception().printStackTrace();\n//\t\tSystem.out.format(\">>>>>>>>>>> PROTOCOL HANDLER: %s\\n\", protocolHandler);\n//\t\tif(protocolHandler == null) throw new ProviderException(\"protocol handler is null - BUG\");\n//    \tthrdProtocol.set(protocolHandler);\n//\t\tthis.protocol = notNull(protocolHandler, \"protocolHandler for ConnectionBase\", ClientRuntimeException.class);\n//\t}\n\t\n\tfinal protected Protocol getProtocolHandler() {\n\t\tif(thrdProtocol.get() == null) {\n\t\t\tfinal Protocol protocol = Assert.notNull (newProtocolHandler(), \"the delegate protocol handler\", ClientRuntimeException.class);\n\t    \tthrdProtocol.set(protocol);\n\t\t}\n//\t\tSystem.out.format(\"<<<<<<<<<<< PROTOCOL HANDLER: %s\\n\", thrdProtocol.get());\n\t\treturn notNull(thrdProtocol.get(), \"protocolHandler for ConnectionBase\", ClientRuntimeException.class);\n\t}\n\n\tfinal protected OutputStream getOutputStream() {\n\t\treturn outstream;\n\t}\n\n\tfinal protected InputStream getInputStream() {\n\t\treturn instream;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/DefaultConnectionFactory.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport java.security.ProviderException;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.Connection.Flag;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 15, 2010\n * \n */\n\npublic class DefaultConnectionFactory implements Connection.Factory {\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection.Factory#newConnection(org.jredis.connector.ConnectionSpec) */\n    public Connection newConnection (ConnectionSpec spec)\n            throws ClientRuntimeException, NotSupportedException \n    {\n    \tConnection conn = null;\n    \tswitch (spec.getModality()){\n\t\t\tcase Monitor:\n\t\t\t\tthrow new ProviderException(\"NOT IMPLEMENTED!\");\n\t\t\tcase PubSub:\n\t\t\t\tthrow new ProviderException(\"NOT IMPLEMENTED!\");\n\t\t\tcase Asynchronous:\n\t\t\t\tconn = newAsyncConnection(spec);\n\t\t\t\tbreak;\n\t\t\tcase Synchronous:\n\t\t\t\tconn = new SyncConnection(spec);\n\t\t\t\tbreak;\n    \t}\n    \t// TODO: factories create completed products --\n    \t// this class needs to set conn settings for ALL connection types\n    \t// \n//\t\tif(spec.getConnectionFlag(Flag.CONNECT_IMMEDIATELY)) {\n//\t\t\t((ConnectionBase)conn).initialize (); \n//    \t}\n    \t\n\t\tLog.debug(\"Created new %s\", conn);\n\t    return conn;\n    }\n\n\t/**\n\t * Creates a new {@link Connection.Modality#Asynchronous} {@link Connection}\n\t * per {@link ConnectionSpec} settings. \n     * @param spec\n     */\n    private Connection newAsyncConnection (ConnectionSpec spec) {\n\n    \tConnection conn = null;\n    \tif(spec.getConnectionFlag(Flag.PIPELINE)){\n\t\t\tconn = new AsyncPipelineConnection(spec); // why not for all asyncs?\n    \t}\n    \telse {\n    \t\tif(spec.getConnectionFlag(Flag.SHARED)){\n        \t\tthrow new ProviderException(\"NOT IMPLEMENTED! [Asynch|SHARED|not_PIPELINE]\");\n    \t\t}\n    \t\telse {\n    \t\t\tconn = new AsyncConnection(spec);\n//    \t\t\tconn = new AsyncPipelineConnection(spec); // why not for all asyncs?\n    \t\t}\n    \t}\n    \treturn conn;\n    }\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/DefaultConnectionSpec.java",
    "content": "package org.jredis.ri.alphazero.connection;\n\nimport static org.jredis.connector.Connection.Flag.CONNECT_IMMEDIATELY;\nimport static org.jredis.connector.Connection.Flag.PIPELINE;\nimport static org.jredis.connector.Connection.Flag.RELIABLE;\nimport static org.jredis.connector.Connection.Flag.SHARED;\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_BANDWIDTH;\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_CONN_TIME;\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_LATENCY;\nimport static org.jredis.connector.Connection.Socket.Property.SO_RCVBUF;\nimport static org.jredis.connector.Connection.Socket.Property.SO_SNDBUF;\nimport static org.jredis.connector.Connection.Socket.Property.SO_TIMEOUT;\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.Connection.Flag;\nimport org.jredis.connector.Connection.Modality;\nimport org.jredis.ri.alphazero.protocol.DefaultProtocolFactory;\nimport org.jredis.ri.alphazero.support.Assert;\n\n/**\n * Default connection spec provides the following default values for a connection.  See\n * {@link ConnectionSpec} for details of these properties and flags.\n * <p>\n * The default {@link Modality} for the {@link Connection} is {@link Modality#Synchronous}.\n * <p>\n * This {@link ConnectionSpec} is configured to prefer bandwidth and relatively large (48K)\n * buffers (which is probably less than your OS's default buffer sizes anyway, but you never know).\n * <p>\n * Connection Retry limit is {@link DefaultConnectionSpec#DEFAULT_RECONNECT_CNT}.\n * <p>\n * Connection is spec'd for Keep Alive.\n * <p>\n * Socket timeout is {@link DefaultConnectionSpec#DEFAULT_READ_TIMEOUT_MSEC}\n * <p>\n * No codecs and/or compression classes are defined.\n *   \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 20, 2009\n * @since   alpha.0\n * \n */\nfinal public class DefaultConnectionSpec extends ConnectionSpec.RefImpl {\n\t// ------------------------------------------------------------------------\n\t// Consts\n\t// ------------------------------------------------------------------------\n\t\n\tstatic final int DEFAULT_REDIS_PORT = 6379;\n\tstatic final String DEFAULT_REDIS_HOST_NAME = \"localhost\";\n\tstatic final int DEFAULT_REDIS_DB = 0;\n\tstatic final byte[] DEFAULT_REDIS_PASSWORD = null;\n\t\n\t/** def value: <code>48KB</code> */\n\tprivate static final int DEFAULT_RCV_BUFF_SIZE = 1024 * 48;\n\t/** def value: <code>48KB</code> */\n\tprivate static final int DEFAULT_SND_BUFF_SIZE = 1024 * 48;\n\t/** def value: <code>5000 msecs</code> */\n\tstatic final int DEFAULT_READ_TIMEOUT_MSEC = 5000;\n\t\n\t/** def value: <code>1</code> sec. (min timeout in redis conf */\n\tstatic final int DEFAULT_HEARTBEAT_SEC = 1;\n\t\n\t/** def value: <code>0</code> e.g. higher priority pref is bandwidth */\n\tprivate static final int DEFAULT_SO_PREF_BANDWIDTH = 0;\n\t/** def value: <code>1</code> e.g. second priority pref is latency */\n\tprivate static final int DEFAULT_SO_PREF_LATENCY = 1;\n\t/** def value: <code>3</code> e.g. third priority pref is connection time */\n\tprivate static final int DEFAULT_SO_PREF_CONN_TIME = 2;\n\t\n\t/** def value: <code>true</code> */\n\tprivate static final boolean DEFAULT_CF_SHARED = true;\n\t/** def value: <code>false</code> */\n\tprivate static final boolean DEFAULT_CF_RELIABLE = false;\n\t/** def value: <code>false</code> */\n\tprivate static final boolean DEFAULT_CF_PIPELINE = false;\n\t/** def value: <code>true</code> */\n\tprivate static final boolean DEFAULT_CF_CONNECT_IMMEDIATELY = true;\n\t/** def value: <code>true</code> */\n\tprivate static final boolean DEFAULT_CF_STATEFUL = false;\n\t\n\t/** def value: <code>Modality.Synchronous</code> */\n\tprivate static final Modality DEFAULT_CP_CONN_MODALITY = Modality.Synchronous;\n\t/** def value: <code>3</code> */\n\tprivate static final int DEFAULT_CP_MAX_CONNECT_ATTEMPT = 3;\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructors\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Instantiates a default connection spec for the given host and port.\n\t * @param address\n\t * @param port\n\t * @throws ClientRuntimeException for invalid port, or null address values\n\t */\n\tpublic DefaultConnectionSpec () throws ClientRuntimeException {\n//\t\tLog.debug(\"Yo!\");\n\t\tsetDefaultValues();\n\t}\n\t/**\n\t * Instantiates a default connection spec for the given host and port.\n\t * @param address\n\t * @param port\n\t * @throws ClientRuntimeException for invalid port, or null address values\n\t */\n\t@Deprecated\n\tpublic DefaultConnectionSpec (InetAddress address, int port) throws ClientRuntimeException {\n\t\tthis (address, port, 0, null);\n\t}\n\t/**\n\t * Instantiates a default connection spec for the given host and port.\n\t * @param address\n\t * @param port\n\t * @param database\n\t * @param credentials\n\t * @throws ClientRuntimeException for invalid port, or null address values\n\t */\n\t@Deprecated\n\tpublic DefaultConnectionSpec (InetAddress address, int port, int database, byte[] credentials) throws ClientRuntimeException {\n\t\tthis();\n\t\tsetPort(Assert.inRange (port, 1, 65534, \"port init parameter for DefaultConnectionSpec\", ClientRuntimeException.class));\n\t\tsetAddress(Assert.notNull(address, \"address init parameter for DefaultConnectionSpec\", ClientRuntimeException.class));\n\t\tsetDatabase(database);\n\t\tsetCredentials(credentials);\n\t}\n\t/**\n     * Set the default values for the {@link ConnectionSpec}\n     * other properties.\n     * @see ConnectionSpec\n     * @see Connection.Property\n     * @see Connection.Property\n     * @see Connection.Flag\n     * @see Connection.Socket.Flag\n     * @see Connection.Socket.Property\n     * @see DefaultConnectionFactory\n     * @see DefaultProtocolFactory\n     */\n    private void setDefaultValues () {\n//    \t// reconnect try count\n//    \tsetReconnectCnt(DEFAULT_CP_MAX_CONNECT_ATTEMPT);\n    \t\n    \t//  tcp socket flags\n    \tsetSocketFlag(Connection.Socket.Flag.SO_KEEP_ALIVE, true);\n    \t\n    \t// tcp socket flags\n    \tsetSocketProperty(SO_TIMEOUT, DEFAULT_READ_TIMEOUT_MSEC);\n    \tsetSocketProperty(SO_RCVBUF, DEFAULT_RCV_BUFF_SIZE);\n    \tsetSocketProperty(SO_SNDBUF, DEFAULT_SND_BUFF_SIZE);\n    \tsetSocketProperty(SO_PREF_BANDWIDTH, DEFAULT_SO_PREF_BANDWIDTH);\n    \tsetSocketProperty(SO_PREF_CONN_TIME, DEFAULT_SO_PREF_CONN_TIME);\n    \tsetSocketProperty(SO_PREF_LATENCY, DEFAULT_SO_PREF_LATENCY);\n    \t\n    \tsetConnectionFlag(RELIABLE, DEFAULT_CF_RELIABLE);\n    \tsetConnectionFlag(SHARED, DEFAULT_CF_SHARED);\n    \tsetConnectionFlag(PIPELINE, DEFAULT_CF_PIPELINE);\n    \tsetConnectionFlag(CONNECT_IMMEDIATELY, DEFAULT_CF_CONNECT_IMMEDIATELY);\n    \tsetConnectionFlag(Flag.STATEFUL, DEFAULT_CF_STATEFUL);\n    \t\n    \tsetConnectionProperty(Connection.Property.MODALITY, DEFAULT_CP_CONN_MODALITY);\n    \tsetConnectionProperty(Connection.Property.MAX_CONNECT_ATTEMPT, DEFAULT_CP_MAX_CONNECT_ATTEMPT);\n    \tsetConnectionProperty(Connection.Property.PROTOCOL_FACTORY, new DefaultProtocolFactory());\n    \tsetConnectionProperty(Connection.Property.CONNECTION_FACTORY, new DefaultConnectionFactory());\n    \t\n    \tsetHeartbeat(DEFAULT_HEARTBEAT_SEC);\n    }\n\t// ------------------------------------------------------------------------\n\t// Static methods\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @return\n\t * @throws ClientRuntimeException\n\t */\n\tpublic static final ConnectionSpec newSpec () \n\t\tthrows ClientRuntimeException \n\t{\n\t\treturn newSpec (DEFAULT_REDIS_HOST_NAME, DEFAULT_REDIS_PORT, DEFAULT_REDIS_DB, DEFAULT_REDIS_PASSWORD);\n\t}\n\n\t/**\n\t * Returns an instance of the {@link ConnectionSpec} used by this {@link Connection}\n\t * as default spec, for the provided params.\n\t * @param host\n\t * @param port\n\t * @param database\n\t * @param credentials\n\t * @param redisversion\n\t * @return\n\t * @throws ClientRuntimeException\n\t */\n\tpublic static final ConnectionSpec newSpec (\n\t\t\tString \t\t\thost, \n\t\t\tint \t\t\tport, \n\t\t\tint \t\t\tdatabase, \n\t\t\tbyte[] \t\t\tcredentials\n\t\t) \n\t\tthrows ClientRuntimeException \n\t{\n    \tInetAddress address;\n        try {\n\t        address = InetAddress.getByName(host);\n        }\n        catch (UnknownHostException e) {\n        \tthrow new ClientRuntimeException(\"unknown host: \" + host, e);\n        }\n\t\t\n\t\treturn newSpec(address, port, database, credentials);\n\t}\n\t/**\n\t * Returns an instance of the {@link ConnectionSpec} used by this {@link Connection}\n\t * as default spec, for the provided params.\n\t * @param address\n\t * @param port\n\t * @param database\n\t * @param credentials\n\t * @param redisversion\n\t * @return\n\t * @throws ClientRuntimeException\n\t */\n\tpublic static final ConnectionSpec newSpec (\n\t\t\tInetAddress \taddress, \n\t\t\tint \t\t\tport, \n\t\t\tint \t\t\tdatabase, \n\t\t\tbyte[] \t\t\tcredentials\n\t\t) \n\t\tthrows ClientRuntimeException \n\t{\n//\t\treturn new DefaultConnectionSpec(address, port, database, credentials);\n\t\tConnectionSpec spec = new DefaultConnectionSpec();\n\t\treturn spec.setAddress(address).setPort(port).setDatabase(database).setCredentials(credentials);\n\t\t\n\t}\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/HeartbeatJinn.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport java.security.ProviderException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.Connection.Event;\nimport org.jredis.connector.Connection.Modality;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * A demon thread tasked with PINGing the associated connection\n * per its {@link ConnectionSpec#getHeartbeat()} heartbeat interval.\n * <p>\n * {@link HeartbeatJinn}s are {@link Connection.Listener}s, and rely\n * on {@link Connection} event propagation to synchronize their activity\n * with the associated connection.\n * <p>\n * The connection must only call {@link Thread#start()} when it has\n * established its connectivity.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 22, 2009\n * @since   alpha.0\n * \n */\npublic class HeartbeatJinn extends Thread implements Connection.Listener{\n\n\t/**  */\n\tAtomicBoolean connected;\n\t/**  */\n\tAtomicBoolean mustBeat;\n\t/**  */\n\tprivate final Modality modality;\n\t/**  */\n\tprivate final Connection conn;\n\t/**  */\n\tprivate final int period;\n\t\n\t/**\n\t * Instantiate and initialize the HeartbeatJinn.  On return, this instance\n\t * is:\n\t * <li> sets flag to work\n\t * <li> added to the listeners for the connection\n\t * <li> assumes connection is not yet established\n\t * \n\t * @param conn associated with this instnace\n\t * @param periodInSecs a reasonable value is 1.  Internally converted to millisecs.\n\t * @param name associated with this (heartbeat) thread.\n\t */\n\tpublic HeartbeatJinn (Connection conn, int periodInSecs, String name) {\n\t\tsuper (name);\n\t\tsetDaemon(true);\n\t\tthis.conn = conn;\n\t\tconn.addListener(this);\n\t\tthis.modality = conn.getSpec().getModality();\n\t\tthis.period = periodInSecs * 1000;\n\t\tthis.connected = new AtomicBoolean(false);\n\t\tthis.mustBeat = new AtomicBoolean(true);\n\t}\n\n\t/**\n\t * \n\t */\n\tpublic void shutdown() {\n\t\tmustBeat.set(false);\n\t\tthis.interrupt();\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// INTERFACE\n\t/* ====================================================== Thread (Runnable)\n\t * \n\t */\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * Your basic infinite loop with branchings on connection state and modality\n\t * <p>\n\t * TODO: run loop should be a proper state machine.\n\t * TODO: delouse this baby ..\n\t * \n\t * @see java.lang.Thread#run()\n\t */\n\tpublic void run () {\n//\t\tif (conn.getSpec().getLogLevel()==ConnectionSpec.LogLevel.DEBUG)\n\t\tLog.debug(\"HeartbeatJinn thread <%s> started.\", Thread.currentThread().getName());\n\t\t\n\t\twhile (mustBeat.get()) {\n\t\t\ttry {\n\t\t\t\tif(connected.get()){  // << buggy: quit needs to propagate down here.\n\t\t\t\t\tResponse response = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tswitch (modality){\n\t\t\t\t\t\tcase Asynchronous:\n\t\t\t\t\t\t\tFuture<Response> fResponse = conn.queueRequest(Command.PING);\n\t\t\t\t\t\t\tresponse = fResponse.get();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase Synchronous:\n\t\t\t\t\t\t\tresponse = conn.serviceRequest(Command.PING);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase Monitor:\n\t\t\t\t\t\tcase PubSub:\n\t\t\t\t\t\t\tthrow new ProviderException(String.format(\"%s connector not supported\", modality.name()));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!response.isError()){ \n//\t\t\t\t\t\t\tif(conn.getSpec().getLogLevel().equals(LogLevel.DEBUG))\n\t\t\t\t\t\t\tLog.debug (String.format(\"<%s> is alive\", conn)); \n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tString errmsg = String.format(\"Error response on PING: %s\", response.getStatus().toString());\n\t\t\t\t\t\t\tLog.error(errmsg);\n\t\t\t\t\t\t\tthrow new ClientRuntimeException(errmsg);  // NOTE: can't be sure this is a protocol BUG .. so CRE instead\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception e) {\n\t\t\t\t\t\t// addressing buggy above.  notifyDisconnected gets called after we have checked it but before we\n\t\t\t\t\t\t// made the call - it is disconnected by the time the call is made and we end up here\n\t\t\t\t\t\t// checking the flag again and if it is indeed not the above scenario then there is something wrong,\n\t\t\t\t\t\t// otherwise ignore it and basically loop on sleep until we get notify on connect again (if ever).\n\t\t\t\t\t\tif(connected.get()){\n\t\t\t\t\t\t\t// how now brown cow?  we'll log it for now and assume reconnect try in progress and wait for the flag change.\n\t\t\t\t\t\t\tLog.problem(\"HeartbeatJinn thread <\" + Thread.currentThread().getName() + \"> encountered exception on PING: \" + e.getMessage() );\n//\t\t\t\t\t\t\tconnected.set(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n//\t\t\t\tLog.debug(\"Looping : <%s>\", conn);\n\t\t\t\tsleep (period);\t// sleep regardless - \n\t\t\t}\n\t\t\tcatch (InterruptedException e) { \n//\t\t\t\tif (conn.getSpec().getLogLevel()==ConnectionSpec.LogLevel.DEBUG)\n\t\t\t\tLog.debug (\"HeartbeatJinn thread <%s> interrupted.\", Thread.currentThread().getName());\n\t\t\t\tbreak; \n\t\t\t}\n\t\t}\n\t\tLog.log(\"HeartbeatJinn thread <%s> stopped.\", Thread.currentThread().getName());\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// INTERFACE\n\t/* =================================================== Connection.Listener\n\t * \n\t * hooks for integrating the heartbeat thread's state with the associated\n\t * connection's state through event callbacks. \n\t */\n\t// ------------------------------------------------------------------------\n\t/**\n\t * \n     * @see org.jredis.connector.Connection.Listener#onEvent(org.jredis.connector.Connection.Event)\n     */\n\t// TODO: let's hook this up.\n    public void onEvent (Event event) {\n//\t\tif (conn.getSpec().getLogLevel()==ConnectionSpec.LogLevel.DEBUG)\n\t\tLog.debug(\"onEvent %s : <%s>\", event.getType().name(), this);\n\t\t\n    \tswitch (event.getType()){\n\t\t\tcase CONNECTING:\n\t\t\t\tbreak;\n\t\t\tcase CONNECTED:\n\t\t\t\tconnected.set(true);\n\t\t\t\tbreak;\n\t\t\tcase DISCONNECTING:\n\t\t\tcase DISCONNECTED:\n\t\t\t\tconnected.set(false);\n\t\t\t\tbreak;\n\t\t\tcase FAULTED:\n//\t\t\t\tshutdown();  // REVU: this is wrong.\n\t\t\t\tbreak;\n\t\t\tcase SHUTDOWN:\n\t\t\t\tshutdown();\n\t\t\t\tbreak;\n//\t\t\tcase STOPPING:\n//\t\t\t\tbreak;\n    \t}\n    }\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/PendingRequest.java",
    "content": "/*\n *   Copyright 2009-2011 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Request;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.support.Signal;\n\n/**\n * An implementation of {@link Future} for parameteric <code>T</code> type {@link Response}\n * used for processing of pipelined responses from the server.\n * <p>\n * Note that this implementation does NOT support canceling of {@link Request}s.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Sep 7, 2009\n * @since   alpha.0\n * \n */\npublic class PendingRequest implements Future<Response> {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/** Used to signal completion of the request */\n//\tfinal private BooleanLatch completion = new BooleanLatch();\n\tfinal Signal completion = new Signal();\n\n\t/** awaited response */\n\tResponse response;\n\n\t/** Pending command */\n\tfinal Command cmd;\n\n\t/** true if response processor encountered exceptions */\n\tprivate boolean excepted = false;\n\t\n\t/** if {@link PendingRequest#excepted} is true, this will be set to the cause. */\n\tprivate ClientRuntimeException cre = null;\n\t\n\tfinal byte[][] args;\n\t// ------------------------------------------------------------------------\n\t// constructor(s)\n\t// ------------------------------------------------------------------------\n\tpublic PendingRequest(Command cmd){\n\t\tthis.cmd = cmd;\n\t\tthis.args = null;\n\t}\n\t\n\tpublic PendingRequest(Command cmd, byte[]... args){\n\t\tthis.cmd = cmd;\n\t\tthis.args = args;\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// package scoped methods used by request processors\n\t// ------------------------------------------------------------------------\n\tfinal Command getCommand () {\n\t\treturn cmd;\n\t}\n\n\t/**\n\t * Signals completion without error.\n\t * <p>\n\t * Sets the response, which also signals the completion of this {@link Future} \n\t * object.  When this method is invoked, a call to {@link PendingRequest#get()}\n\t * will immediately return with the response.\n\t * @param response\n\t */\n\tfinal void setResponse(Response response){\n\t\tthis.response = response;\n\t\tthis.completion.signal();\n\t}\n\n\t/**\n\t * Signals completion with error -- response will be null\n\t * @param cre\n\t */\n\tfinal void setCRE (ClientRuntimeException cre){\n\t\tthis.cre = cre;\n\t\texcepted = true;\n\t\tsetResponse(null);\n//\t\tthis.completion.signal();\n\t}\n\t\n\t\n\t/**\n\t * Determines if a completed request encountered errors and will throw an {@link ExecutionException} wrapping \n\t * the original cause.  Called by the {@link PendingRequest#get} methods.\n\t * @throws ExecutionException\n\t */\n\tprivate final void checkStatus () throws ExecutionException \n\t{\n\t\t// check for runtime or provider exceptions\n\t\tif(excepted) {\n\t\t\tif(cre != null) {\n\t\t\t\tif(cre instanceof ProviderException)\n\t\t\t\t\tthrow new ExecutionException (\"Provider Exception\", cre);\n\t\t\t\telse\n\t\t\t\t\tthrow new ExecutionException (\"Client Runtime Exception\", cre);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new ExecutionException (\"Bug -- Request processing encountered exceptions but CRE is null\", new ProviderException(\"unknown cause\"));\n\t\t\t}\n\t\t}\n\t\t// check for Redis Errors\n\t\tif(response.isError())\n\t\t\tthrow new ExecutionException(\"Redis Exception on [\"+cmd.name()+\"] \" + response.getStatus().message(), new RedisException(cmd, response.getStatus().message()));\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface: Future<Response>\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc) @see java.util.concurrent.Future#get() */\n\t@Override\n\tpublic Response get () throws InterruptedException, ExecutionException {\n\t\tcompletion.await();\n\n\t\tcheckStatus();\n\t\treturn response;\n\t}\n\n\t/* (non-Javadoc) @see java.util.concurrent.Future#get(long, java.util.concurrent.TimeUnit) */\n\t@Override\n\tpublic Response get (long timeout, TimeUnit unit)\n\tthrows InterruptedException, ExecutionException, TimeoutException \n\t{\n\t\tif(!completion.await(timeout, unit))\n\t\t\tthrow new TimeoutException();\n\t\t\n\t\tcheckStatus();\n\t\treturn response;\n\t}\n\n\t/**  \n\t * Pipeline does not support canceling of requests -- will always return false.\n\t * @see java.util.concurrent.Future#cancel(boolean) \n\t */\n\t@Override\n\tpublic boolean cancel (boolean mayInterruptIfRunning) { return false; }\n\n\t/**  \n\t * Pipeline does not support canceling of requests -- will always return false.\n\t * @see PendingRequest#cancel(boolean)\n\t * @see java.util.concurrent.Future#isCancelled()\n\t */\n\t@Override\n\tpublic boolean isCancelled () { return false; }\n\n\n\t/* (non-Javadoc) @see java.util.concurrent.Future#isDone() */\n\t@Override\n\tpublic boolean isDone () { \n\t\treturn completion.isSignalled(); \n\t}\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/PipelineConnectionBase.java",
    "content": "/*\n *   Copyright 2009-2011 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport java.io.InputStream;\nimport java.util.NoSuchElementException;\nimport java.util.Queue;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.NotConnectedException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Request;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.protocol.ConcurrentSyncProtocol;\nimport org.jredis.ri.alphazero.protocol.VirtualResponse;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.FastBufferedInputStream;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * Abstract base for all Pipeline connections, providing basically all of the\n * required functionality for a pipeline with asynchronous semantics.  \n * \n * Synchronous pipelines can simply call\n * the {@link PipelineConnectionBase#queueRequest(Command, byte[])} method\n * in their implementation of the synchronous {@link Connection#serviceRequest(Command, byte[])} \n * method and block on {@link Future#get()} to realize the blocking semantics \n * and results required.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Sep 7, 2009\n * @since   alpha.0\n * \n */\n\npublic abstract class PipelineConnectionBase extends ConnectionBase {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/**  */\n\tprivate ResponseHandler\t    \trespHandler;\n\n\t/**  */\n\tprivate Thread \t\t\t\t\trespHandlerThread;\n\n\t/**  */\n\tBlockingQueue<PendingRequest>\tpendingResponseQueue;\n\n\t/** synchronization object used to serialize request queuing  */\n\tprivate Object\t\t\t\t\tserviceLock = new Object();\n\t\n\t/** \n\t * flag (default false) indicates if a pending QUIT command is being processed.  \n\t * If true, any calls to queueRequests will result in a raise runtime exception\n\t */\n\tprivate boolean\t\t\t\t\tpendingQuit = false;\n\t\n\t/** used by the Pipeline to indicate its state.  Set to true on connect and false on Quit/Close */\n\tprivate AtomicBoolean\t\t\tisActive;\n\t\n\t/** counted down on notifyConnect */\n\tprivate CountDownLatch\t\t    connectionEstablished;\n\n\t// ------------------------------------------------------------------------\n\t// Constructor(s)\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @param spec\n\t * @throws ClientRuntimeException\n\t */\n\tprotected PipelineConnectionBase (ConnectionSpec spec) throws ClientRuntimeException {\n\t\tsuper(spec);\n\t}\n\t// ------------------------------------------------------------------------\n\t// Extension\n\t// ------------------------------------------------------------------------\n\t/**\n     * \n     */\n    @SuppressWarnings(\"boxing\")\n\t@Override\n    protected void initializeComponents () {\n    \t\n    \tspec.setConnectionFlag(Flag.PIPELINE, true);\n    \tspec.setConnectionFlag(Flag.RELIABLE, true);\n    \tspec.setConnectionFlag(Flag.SHARED, true);\n    \t\n    \tsuper.initializeComponents();\n    \t\n    \tserviceLock = new Object();\n    \tisActive = new AtomicBoolean(false);\n    \tconnectionEstablished = new CountDownLatch(1);\n    \t\n    \tpendingResponseQueue = new LinkedBlockingQueue<PendingRequest>();\n    \trespHandler = new ResponseHandler();\n    \trespHandlerThread = new Thread(respHandler, \"response-handler\");\n    \trespHandlerThread.start();\n    \t\n    \tisActive.set(false);\n    }\n    \n    @Override\n    protected void notifyConnected () {\n    \tsuper.notifyConnected();\n\t\tLog.log(\"Pipeline <%s> connected\", this);\n    \tisActive.set(true);\n    \tconnectionEstablished.countDown();\n    }\n    @Override\n    protected void notifyDisconnected () {\n    \tsuper.notifyDisconnected();\n\t\tLog.log(\"Pipeline <%s> disconnected\", this);\n    \tisActive.set(true);\n    \tconnectionEstablished.countDown();\n    }\n   \n    /**\n     * Pipeline must use a concurrent protocol handler.\n     *  \n     * @see org.jredis.ri.alphazero.connection.ConnectionBase#newProtocolHandler()\n     */\n    @Override\n    protected Protocol newProtocolHandler () {\n\t\treturn new ConcurrentSyncProtocol();\n//\t\treturn new SynchProtocol();\n    }\n\n    // TODO: write chunking + mod ProtocolBase.Stream...Request + Command.FLUSH_BUFFERS.\n//    @Override\n//    protected OutputStream newOutputStream(OutputStream socketOutputStream) {\n//    \treturn new BufferedOutputStream(socketOutputStream);\n//    }\n\n    /**\n     * Just make sure its a {@link FastBufferedInputStream}.\n     */\n    @SuppressWarnings(\"boxing\")\n\t@Override\n\tprotected final InputStream newInputStream (InputStream socketInputStream) throws IllegalArgumentException {\n    \t\n    \tInputStream in = super.newInputStream(socketInputStream);\n    \tif(!(in instanceof FastBufferedInputStream)){\n    \t\tSystem.out.format(\"WARN: input was: %s\\n\", in.getClass().getCanonicalName());\n    \t\tin = new FastBufferedInputStream (in, spec.getSocketProperty(Connection.Socket.Property.SO_RCVBUF));\n    \t}\n    \treturn in;\n    }\n\n    // ------------------------------------------------------------------------\n\t// Interface: Connection\n\t// ------------------------------------------------------------------------\n    /**\n     * This is a pseudo asynchronous method.  The actual write to server does \n     * occur in this method, so when this method returns, your request has been\n     * sent.  This simply defers the response read to the response handler.\n     * <p>\n     * Other item of note is that once a QUIT request has been queued, no further\n     * requests are accepted and a ClientRuntimeException is thrown.\n     * \n     * @see org.jredis.ri.alphazero.connection.ConnectionBase#queueRequest(org.jredis.protocol.Command, byte[][])\n     */\n    @Override\n    public final Future<Response> queueRequest (Command cmd, byte[]... args) \n    \tthrows ClientRuntimeException, ProviderException \n    {\n\t\tif(!isConnected()) \n\t\t\tthrow new NotConnectedException (\"Not connected!\");\n\t\t\n\t\tif(pendingQuit) \n\t\t\tthrow new ClientRuntimeException(\"Pipeline shutting down: Quit in progess; no further requests are accepted.\");\n\t\t\n\t\tProtocol\t\tprotocol = Assert.notNull(getProtocolHandler(), \"thread protocol handler\", ProviderException.class);\n\t\tRequest \t\trequest = Assert.notNull(protocol.createRequest (cmd, args), \"request object from handler\", ProviderException.class);\n\t\tPendingRequest \tpendingResponse = new PendingRequest(cmd);\n\t\t\n\t\tif(cmd == Command.CONN_FLUSH) {\n\t\t\tLog.log(\"%s not supported -- ignored\", cmd.code);\n\t\t\treturn pendingResponse;\n\t\t}\n\t\t\n\t\tsynchronized (serviceLock) {\n\t\t\t\n\t\t\tif(cmd != Command.QUIT) {\n\t\t\t\trequest.write(getOutputStream());\n\t\t\t}\n\t\t\telse {\n\t\t\t\tpendingQuit = true;\n\t\t\t\tisActive.set(false);\n\t\t\t}\n\t\t\t\t\n\t\t\tpendingResponseQueue.add(pendingResponse);\n\t\t}\n\t\treturn pendingResponse;\n    }\n\n    void onResponseHandlerError (ClientRuntimeException cre, PendingRequest request) {\n    \tLog.error(\"Pipeline response handler encountered an error: \" + cre.getMessage());\n    \t\n    \t// signal fault\n    \tonConnectionFault(cre.getMessage(), false);\n    \t\n    \t// set execution error for future object\n    \trequest.setCRE(cre);\n    \t\n\t\t// BEST:\n\t\t// 1 - block the request phase\n\t\t// 2 - try reconnect\n\t\t// 3-ok: \t\treconnected, resume processing\n\t\t// 2-not ok: \tclose shop, and set all pending responses to error\n    \t\n\t\t// for now .. flush the remaining pending responses from queue\n    \t// with execution error\n    \t//\n\t\tPendingRequest pending = null;\n\t\twhile(true){\n\t\t\ttry {\n\t\t\t\tpending = pendingResponseQueue.remove();\n\t\t\t\tpending.setCRE(cre);\n\t\t\t\tLog.error(\"set pending %s response to error with CRE\", pending.cmd);\n\t\t\t}\n\t\t\tcatch (NoSuchElementException empty){ break; }\n\t\t}\n    }\n\t// ------------------------------------------------------------------------\n\t// Inner Class\n\t// ------------------------------------------------------------------------\n    /**\n     * Provides the response processing logic as a {@link Runnable}.\n     * <p>\n     * TODD: Needs to have a more regulated operating cycle.  Right now its just\n     * infinite loop until something goes boom.  Not good.\n     * \n     * @author  Joubin Houshyar (alphazero@sensesay.net)\n     * @version alpha.0, Oct 18, 2009\n     * @since   alpha.0\n     * \n     */\n    public final class ResponseHandler implements Runnable, Connection.Listener {\n\n    \tprivate final AtomicBoolean work_flag;\n    \tprivate final AtomicBoolean alive_flag;\n    \tprivate final AtomicReference<Thread> thread;\n    \t\n    \t// ------------------------------------------------------------------------\n    \t// Constructor\n    \t// ------------------------------------------------------------------------\n    \t\n    \t/**\n         * Adds self to the listeners of the enclosing {@link Connection} instance.\n         */\n        public ResponseHandler () {\n        \tPipelineConnectionBase.this.addListener(this);\n        \tthis.work_flag = new AtomicBoolean(true); \n        \tthis.alive_flag = new AtomicBoolean(false);\n        \tthis.thread = new AtomicReference<Thread>(null);\n        } \n        \n    \t// ------------------------------------------------------------------------\n    \t// INTERFACE\n    \t/* ====================================================== Thread (Runnable)\n    \t * \n    \t */\n    \t// ------------------------------------------------------------------------\n    \t/**\n    \t * Keeps processing the {@link PendingRequest}s in the pending {@link Queue}\n\t\t * until a QUIT is encountered in the pending queue.  Thread will stop after\n\t\t * processing the QUIT response (which is expected to be a {@link VirtualResponse}.\n    \t * <p>\n    \t * TODO: not entirely clear what is the best way to handle exceptions.\n    \t * <p>\n    \t * TODO: socket Reconnect in the context of pipelining is non-trivial, and maybe\n    \t * not even practically possible.  (e.g. request n is sent but pipe breaks on\n    \t * some m (m!=n) response.  non trivial.  Perhaps its best to assume broken connection\n    \t * means faulted server, specially given the fact that a pipeline has a heartbeat\n    \t * so the issue can not be timeout.\n    \t */\n        @Override\n        public void run () {\n        \tthread.compareAndSet(null, Thread.currentThread());\n        \talive_flag.compareAndSet(false, true);\n        \t/** Response handler thread specific protocol handler -- optimize fencing */\n        \tProtocol protocol = Assert.notNull (newProtocolHandler(), \"the delegate protocol handler\", ClientRuntimeException.class);\n        \t\n\t\t\tLog.log(\"Pipeline <%s> thread for <%s> started.\", Thread.currentThread().getName(), PipelineConnectionBase.this.toString());\n        \tPendingRequest pending = null;\n        \twhile(work_flag.get()){\n        \t\tResponse response = null;\n\t\t\t\ttry {\n\t                pending = pendingResponseQueue.take();\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresponse = protocol.createResponse(pending.cmd);\n\t\t\t\t\t\tresponse.read(getInputStream());\n\t\t\t\t\t\tpending.response = response;\n\t\t\t\t\t\tpending.completion.signal();\n\t\t\t\t\t\tif(response.getStatus().isError()) {\n\t\t\t\t\t\t\tLog.error (\"(Asynch) Error response for \" + pending.cmd.code + \" => \" + response.getStatus().message());\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// this exception handling as of now is basically broken and fairly useless\n\t\t\t\t\t// really, what we want is making a distinction between bugs and runtime problems\n\t\t\t\t\t// and in case of connection issues, signal the retry mechanism.\n\t\t\t\t\t// in the interim, all incoming requests must be rejected (e.g. PipelineReconnecting ...)\n\t\t\t\t\t// and all remaining pending responses must be set to error.\n\t\t\t\t\t// major TODO\n\t\t\t\t\t\n\t\t\t\t\tcatch (ProviderException bug){\n\t\t\t\t\t\tLog.bug (\"ProviderException: \" + bug.getMessage());\n\t\t\t\t\t\tonResponseHandlerError(bug, pending);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (ClientRuntimeException cre) {\n\t\t\t\t\t\tLog.problem (\"ClientRuntimeException: \" + cre.getMessage());\n\t\t\t\t\t\tonResponseHandlerError(cre, pending);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RuntimeException e){\n\t\t\t\t\t\tLog.problem (\"Unexpected (and not handled) RuntimeException: \" + e.getMessage());\n\t\t\t\t\t\tonResponseHandlerError(new ClientRuntimeException(\"Unexpected (and not handled) RuntimeException\", e), pending);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// redis (1.00) simply shutsdown connection even if pending responses\n\t\t\t\t\t// are expected, so quit is NOT sent.  we simply close connection on this\n\t\t\t\t\t// end. \n\t\t\t\t\tif(pending.cmd == Command.QUIT) {\n\t\t\t\t\t\tPipelineConnectionBase.this.disconnect();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n                }\n                catch (InterruptedException e1) {\n                  Log.log(\"Pipeline thread interrupted.\");\n                  break;\n\t                //e1.printStackTrace();\n                }\n        \t}\n\t\t\tLog.log(\"Pipeline <%s> thread for <%s> stopped.\", Thread.currentThread().getName(), PipelineConnectionBase.this);\n\t\t\talive_flag.compareAndSet(true, false);\n        }\n\n        final private void stopHandler() {\n        \tLog.log(\"%s stopping handler thread\", this);\n        \twork_flag.set(false);\n        \tthread.get().interrupt();\n//        \tPipelineConnectionBase.this.respHandlerThread.interrupt();\n        }\n        final private void shutdownHandler() {\n        \t/*\n        \t * It is not expected that shutdown would get called before\n        \t * stop, but if it has, this makes sure we first go through\n        \t * the stop sequence.\n        \t */\n        \tif(work_flag.get() != false || alive_flag.get() != false)\n        \t\tstopHandler();\n        \talive_flag.set(false);\n\t\t\tPipelineConnectionBase.this.removeListener(this);\n        \tLog.log(\"%s response handler has shutdown\", this);\n        }\n    \t// ------------------------------------------------------------------------\n    \t// INTERFACE\n    \t/* =================================================== Connection.Listener\n    \t * \n    \t * hooks for integrating the response handler thread's state with the \n    \t * wrapping connection's state through event callbacks. \n    \t */\n    \t// ------------------------------------------------------------------------\n        \n\t\t/**\n\t\t * Needs to be hooked up.\n\t\t * TODO: zood tond foree saree!\n\t\t * \n         * @see org.jredis.connector.Connection.Listener#onEvent(org.jredis.connector.Connection.Event)\n         */\n        @Override\n        public void onEvent (Event event) {\n        \tif(event.getSource() != PipelineConnectionBase.this) {\n        \t\tLog.bug(\"event source [%s] is not this pipeline [%s]\", event.getSource(), PipelineConnectionBase.this);\n        \t\t// BUG: what to do about it?\n        \t}\n//        \t(new Exception()).printStackTrace();\n        \tLog.log(\"Pipeline.ResponseHandler: onEvent %s source: %s\", event.getType().name(), event.getSource());\n        \tswitch (event.getType()){\n\t\t\t\tcase CONNECTED:\n\t\t\t\t\t// (re)start\n\t\t\t\t\tbreak;\n\t\t\t\tcase DISCONNECTED:\n\t\t\t\t\t// should be stopped now\n\t\t\t\t\t//\n//\t\t\t\t\tbreak;\n\t\t\t\tcase CONNECTING:\n\t\t\t\t\t// no op\n\t\t\t\t\tbreak;\n\t\t\t\tcase FAULTED:\n\t\t\t\tcase DISCONNECTING:\n\t\t\t\t\tstopHandler();\n\t\t\t\t\tbreak;\n\t\t\t\tcase SHUTDOWN:\n\t\t\t\t\tshutdownHandler();\n\t\t\t\t\tbreak;\n        \t}\n        }\n    }\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/SyncConnection.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionReset;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.connector.NotConnectedException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Request;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Log;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 10, 2009\n * @since   alpha.0\n * \n */\npublic class SyncConnection extends ConnectionBase implements Connection {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t\n\tfinal private Lock lock;\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructors\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * This constructor will pass the connection spec to the super class constructor and\n\t * create and install the {@link Protocol} handler delegate instance for this {@link SyncConnection}.\n\t * If you definitely need to specify the redis server version, and the protocol implementation for that\n\t * version exists, you should use this constructor.  Otherwise, it is recommended that the \n\t * {@link SyncConnection#SyncConnection(ConnectionSpec)}be used.\n\t * <p>\n\t * This constructor will open the socket connection immediately. \n\t *  \n\t * @param connectionSpec\n\t * @param redisversion\n\t * @throws ClientRuntimeException due to either dns (host connectivity) or any IO issues related to establishing \n\t * the socket connection to the specified server.\n\t * @throws ProviderException if the version specified is not supported.\n\t */\n\tpublic SyncConnection (\n\t\t\tConnectionSpec  connectionSpec\n\t\t)\n\t\tthrows ClientRuntimeException, ProviderException \n\t{\n\t\tsuper (connectionSpec.setModality(Modality.Synchronous));\n\t\t// REVU: huge flaw.  connection initialization occurs in constructor!!! stupid.\n\t\t// TODO: change it.\n\t\tif(spec.getConnectionFlag(Flag.RELIABLE))\n\t\t\tlock = new ReentrantLock(false);\n\t\telse{\n\t\t\tlock = null;\n\t\t\tspec.getConnectionFlag(Flag.RELIABLE);\n\t\t}\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ======================================================= ProtocolHandler\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc)\n\t * @see org.jredis.connector.Connection#getModality()\n\t */\n\t// TODO: restore this\n//\t@Override\n\tpublic final Modality getModality() {\n\t\treturn Connection.Modality.Synchronous;\n\t}\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.ri.alphazero.connection.ConnectionBase#serviceRequest(org.jredis.protocol.Command, byte[][])\n\t */\n\t@Override\n\tpublic Response serviceRequest (Command cmd, byte[]... args) \n\t\tthrows RedisException\n\t{\n\t\tif(!isConnected()) throw new NotConnectedException (\"Not connected!\");\n\t\t\n\t\tRequest  \t\trequest = null;\n\t\tResponse\t\tresponse = null;\n\t\tResponseStatus  status = null;\n\t\tProtocol\t\tprotocol = Assert.notNull(getProtocolHandler(), \"thread protocol handler\", ProviderException.class);\n\n\t\ttry {\n\t\t\t// 1 - Request\n\t\t\t//\t\t\t\tLog.log(\"RedisConnection - requesting ...\" + cmd.code);\n\t\t\t\n\t\t\trequest = Assert.notNull(protocol.createRequest (cmd, args), \"request object from handler\", ProviderException.class);\n\t\t\trequest.write(super.getOutputStream());\n\n\t\t\t// 2 - response\n\t\t\t//\t\t\t\tLog.log(\"RedisConnection - read response ...\" + cmd.code);\n\t\t\tresponse = Assert.notNull(protocol.createResponse(cmd), \"response object from handler\", ProviderException.class);\n\t\t\tresponse.read(super.getInputStream());\n\n\t\t\t//\t\t\t\tbreak;\n\t\t}\n\t\tcatch (ProviderException bug){\n\t\t\tLog.bug (\"serviceRequest() -- ProviderException: \" + bug.getLocalizedMessage());\n\t\t\tLog.log (\"serviceRequest() -- closing connection ...\");\n\t\t\tdisconnect();\n\t\t\tthrow bug;\n\t\t}\n\t\tcatch (ClientRuntimeException cre) {\n\t\t\tLog.problem (\"serviceRequest() -- ClientRuntimeException  => \" + cre.getLocalizedMessage());\n\t\t\treconnect();\n\t\t\t\n\t\t\tthrow new ConnectionReset (\"Connection re-established but last request not processed:  \" + cre.getLocalizedMessage());\n\t\t}\n\t\tcatch (RuntimeException e){\n\t\t\te.printStackTrace();\n\t\t\tLog.bug (\"serviceRequest() -- *unexpected* RuntimeException: \" + e.getLocalizedMessage());\n\n\t\t\tLog.log (\"serviceRequest() -- closing connection ...\");\n\t\t\tdisconnect();\n\n\t\t\tthrow new ClientRuntimeException(\"unexpected runtime exeption: \" + e.getLocalizedMessage(), e);\n\t\t}\n\t\t// 3 - Status\n\t\t//\n\t\tstatus = Assert.notNull (response.getStatus(), \"status from response object\", ProviderException.class);\n\t\tif(status.isError()) {\n\t\t\tLog.error (\"Error response for \" + cmd.code + \" => \" + status.message());\n\t\t\tthrow new RedisException(cmd, status.message());\n\t\t}\n\t\telse if(status.code() == ResponseStatus.Code.CIAO) {\n\t\t\t// normal for quit and shutdown commands.  we disconnect too.\n\t\t\tdisconnect();\n\t\t}\n\n\t\treturn response;\n\t}\n\t@SuppressWarnings(\"unused\")\n    private Lock acquireLock() {\n\t\tlock.lock();\n\t\treturn lock;\n\t}\n\t@SuppressWarnings(\"unused\")\n    private void releaseLock() {\n\t\tlock.unlock();\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/SyncPipelineConnection.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * Synchronous {@link PipelineConnectionBase} extension.\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Sep 7, 2009\n * @since   alpha.0\n * \n */\n\npublic class SyncPipelineConnection extends PipelineConnectionBase {\n\n    // ------------------------------------------------------------------------\n    // Properties\n    // ------------------------------------------------------------------------\n    // ------------------------------------------------------------------------\n    // Constructor(s)\n    // ------------------------------------------------------------------------\n\t/**\n     * @param spec\n     * @throws ClientRuntimeException\n     */\n    public SyncPipelineConnection (ConnectionSpec spec) throws ClientRuntimeException {\n\t    super(spec.setModality(Modality.Synchronous));\n    }\n\n    // ------------------------------------------------------------------------\n    // Interface : Connection\n    // ------------------------------------------------------------------------\n    \n\t/* (non-Javadoc)\n     * @see org.jredis.ri.alphazero.connection.ConnectionBase#serviceRequest(org.jredis.protocol.Command, byte[][])\n     */\n    @Override\n    public Response serviceRequest (Command cmd, byte[]... args)\n            throws RedisException, ClientRuntimeException, ProviderException \n    {\n\n    \t// queue the request\n    \t//\n    \tFuture<Response> pendingResponse = queueRequest(cmd, args);\n    \t\n    \t// wait for response\n    \t//\n    \tResponse response;\n        try {\n        \t// This will block.\n\t        response = pendingResponse.get();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n\t        throw new ClientRuntimeException(\"on pendingResponse.get()\", e);\n        }\n        catch (ExecutionException e) {\n        \tif(e.getCause() instanceof RedisException) {\n        \t\tthrow (RedisException) e.getCause();\n        \t}\n        \telse {\n\t\t        e.printStackTrace();\n\t\t        throw new ProviderException(\"on pendingResponse.get()\", e);\n        \t}\n        }\n    \t\n        // check response status\n        //\n\t\tResponseStatus status = Assert.notNull (response.getStatus(), \"status from response object\", ProviderException.class);\n\t\tif(status.isError()) {\n\t\t\tLog.error (\"Error response for \" + cmd.code + \" => \" + status.message());\n\t\t\tthrow new RedisException(cmd, status.message());\n\t\t}\n\t\t/* this is handled by the super class */\n//\t\telse if(status.code() == ResponseStatus.Code.CIAO) {\n//\t\t\t// normal for quit and shutdown commands.  we disconnect too.\n//\t\t\tdisconnect();\n//\t\t}\n\n\t\treturn response;\n    }\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/connection/UnexpectedEOFException.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.connection;\n\nimport org.jredis.connector.ConnectionException;\nimport org.jredis.ri.alphazero._specification;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 15, 2009\n * @since   alpha.0\n * \n */\n\npublic class UnexpectedEOFException extends ConnectionException {\n\t/**\n\t * @param msg\n\t * @param e\n\t */\n\tpublic UnexpectedEOFException(String msg) {\n\t\tsuper(msg);\n\t}\n\n\t/**  */\n\tprivate static final long serialVersionUID = _specification.Version.major;\n\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * This package and child packages contain reference implementation alphazero\n * of the {@link org.jredis.JRedis} and {@link org.jredis.connector.Connection}\n * of the optional Connector specifications.\n */\npackage org.jredis.ri.alphazero;"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/protocol/ConcurrentSyncProtocol.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.protocol;\n\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\n\n/**\n * This basically extends {@link SyncProtocol} so that the response buffers\n * are not shared, so that it can be used in multi-threaded environments. \n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, Apr 23, 2009\n * @since   alpha.0\n * \n */\n\npublic class ConcurrentSyncProtocol extends SyncProtocol {\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t\n\t// ------------------------------------------------------------------------\n\t// Super Extensions\n\t// ------------------------------------------------------------------------\n\n//\t@Override\n//\tprotected ByteArrayOutputStream createRequestBufffer(Command cmd) {\n//\t\treturn new ByteArrayOutputStream (PREFERRED_REQUEST_BUFFER_SIZE);\n//\t}\n//\t\n//\tprotected Request createRequest (ByteArrayOutputStream buffer) {\n////\t\tsharedRequestObject.reset(buffer);\n//\t\treturn new StreamBufferRequest (buffer);\t\n//\t}\n\n\t@Override\n\tprotected Response createStatusResponse(Command cmd) {\n\t\treturn new SyncLineResponse (new byte[PREFERRED_LINE_BUFFER_SIZE], cmd, ValueType.STATUS);\n\t}\n\t\n\t@Override\n\tprotected Response createBooleanResponse(Command cmd) {\n\t\treturn new SyncLineResponse (new byte[PREFERRED_LINE_BUFFER_SIZE], cmd, ValueType.BOOLEAN);\n\t}\n\t@Override\n\tprotected Response createStringResponse(Command cmd) {\n\t\treturn new SyncLineResponse (new byte[PREFERRED_LINE_BUFFER_SIZE], cmd, ValueType.STRING);\n\t}\n\t\n\t@Override\n\tprotected Response createNumberResponse(Command cmd /*, boolean isBigNum*/) {\n\t\tValueType flavor = ValueType.NUMBER64;\n\t\treturn new SyncLineResponse (new byte[PREFERRED_LINE_BUFFER_SIZE], cmd, flavor);\n\t}\n\t\n\t@Override\n\tprotected Response createBulkResponse(Command cmd) {\n\t\treturn new SyncBulkResponse (new byte[PREFERRED_LINE_BUFFER_SIZE], cmd);\n\t}\n\t\n\t@Override\n\tprotected Response createMultiBulkResponse(Command cmd) {\n\t\treturn new SyncMultiBulkResponse (new byte[PREFERRED_LINE_BUFFER_SIZE], cmd);\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/protocol/DefaultProtocolFactory.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.protocol;\n\nimport org.jredis.NotSupportedException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.connector.Connection;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Sep 13, 2010\n * \n */\n\npublic class DefaultProtocolFactory implements Protocol.Factory {\n\n\t/* (non-Javadoc) @see org.jredis.protocol.Protocol.Factory#newProtocol(org.jredis.connector.ConnectionSpec) */\n    public Protocol newProtocol (ConnectionSpec connSpec) throws NotSupportedException {\n    \t/* \n    \t * TODO:\n    \t * check various Connection.Property/Spec keys.  \n    \t * \n    \t */\n\t\treturn connSpec.getConnectionFlag(Connection.Flag.SHARED) ? new ConcurrentSyncProtocol() : new SyncProtocol();\n    }\n\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/protocol/ProtocolBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.protocol;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.SocketException;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Request;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Convert;\nimport org.jredis.ri.alphazero.support.Log;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, Apr 10, 2009\n * @since   alpha.0\n * \n */\npublic abstract class ProtocolBase implements Protocol {\n\n\t// ------------------------------------------------------------------------\n\t// Protocol Revision specific \n\t// ------------------------------------------------------------------------\n\n\tpublic static final byte[] \tCRLF = {(byte) 13, (byte)10};\n\tpublic static final byte[] \tSPACE = {(byte) 32};\n\tpublic static final int \tCRLF_LEN = CRLF.length;\n\tpublic static final int \tDELIMETER_LEN = SPACE.length;\n\tpublic static final byte\tERR_BYTE \t= (byte) 45; // -\n\tpublic static final byte\tOK_BYTE \t= (byte) 43; // +\n\tpublic static final byte\tCOUNT_BYTE \t= (byte) 42; // *\n\tpublic static final byte\tSIZE_BYTE \t= (byte) 36; // $\n\tpublic static final byte\tNUM_BYTE \t= (byte) 58; // :\n\tpublic static final byte\tASCII_ZERO\t= (byte) 48; // 0\n\t\n\t// ------------------------------------------------------------------------\n\t// Protocol Revision specific consts\n\t// ------------------------------------------------------------------------\n\tprotected ProtocolBase () {}\n\t\n\t// ------------------------------------------------------------------------\n\t// Interface: Protocol\n\t// ------------------------------------------------------------------------\n\t\n\t/* TODO: lets just forget about this multi-version nonsense. */  \n\t@Override\n\tpublic boolean isCompatibleWithVersion(String version) {\n\t\treturn version.equals(\"0.09\");\n\t}\n\t\n\tpublic byte[] createRequestBuffer(Command cmd, byte[]...args) throws ProviderException, IllegalArgumentException {\n\t\tclass Buffer {\n\t\t\tbyte[] b = null;\n\t\t\tprivate int off = 0;\n\t\t\tBuffer(int size){\n\t\t\t\tb = new byte[size];\n\t\t\t}\n\t\t\tvoid write (byte[] d){\n\t\t\t\tfinal int dlen = d.length;\n\t\t\t\tSystem.arraycopy(d, 0, b, off, dlen);\n\t\t\t\toff+=dlen;\n\t\t\t}\n\t\t\tvoid write (byte d){\n\t\t\t\tb[off] = d;\n\t\t\t\toff++;\n\t\t\t}\n\t\t\tbyte[] getBytes() {\n\t\t\t\treturn b;\n\t\t\t}\n\t\t}\n\t\tBuffer buffer = null;\n\t\tbyte[] cmdLenBytes = Convert.toBytes(cmd.bytes.length);\n\t\tbyte[] lineCntBytes = Convert.toBytes(args.length+1);\n\n\t\t// calculate the buffer size\n\t\tint bsize = 1 + lineCntBytes.length + CRLF_LEN + 1 + cmdLenBytes.length + CRLF_LEN + cmd.bytes.length + CRLF_LEN;\n\t\tfor(int i=0;i<args.length; i++){\n\t\t\tbyte[] argLenBytes = Convert.toBytes(Assert.notNull(args[i], i, ProviderException.class).length);\n\t\t\tint _bsize = 1 + argLenBytes.length + CRLF_LEN + args[i].length + CRLF_LEN;\n\t\t\tbsize += _bsize;\n\t\t}\n\t\t\n\t\tbuffer = new Buffer(bsize);\n        buffer.write(COUNT_BYTE);  \t\t// 1\n        buffer.write(lineCntBytes);\t\t// lineCntBytes.length()\n        buffer.write(CRLF);\t\t\t\t// CRLF.lengt\n        buffer.write(SIZE_BYTE);\t\t// 1\n        buffer.write(cmdLenBytes);\t\t// length\n        buffer.write(CRLF);\t\t\t\t// CRLF_LEN\n        buffer.write(cmd.bytes);\t\t//\n        buffer.write(CRLF);\n        \n\t\tswitch (cmd.requestType) {\n\n\t\tcase NO_ARG:\n\t\t    break;\n\t\t    \n\t\t// TODO: check w/ antirez if in fact nulls are now generally accepted\n\t\t// that is the only diff here.\n\t\tcase BULK_SET:\n\t\t\tString errmsg = \"Only MSET, MSETNX, LINSERT bulk commands are supported\";\n\t\t\tAssert.isTrue(cmd == Command.MSET || cmd == Command.MSETNX || cmd == Command.LINSERT, errmsg, NotSupportedException.class);\n\n\t\t\t// THIS IS CLEARLY BROKEN ... SO MUCH FOR COMPREHSIVE TESTS ...\n\t\t\tbuffer.write(COUNT_BYTE);\n\t\t\tbuffer.write(lineCntBytes);\n\t\t\tbuffer.write(CRLF);\n\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\tbuffer.write(cmdLenBytes);\n\t\t\tbuffer.write(CRLF);\n\t\t\tbuffer.write(cmd.bytes);\n\t\t\tbuffer.write(CRLF);\n\t\t\t\n\t\t\tfor(int s=0; s<args.length; s++){\n\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\tif (args[s] != null) {\n  \t\t\t\t\tbuffer.write(Convert.toBytes(args[s].length));\n  \t\t\t\t\tbuffer.write(CRLF);\n  \t\t\t\t\tbuffer.write(args[s]);\n  \t\t\t\t\tbuffer.write(CRLF);\n  \t\t\t\t} else {\n\t\t\t\t\tbuffer.write(ASCII_ZERO);\n\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\tbuffer.write(CRLF);\n  \t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t\n\t\tdefault:\n\t\t\tfor(int i=0;i<args.length; i++){\n\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\tbuffer.write(Convert.toBytes(Assert.notNull(args[i], i, ProviderException.class).length));\n\t\t\t\tbuffer.write(CRLF);\n\t\t\t\tbuffer.write(args[i]);\n\t\t\t\tbuffer.write(CRLF);\n\t\t\t}\n\t\t\tbreak;\n\t\t\n\t\t}\n\t\treturn buffer.getBytes();\n\t}\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.connector.Protocol#createRequest(org.jredis.Command, byte[][])\n\t */\n\t@Override\n\tpublic Request createRequest(Command cmd, byte[]... args) throws ProviderException, IllegalArgumentException {\n\t\t\n\t\tByteArrayOutputStream buffer = createRequestBufffer (cmd);\n\n\t\ttry {\n\t\t\tbyte[] cmdLenBytes = Convert.toBytes(cmd.bytes.length);\n\t\t\tbyte[] lineCntBytes = Convert.toBytes(args.length+1);\n\n            buffer.write(COUNT_BYTE);\n            buffer.write(lineCntBytes);\n            buffer.write(CRLF);\n            buffer.write(SIZE_BYTE);\n            buffer.write(cmdLenBytes);\n            buffer.write(CRLF);\n            buffer.write(cmd.bytes);\n            buffer.write(CRLF);\n            \n\t\t\tswitch (cmd.requestType) {\n\n\t\t\tcase NO_ARG:\n\t\t\t    break;\n\t\t\t    \n\t\t\t// TODO: check w/ antirez if in fact nulls are now generally accepted\n\t\t\t// that is the only diff here.\n\t\t\tcase BULK_SET:\n\t\t\t\tString errmsg = \"Only MSET, MSETNX, LINSERT bulk commands are supported\";\n\t\t\t\tAssert.isTrue(cmd == Command.MSET || cmd == Command.MSETNX || cmd == Command.LINSERT, errmsg, NotSupportedException.class);\n\n\t\t\t\t// THIS IS CLEARLY BROKEN ... SO MUCH FOR COMPREHSIVE TESTS ...\n\t\t\t\tbuffer.write(COUNT_BYTE);\n\t\t\t\tbuffer.write(lineCntBytes);\n\t\t\t\tbuffer.write(CRLF);\n\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\tbuffer.write(cmdLenBytes);\n\t\t\t\tbuffer.write(CRLF);\n\t\t\t\tbuffer.write(cmd.bytes);\n\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\n\t\t\t\tfor(int s=0; s<args.length; s++){\n\t\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\t\tif (args[s] != null) {\n\t  \t\t\t\t\tbuffer.write(Convert.toBytes(args[s].length));\n\t  \t\t\t\t\tbuffer.write(CRLF);\n\t  \t\t\t\t\tbuffer.write(args[s]);\n\t  \t\t\t\t\tbuffer.write(CRLF);\n\t  \t\t\t\t} else {\n\t\t\t\t\t\tbuffer.write(ASCII_ZERO);\n\t\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\t\tbuffer.write(CRLF);\n\t  \t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tdefault:\n\t\t\t\tfor(int i=0;i<args.length; i++){\n\t\t\t\t\tbuffer.write(SIZE_BYTE);\n\t\t\t\t\tbuffer.write(Convert.toBytes(Assert.notNull(args[i], i, ProviderException.class).length));\n\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t\tbuffer.write(args[i]);\n\t\t\t\t\tbuffer.write(CRLF);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tthrow new ProviderException(\"Problem writing to the buffer\" + e.getLocalizedMessage(), e);\n\t\t}\n\t\treturn createRequest(buffer);\n\t}\n\t\n\t/* (non-Javadoc)\n\t * @see org.jredis.connector.Protocol#createResponse(org.jredis.Command)\n\t */\n\t@Override\n\tpublic Response createResponse(Command cmd) throws ProviderException, ClientRuntimeException {\n\n\t\tResponse response = null;\n\t\tswitch (cmd.responseType){\n\t\tcase BOOLEAN:\n\t\t\tresponse = createBooleanResponse(cmd);\n\t\t\tbreak;\n\t\tcase BULK:\n\t\t\tresponse = createBulkResponse (cmd);\n\t\t\tbreak;\n\t\tcase MULTI_BULK:\n\t\t\tresponse = createMultiBulkResponse (cmd);\n\t\t\tbreak;\n\t\tcase NUMBER:\n\t\t\tresponse = createNumberResponse (cmd);\n\t\t\tbreak;\n\t\tcase STATUS:\n\t\t\tresponse = createStatusResponse (cmd);\n\t\t\tbreak;\n\t\tcase STRING:\n\t\t\tresponse = createStringResponse (cmd);\n\t\t\tbreak;\n\t\tcase VIRTUAL:\n\t\t\tresponse = new VirtualResponse(ResponseStatus.STATUS_CIAO);\n\t\t\tbreak;\n\t\tcase NOP:\n\t\t\tresponse = new VirtualResponse(ResponseStatus.STATUS_OK); // TODO: needs more thinking ..\n\t\t\tbreak;\n\t\tcase QUEUED:\n\t\tcase RESULT_SET:\n\t\t\tthrow new NotSupportedException(String.format(\"ResponseType %s not yet supported\", cmd.requestType.name()));\n\t\t\n\t\t}\n\n\t\treturn response;\n\t\n\t}\n\n\n\t// ------------------------------------------------------------------------\n\t// Extension Points\n\t// ------------------------------------------------------------------------\n\t\n\tprotected abstract ByteArrayOutputStream createRequestBufffer(Command cmd);\n\tprotected abstract Request createRequest (ByteArrayOutputStream buffer);\n\tprotected abstract Response createMultiBulkResponse(Command cmd) ;\n\tprotected abstract Response createBulkResponse(Command cmd) ;\n\tprotected abstract Response createNumberResponse(Command cmd /*, boolean bigNum*/) ;\n\tprotected abstract Response createBooleanResponse(Command cmd) ;\n\tprotected abstract Response createStringResponse(Command cmd) ;\n\tprotected abstract Response createStatusResponse(Command cmd);\n\n\t\n\t// ========================================================================\n\t// Inner Types\n\t// ========================================================================\n\t\n\t/**\n\t * SimpleRequest implements the required {@link Request#read(InputStream)}\n\t * using a (likely) shared data buffer.  It is not thread safe and can only\n\t * be used by connections that serialized request processing through a single\n\t * requesting thread.\n\t * <p>\n\t * Specifically, if an instance of this class is obtained and not immediately\n\t * used (by calling read) before the user has obtained another instance of the\n\t * same, data corruption is guaranteed.\n\t *\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, 04/02/09\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic static class StreamBufferRequest implements Request {\n\n\t\t/**  */\n\t\tByteArrayOutputStream buffer;\n\t\t/**\n\t\t * @param buffer\n\t\t */\n\t\tpublic StreamBufferRequest (ByteArrayOutputStream\tbuffer) {\n\t\t\tthis.buffer = buffer;\n\t\t}\n\t\tpublic void reset (ByteArrayOutputStream\tbuffer) {\n\t\t\tthis.buffer = buffer;\n\t\t}\n\t\t/* (non-Javadoc)\n\t\t * @see com.alphazero.jredis.connector.Message#read(java.io.InputStream)\n\t\t */\n\t\t@Override\n\t\tpublic void read(InputStream in) throws ClientRuntimeException, ProviderException {\n\t\t\tthrow new ProviderException(\"Request.read is not supported by this class! [Apr 2, 2009]\");\n\t\t}\n\n\t\t/**\n\t\t * Writes the entire content of the message to the output stream and flushes it.\n\t\t * \n\t\t * @param out the stream to write the Request message to.\n\t\t */\n\t\t@Override\n\t\tpublic void write(OutputStream out) throws ClientRuntimeException, ProviderException {\n\t\t\ttry {\n\t\t\t\t// you would expect these to throw exceptions if the socket has been reset\n\t\t\t\t// but they don't.  \n\t\t\t\tbuffer.writeTo(out);\n\t\t\t\tout.flush();\n\t\t\t}\n\t\t\tcatch (SocketException e){\n\t\t\t\tLog.error(\"StreamBufferRequest.write(): SocketException on write: \" + e.getLocalizedMessage());\n\t\t\t\tthrow new ClientRuntimeException (\"socket exception\", e);\n\t\t\t}\n\t\t\tcatch (IOException e) { \n\t\t\t\tLog.error(\"StreamBufferRequest.write(): IOException on write: \" + e.getLocalizedMessage());\n\t\t\t\tthrow new ClientRuntimeException (\"stream io exception\", e);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/protocol/ResponseSupport.java",
    "content": "package org.jredis.ri.alphazero.protocol;\n\nimport java.io.OutputStream;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ResponseStatus;\n\n/**\n\t * Base for all responses.  Responsible for reading and determining status.\n\t *\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, 04/02/09\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic abstract class ResponseSupport implements Response {\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Properties and fields\n\t\t// ------------------------------------------------------------------------\n\t\tprotected Type\t\t\t\ttype;\n\t\tprotected ResponseStatus\tstatus;\n\t\tprotected Command \t\t\tcmd;\n\t\tprotected boolean \t\t\tdidRead = false;\n\t\tprotected boolean \t\t\tisError = false;\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// Constructor\n\t\t// ------------------------------------------------------------------------\n\t\tpublic ResponseSupport (Command cmd, Type type) {\n\t\t\tthis.type = type;\n\t\t\tthis.cmd = cmd;\n\t\t}\n\t\t// ------------------------------------------------------------------------\n\t\t// Internal ops\n\t\t// ------------------------------------------------------------------------\n\t\t/** called by child classes to indicate if & when their read operation has completed */\n\t\tprotected final boolean didRead (boolean value) { return didRead = value;}\n\t\t\n\t\t/** a bit aggressive but to force out the little bugs .. */\n\t\tprotected final void assertResponseRead () {\n\t\t\tif(!didRead) throw new ProviderException (\"Response has not been read yet! -- whose bad?\");\n\t\t}\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// Interface\n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\t@Override\n\t\tpublic boolean didRead() { return didRead;  }\n\n\t\t@Override\n\t\tpublic ResponseStatus getStatus() {return status; }\n\t\t\n\t\t@Override\n\t\tpublic Type getType() { return type;}\n\n\t\t@Override\n\t\tpublic boolean isError() {\n\t\t\tassertResponseRead(); \n\t\t\treturn isError; \n\t\t}\n\n\t\t@Override\n\t\tpublic void write(OutputStream out) throws ClientRuntimeException, ProviderException {\n\t\t\tthrow new RuntimeException (\"Message.write not implemented! [Apr 10, 2009]\");\n\t\t}\n\t}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/protocol/SyncProtocol.java",
    "content": "/*\n *   Copyright 2009 - 2011 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.protocol;\n\n//import java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.SocketException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.connector.ConnectionReset;\nimport org.jredis.protocol.BulkResponse;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.MultiBulkResponse;\nimport org.jredis.protocol.Protocol;\nimport org.jredis.protocol.Request;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.protocol.StatusResponse;\nimport org.jredis.protocol.ValueResponse;\nimport org.jredis.ri.alphazero.connection.UnexpectedEOFException;\nimport org.jredis.ri.alphazero.support.Convert;\nimport org.jredis.ri.alphazero.support.Log;\n\n\n/**\n * [TODO: document me!]\n *\n * @version alpha.0, Apr 10, 2009\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @since   alpha.0\n * \n */\npublic class SyncProtocol extends ProtocolBase {\n\t\n\t// ------------------------------------------------------------------------\n\t// Protocol Handler's Data Buffer (pseudo-Registers) specific attributes\n\t// ------------------------------------------------------------------------\n\n\t/** Preferred size of request data buffer */\n\tprotected static final int\t\t\tPREFERRED_REQUEST_BUFFER_SIZE\t= 1024 * 48;\n\t\n\t/** Initial size of the shared line buffer */\n\tprotected static final int\t\t\tPREFERRED_LINE_BUFFER_SIZE = 128;\n\t\n\t/**  */\n\tprotected static final int\t\t\tINPUT_STREAM_BUFFER_SIZE = 1024 * 128;\n\t\n\t// ------------------------------------------------------------------------\n\t// SyncConnection's can use the same buffers again and again and ...\n\t// ------------------------------------------------------------------------\n\t\n\t/** Shared by <b>all</b> {@link Request} instances of this <b>non-thread-safe</b> {@link Protocol} implementation. */\n\tprivate final ByteArrayOutputStream sharedRequestBuffer;\n\n\t/** Shared {@link Request} instance of this <b>non-thread-safe</b> {@link Protocol} implementation. */\n\tprivate final StreamBufferRequest   sharedRequestObject;\n\n\t/** Shared by <b>all</b> {@link Response} instances of this <b>non-thread-safe</b> {@link Protocol} implementation. */\n\tprivate final byte[]\tsharedResponseBuffer;\n\n\t// ------------------------------------------------------------------------\n\t// Constructor(s)\n\t// ------------------------------------------------------------------------\n\t\n\tpublic SyncProtocol() {\n\t\tsharedRequestBuffer = new ByteArrayOutputStream (PREFERRED_REQUEST_BUFFER_SIZE);\n\t\tsharedRequestObject = new StreamBufferRequest (sharedRequestBuffer);\n\t\tsharedResponseBuffer = new byte [PREFERRED_LINE_BUFFER_SIZE];\n\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Super Extensions\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @param cmd {@link Command} for this request - potentially useful for \n\t * optimizing buffers.\n\t * \n\t * @return the shared instance of {@link ByteArrayOutputStream} that\n\t * is used <b>by all requests</b> created by this {@link Protocol} implementation.\n\t */\n\t@Override\n\tprotected ByteArrayOutputStream createRequestBufffer(Command cmd) {\n\t\tsharedRequestBuffer.reset();\n\t\treturn sharedRequestBuffer;\n\t}\n\t\n\tprotected Request createRequest (ByteArrayOutputStream buffer) {\n//\t\tsharedRequestObject.reset(buffer);\n\t\treturn sharedRequestObject;\n\t}\n\n\tSyncLineResponse cache_syncLineResponse = null;\n\t@Override\n\tprotected Response createStatusResponse(Command cmd) {\n\t\tif(null == cache_syncLineResponse)\n\t\t\tcache_syncLineResponse = new SyncLineResponse(cmd, ValueType.STATUS);\n\t\telse {\n\t\t\tcache_syncLineResponse.reset(cmd);\n\t\t}\n\t\treturn cache_syncLineResponse;\n\t}\n\t@Override\n\tprotected Response createBooleanResponse(Command cmd) {\n\t\tif(null == cache_syncLineResponse)\n\t\t\tcache_syncLineResponse = new SyncLineResponse(cmd, ValueType.BOOLEAN);\n\t\telse {\n\t\t\tcache_syncLineResponse.reset(cmd, ValueType.BOOLEAN);\n\t\t}\n\t\treturn cache_syncLineResponse;\n\t}\n\t@Override\n\tprotected Response createStringResponse(Command cmd) {\n\t\tif(null == cache_syncLineResponse)\n\t\t\tcache_syncLineResponse = new SyncLineResponse(cmd, ValueType.STRING);\n\t\telse {\n\t\t\tcache_syncLineResponse.reset(cmd, ValueType.STRING);\n\t\t}\n\t\treturn cache_syncLineResponse;\n\t}\n\t@Override\n\tprotected Response createNumberResponse(Command cmd /*, boolean isBigNum*/) {\n\t\tValueType flavor = ValueType.NUMBER64;\n\t\tif(null == cache_syncLineResponse)\n\t\t\tcache_syncLineResponse = new SyncLineResponse(cmd, flavor);\n\t\telse {\n\t\t\tcache_syncLineResponse.reset(cmd, flavor);\n\t\t}\n\t\treturn cache_syncLineResponse;\n\t}\n\t\n\tSyncBulkResponse  cache_syncBulkResponse = null;\n\t@Override\n\tprotected Response createBulkResponse(Command cmd) {\n\t\tif(null == cache_syncBulkResponse)\n\t\t\tcache_syncBulkResponse = new SyncBulkResponse(cmd);\n\t\telse {\n\t\t\tcache_syncBulkResponse.reset(cmd);\n\t\t}\n\t\treturn cache_syncBulkResponse;\n\t}\n\n\t\n\tSyncMultiBulkResponse  cache_syncMultiBulkResponse = null;\n\t@Override\n\tprotected Response createMultiBulkResponse(Command cmd) {\n\t\tif(null == cache_syncMultiBulkResponse)\n\t\t\tcache_syncMultiBulkResponse = new SyncMultiBulkResponse(cmd);\n\t\telse {\n\t\t\tcache_syncMultiBulkResponse.reset(cmd);\n\t\t}\n\t\treturn cache_syncMultiBulkResponse;\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Inner Type\n\t// ========================================================================\n\t// ------------------------------------------------------------------------\n\tprotected enum ValueType {\n\t\tSTATUS,\n\t\tBOOLEAN,\n\t\tNUMBER64,\n\t\tSTRING\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Inner Type\n\t// ============================================================ Response(s)\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Synchronous responses are guaranteed to be contiguous chunks (if the\n\t * client of this class is respecting its contract) -- meaning, it can go\n\t * ahead and read as much as it can in its first read without busy waiting\n\t * or reading one byte at a time.  After that initial read, specialized\n\t * response types can go head and read/parse as they please.  \n\t *\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, 04/02/09\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic abstract class SyncResponseBase extends ResponseSupport {\n\n\t\tbyte[]\t\tbuffer;\n\t\tint\t\t\toffset;\n\t\t\n\t\tprotected SyncResponseBase(byte[] buffer, Command cmd, Type type) {\n\t\t\tsuper(cmd, type);\n\t\t\tthis.buffer = buffer;\n\t\t\toffset = 0;\n\t\t}\n\n\t\tprotected void reset (Command cmd, Type type) {\n\t\t\tthis.cmd = cmd;\n\t\t\tthis.type = type;\n\t\t\toffset = 0;\n\t\t\tdidRead = false;\n\t\t\tstatus = null;\n\t\t\tisError = false;\n\t\t}\n\t\t/**\n\t\t * Makes blocking calls to input stream until it gets crlf. Should not be\n\t\t * used for size/count lines.\n\t\t * @param in\n\t\t */\n\t\tvoid readSingleLineResponse (InputStream in) {\n\t\t\toffset = 0;\n\t\t\tint c = -1;\n\t\t\tint available = buffer.length;\n\t\t\ttry {\n\t\t\t\twhile ((c = in.read(buffer, offset, 1)) != -1) {\n\t\t\t\t\toffset += c; \n\t\t\t\t\tavailable -= c;\n\t\t\t\t\tif(offset > 2 && buffer[offset-2]==(byte)13 && buffer[offset-1]==(byte)10){\n\t\t\t\t\t\tbreak;  // we're done\n\t\t\t\t\t}\n\t\t\t\t\tif(available == 0) {\n\t\t\t\t\t\tbyte[] newbuff = new byte[buffer.length * 2];\n\t\t\t\t\t\tSystem.arraycopy(buffer, 0, newbuff, 0, buffer.length);\n\t\t\t\t\t\tbuffer = newbuff;\n\t\t\t\t\t\tavailable = buffer.length - offset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(c == -1) {\n\t\t\t\t\tLog.error(\"-1 read count in readLine() while reading response line.\");\n\t\t\t\t\tthrow new UnexpectedEOFException (\"Unexpected EOF (read -1) in readLine.  Command: \" + cmd.code);\n\t\t\t\t}\n\t\t\t\tif((this.isError = buffer[0] == ProtocolBase.ERR_BYTE) == true) \n\t\t\t\t\tstatus = new ResponseStatus(ResponseStatus.Code.ERROR, new String(buffer, 1, offset-3));\n\t\t\t\telse \n\t\t\t\t\tstatus = ResponseStatus.STATUS_OK;\n\t\t\t}\n\t\t\tcatch (SocketException e) {\n\t\t\t\t// on connection reset\n\t\t\t\tthrow new ConnectionReset(\"SocketException in readLine.  Command: \" + cmd.code, e);\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tthrow new ClientRuntimeException (\"IOException in readLine.  Command: \" + cmd.code, e);\n\t\t\t}\n\t\t}\n\t}\n\t// ------------------------------------------------------------------------\n\t// Inner Type\n\t// ============================================================ Response(s)\n\t// ------------------------------------------------------------------------\n\t/**\n\t *\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, 04/02/09\n\t * @since   alpha.0\n\t *\n\t */\n\tpublic class SyncLineResponse extends SyncResponseBase implements StatusResponse, ValueResponse {\n\t\tprivate ValueType \tflavor;\n\t\tprivate String\t\tstringValue;\n\t\tprivate long\t\tlongValue;\n\t\tprivate boolean\t\tbooleanValue;\n\t\t\n\t\tprivate SyncLineResponse(Command cmd, ValueType flavor) {\n\t\t\tthis (sharedResponseBuffer, cmd, flavor);\n\t\t}\n\t\t/**\n\t\t * @param bs\n\t\t * @param cmd\n\t\t * @param status\n\t\t */\n\t\tpublic  SyncLineResponse(byte[] buff, Command cmd, ValueType flavor) {\n\t\t\tsuper(buff, cmd, Type.Value);\n\t\t\tthis.flavor = flavor;\n\t\t}\n\t\tprotected void reset (Command cmd){\n\t\t\tsuper.reset(cmd, Type.Status);\n\t\t\tthis.flavor = ValueType.STATUS;\n\t\t}\n\t\tprotected void reset (Command cmd, ValueType flavor){\n\t\t\tsuper.reset(cmd, Type.Value);\n\t\t\tthis.flavor = flavor;\n\t\t}\n\n\t\t@Override\n\t\tpublic boolean getBooleanValue() throws IllegalStateException {\n\t\t\tif(flavor != ValueType.BOOLEAN) throw new IllegalStateException (\"Response value type is \" + flavor.name() + \" not \" + ValueType.BOOLEAN.name());\n\t\t\treturn booleanValue;\n\t\t}\n\t\t\n\t\t@Override\n\t\tpublic long getLongValue() throws IllegalStateException {\n\t\t\tif(flavor != ValueType.NUMBER64) throw new IllegalStateException (\"Response value type is \" + flavor.name() + \" not \" + ValueType.NUMBER64.name());\n\t\t\treturn longValue;\n\t\t}\n\t\t@Override\n\t\tpublic String getStringValue() throws IllegalStateException {\n\t\t\tif(flavor != ValueType.STRING) throw new IllegalStateException (\"Response value type is \" + flavor.name() + \" not \" + ValueType.STRING.name());\n\t\t\treturn stringValue;\n\t\t}\n\t\t\n\t\t/**\n\t\t * Delegates the io handling to the base class and parses the value reponse\n\t\t * based on the data flavor.\n\t\t */\n\t\t@Override\n\t\tpublic void read(InputStream in) throws ClientRuntimeException, ProviderException {\n\t\t\tif(didRead) return;\n\t\t\t\n//\t\t\tBufferedInputStream bin = new BufferedInputStream(in, 1024 * 48);\n//\t\t\tsuper.readSingleLineResponse (bin);\n\n\t\t\tsuper.readSingleLineResponse (in);\n\t\t\tdidRead = true;\n\n\t\t\t// TODO: not quite happy with the access to raw buffer here -- a method call would\n\t\t\t// slow things done but this is fragile in light of possible future code re-factoring.\n\t\t\tif(!status.isError() && flavor != ValueType.STATUS){\n\t\t\t\tswitch (flavor){\n\t\t\t\tcase BOOLEAN:\n\t\t\t\t\tbooleanValue = buffer[1]==49?true:false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase NUMBER64:\n\t\t\t\t\tlongValue = Convert.toLong (buffer, 1, offset-3);\n\t\t\t\t\tbreak;\n\t\t\t\tcase STATUS:\n\t\t\t\t\tbreak;\n\t\t\t\tcase STRING:\n\t\t\t\t\tstringValue = new String (buffer, 1, offset-3);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\t\n\t// ------------------------------------------------------------------------\n\t// Inner Type\n\t// ============================================================ Response(s)\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Abstract base for all multiline responses (as of now, Bulk and MultBulk).\n\t *\n\t * @author  Joubin (alphazero@sensesay.net)\n\t * @version alpha.0, Sep 2, 2009\n\t * @since   alpha.0\n\t * TODO: Use overflow buffers to increase read efficiency.\n\t */\n\tpublic abstract class SyncMultiLineResponseBase extends SyncResponseBase {\n\n        protected SyncMultiLineResponseBase (byte[] buffer, Command cmd, Type type) {\n\t        super(buffer, cmd, type);\n        }\n\t\t\n\t\t/**\n\t\t * @param in\n\t\t */\n\t\tvoid seekToCRLF (InputStream in){\n\t\t\toffset = 0;\n\t\t\tint c = -1;\n\t\t\tint available = buffer.length;\n\t\t\ttry {\n\t\t\t\twhile ((c = in.read(buffer, offset, 1)) != -1) {\n\t\t\t\t\toffset += c;\n\t\t\t\t\tavailable -= c;\n\t\t\t\t\tif(offset > 2 && buffer[offset-2]==(byte)13 && buffer[offset-1]==(byte)10){\n\t\t\t\t\t\tbreak;  // we're done\n\t\t\t\t\t}\n\t\t\t\t\tif(available == 0) {\n\t\t\t\t\t\tbyte[] newbuff = new byte[buffer.length * 2];\n\t\t\t\t\t\tSystem.arraycopy(buffer, 0, newbuff, 0, buffer.length);\n\t\t\t\t\t\tbuffer = newbuff;\n\t\t\t\t\t\tavailable = buffer.length - offset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t\tthrow new ClientRuntimeException (\"IOEx while reading line for command \" + cmd.code, e);\n\t\t\t}\n\t\t\t\n\t\t\tif(c==-1) throw new ClientRuntimeException (\"in.read returned -1\");\n\t\t}\n\t\t/**\n\t\t * @param in\n\t\t * @param checkForError\n\t\t * @param ctlByte\n\t\t * @return\n\t\t */\n\t\tint readControlLine (InputStream in, boolean checkForError, byte ctlByte){\n\t\t\tseekToCRLF(in);\n\t\t\tif(checkForError && (this.isError = buffer[0] == ProtocolBase.ERR_BYTE) == true) {\n\t\t\t\tstatus = new ResponseStatus(ResponseStatus.Code.ERROR, new String(buffer, 1, offset-3));\n\t\t\t\tdidRead = true;  // we're done - error's are only one line\n\t\t\t\treturn -2;\n\t\t\t}\n\t\t\tif(buffer[0] != ctlByte) {\n\t\t\t\tthrow new ProviderException (\"Bug?  Expecting status code for size/count\");\n\t\t\t}\n\t\t\tstatus = ResponseStatus.STATUS_OK;\n\t\t\treturn Convert.toInt (buffer, 1, offset-3);\n\t\t}\n\n\t\t/**\n\t\t * Will read up expected bulkdata bytes from the input stream.  Routine will\n\t\t * also read in the last two bytes and will check that they are indeed CRLF.\n\t\t *  \n\t\t * @param in the stream to read from.\n\t\t * @param length expected bulk data length (NOT including the trailing CRLF).  \n\t\t * @return a byte[] of length.\n\t\t * @throws IOException \n\t\t * @throws IllegalArgumentException if could not read the bulk data\n\t\t */\n\t\tpublic final byte[] readBulkData (InputStream in, int length)\n\t\t\tthrows IOException, RuntimeException\n\t\t{\n\t\t\tbyte[] data = new byte[length]; // TODO: optimize me\n//\t\t\tbyte[] term = new byte[CRLF.length]; // FIX: http://github.com/alphazero/jredis/issues#issue/5 -- N/A\n\t\t\t\n\t\t\tint readcnt = -1;\n\t\t\tint offset = 0;\n\n\t\t\twhile(offset < length){\n\t\t\t\tif((readcnt = in.read (data, offset, length-offset)) ==-1 ) throw new ClientRuntimeException(\"IO - read returned -1 -- problem\");\n\t\t\t\toffset += readcnt;\n\t\t\t}\n\t\t\t// FIX: http://github.com/alphazero/jredis/issues#issue/5 -- BEGIN\n\t\t\tfor(int i=0; i<CRLF_LEN; i++){\n\t\t\t\tif (in.read() == -1){\n\t\t\t\t\tthrow new RuntimeException (\"read got EOF (-1) while consuming the \" +(i+1)+ \"-th byte of CRLF bytes!\");\n\t\t\t\t}\n\t\t\t}\n//\t\t\tif((readcnt = in.read (term, 0, CRLF.length)) != CRLF.length) { \n//\t\t\t\tthrow new RuntimeException (\"Only read \" + readcnt + \" bytes for CRLF!\");\n//\t\t\t}\n\t\t\t// http://github.com/alphazero/jredis/issues#issue/5 -- END\n\t\t\treturn data;\n\t\t}\n\t}\n\t// ------------------------------------------------------------------------\n\t// Inner Type\n\t// ============================================================ Response(s)\n\t// ------------------------------------------------------------------------\n\tpublic class SyncBulkResponse extends SyncMultiLineResponseBase implements BulkResponse {\n\t\t/**  */\n\t\tbyte[] data = null;\n\n\t\t/**\n\t\t * Uses the sharedResponseBuffer for reading of the response control line.\n\t\t * @param cmd\n\t\t */\n\t\tprivate SyncBulkResponse(Command cmd) {\n\t\t\tthis (sharedResponseBuffer, cmd);\n\t\t}\n\n\t\tpublic SyncBulkResponse(byte[] buff, Command cmd) {\n\t\t\tsuper (buff, cmd, Type.Bulk);\n\t\t}\n\t\t\n\t\tprotected void reset (Command cmd){\n\t\t\tsuper.reset(cmd, Type.Bulk);\n\t\t\tthis.data = null;\n\t\t}\n\n\t\t@Override\n\t\tpublic byte[] getBulkData() {\n\t\t\tassertResponseRead();\n\t\t\treturn data;\n\t\t}\n\n\t\t@Override\n\t\tpublic void read(InputStream in) throws ClientRuntimeException, ProviderException {\n\t\t\tif(didRead) return;\n\n//\t\t\tBufferedInputStream bin = new BufferedInputStream(in, INPUT_STREAM_BUFFER_SIZE);\n\t\t\tint size = readControlLine (in, true, SIZE_BYTE);\n\n\t\t\tif(!status.isError() && size >= 0){\n\t\t\t\ttry {\n\t\t\t\t\tdata = super.readBulkData(in, size);\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException bug){ \n\t\t\t\t\tthrow new ProviderException (\"Bug: in converting the bulk data length bytes\", bug);\n\t\t\t\t}\n\t\t\t\tcatch (IOException problem) {\n\t\t\t\t\tthrow new ClientRuntimeException (\"Problem: reading the bulk data bytes\", problem);\n\t\t\t\t}\n\t\t\t\tcatch (RuntimeException bug) {\n\t\t\t\t\tthrow new ProviderException (\"Bug: reading the bulk data bytes.  expecting \" + size + \" bytes.\", bug);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdidRead = true;\n\t\t\treturn;\n\t\t}\n\t}\n\t// ------------------------------------------------------------------------\n\t// Inner Type\n\t// ============================================================ Response(s)\n\t// ------------------------------------------------------------------------\n\tpublic class SyncMultiBulkResponse extends SyncMultiLineResponseBase implements MultiBulkResponse {\n\n\t\t/**  */\n\t\tList<byte[]>   datalist;\n\t\t\n\t\t/**\n\t\t * @param cmd\n\t\t */\n\t\tprivate SyncMultiBulkResponse(Command cmd) {\n\t\t\tthis (sharedResponseBuffer, cmd);\n\t\t}\n\n\t\tpublic SyncMultiBulkResponse(byte[] buff, Command cmd) {\n\t\t\tsuper (buff, cmd, Type.MultiBulk);\n\t\t}\n\n\t\tprotected void reset (Command cmd){\n\t\t\tsuper.reset(cmd, Type.Bulk);\n\t\t\tthis.datalist = null;\n\t\t}\n\n\t\t@Override\n\t\tpublic List<byte[]> getMultiBulkData() throws ClientRuntimeException, ProviderException {\n\t\t\tassertResponseRead();\n\t\t\treturn datalist;\n\t\t}\n\n\t\t@Override\n\t\tpublic void read(InputStream in) throws ClientRuntimeException, ProviderException {\n\t\t\tif(didRead) return;\n\t\t\t\n//\t\t\tBufferedInputStream bin = new BufferedInputStream(in, 1024);\n\t\t\tint count = super.readControlLine (in, true, COUNT_BYTE);\n\t\t\t\n\t\t\tif(!status.isError() && count >= 0){\n\t\t\t\tdatalist = new ArrayList<byte[]>(count);\n\t\t\t\ttry {\n\t\t\t\t\tint size = -1;\n\t\t\t\t\tfor(int i=0;i<count; i++){\n\t\t\t\t\t\tsize = readControlLine(in, false, SIZE_BYTE);\n\n\t\t\t\t\t\tif(size >= 0)\n\t\t\t\t\t\t\tdatalist.add (super.readBulkData(in, size));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tdatalist.add(null);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException bug){ \n\t\t\t\t\tthrow new ProviderException (\"Bug: in converting the bulk data length bytes\", bug);\n\t\t\t\t}\n\t\t\t\tcatch (IOException problem) {\n\t\t\t\t\tthrow new ClientRuntimeException (\"Problem: reading the bulk data bytes\", problem);\n\t\t\t\t}\n\t\t\t\tcatch (RuntimeException bug) {\n\t\t\t\t\tthrow new ProviderException (\"Bug: reading the multibulk data bytes.\", bug);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdidRead = true;\n\t\t\treturn;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/protocol/VirtualResponse.java",
    "content": "/*\n *   Copyright 2009 Joubin Mohammad Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.protocol;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.ProviderException;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.protocol.ResponseStatus;\n\n\n\n/**\n * Certain requested commands do not have a corresponding response from\n * redis.  Quit and Shutdown are two examples as of now.  This response\n * provides a virtual response for this type of request.  You can set\n * the virtual response's status in the constructor.  The default constructor\n * provides for OK status.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic final class VirtualResponse implements Response {\n\n\t\n\tprivate final ResponseStatus\tstatus;\n\tpublic VirtualResponse () { \n\t\tthis.status = ResponseStatus.STATUS_OK;\n\t}\n\tpublic VirtualResponse (ResponseStatus status) { \n\t\tthis.status = status;\n\t}\n\n\t@Override\n\tpublic boolean didRead() {return true;}\n\n\t@Override\n\tpublic ResponseStatus getStatus() { return status;}\n\n\t@Override\n\tpublic Type getType() { return Type.Status;}\n\n\t@Override\n\tpublic boolean isError() { return false;}\n\n\t@Override\n\t/**\n\t * The purpose of this class is to provide responses that are not actually read from\n\t * the server.  Typically this is for commands that closed the connection on the send, such\n\t * as QUIT.\n\t * @see Command#QUIT\n\t * @see Command#SHUTDOWN\n\t * @see org.jredis.connector.Message#read(java.io.InputStream)\n\t */\n\tpublic void read(InputStream in) throws ClientRuntimeException, ProviderException { return;}\n\n\t@Override\n\tpublic void write(OutputStream out) throws ClientRuntimeException, ProviderException {\n\t\tthrow new RuntimeException (\"Streamable.write not implemented! [Apr 4, 2009]\");\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/semantics/DefaultKeyCodec.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.semantics;\n\nimport java.io.UnsupportedEncodingException;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.jredis.NotSupportedException;\nimport org.jredis.ri.alphazero.JRedisSupport;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\nimport org.jredis.semantics.KeyCodec;\n\n/**\n * Default {@link KeyCodec} provider for JRedis RI.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 25, 2009\n * @since   alpha.0\n * \n */\n\npublic class DefaultKeyCodec<K extends Object> implements KeyCodec<K> {\n\tprivate static final KeyCodec<Object> instance;\n\tstatic {\n\t\tinstance = new DefaultKeyCodec<Object>();\n\t}\n\t/**  */\n\tstatic final private Map<String, byte[]>\tkeyByteCache = new ConcurrentHashMap<String, byte[]>();\n\t\n\tpublic static final KeyCodec<Object> provider() { return instance; }\n\t\n\t/** TODO: jvm arg me ... defaults to FALSE now */\n\tpublic static final boolean\tCacheKeys\t= false;\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.Codec#decode(byte[])\n\t */\n\tpublic K decode (byte[] bytes) { throw new NotSupportedException(\"key decode not supported.\"); }\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.Codec#encode(java.lang.Object)\n\t */\n\tpublic byte[] encode (K key) {\n\t\tif(null == key) throw new IllegalArgumentException(\"key is null\");\n\t\tif(key instanceof String) {\n\t\t\treturn encodeString((String) key);\n\t\t}\n\t\telse if (key instanceof byte[]){\n\t\t\tbyte[] bkey = (byte[]) key ;\n\t\t\tif(bkey.length == 0) throw new IllegalArgumentException(\"key is zerolewn\");\n\t\t\treturn bkey;\n\t\t}\n\t\telse {\n\t\t\tString msg = String.format(\"only String and byte[] keys are supported\", key.getClass().getCanonicalName());\n\t\t\tthrow new IllegalArgumentException(msg);\n\t\t}\n\t}\n\tpublic static byte[] encodeString(String key) throws IllegalArgumentException {\n\t\tif(null == key) throw new IllegalArgumentException(\"key is null\");\n\t\tbyte[] bytes = null;\n\t\tif(JRedisSupport.CacheKeys == true)\n\t\t\tbytes = keyByteCache.get(key);\n\t\tif(null == bytes) {\n//\t\t\tbytes = key.getBytes(DefaultCodec.SUPPORTED_CHARSET); // java 1.6\n\t\t\ttry {\n\t            bytes = key.getBytes(DefaultCodec.SUPPORTED_CHARSET_NAME);\n            }\n            catch (UnsupportedEncodingException e) {\n\t            throw new UndeclaredThrowableException(e);\n            }\n\t\t\tfor(byte b : bytes) {\n\t\t\t\tif (b == (byte)32 || b == (byte)10 || b == (byte)13)\n\t\t\t\t\tthrow new IllegalArgumentException (\"Key includes invalid byte value: \" + (int)b);\n\t\t\t}\n\t\t\t\n\t\t\tif(JRedisSupport.CacheKeys == true)\n\t\t\t\tkeyByteCache.put(key, bytes);\n\t\t}\n\t\treturn bytes;\n\t}\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.Codec#supports(java.lang.Class)\n\t */\n\tstatic byte[] ba = new byte[0];\n\tstatic Class<?> BAClass = ba.getClass();\n\tpublic boolean supports (Class<?> type) { \n\t\treturn type == String.class || type.equals(BAClass); \n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/semantics/DefaultStringCodec.java",
    "content": "package org.jredis.ri.alphazero.semantics;\n\nimport java.nio.charset.Charset;\nimport org.jredis.Codec;\n\n/**\n * Nothing to see here, folks.  Your basic {@link String#getBytes(Charset)} and {@link String#String(byte[], Charset)}\n * wrapper, and of course you can get to set the {@link Charset} if the default <code>UTF-8</code> {@link Charset} is \n * not to your liking.\n *\n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, Aug 23, 2009\n * @since   alpha.0\n * \n */\npublic class DefaultStringCodec implements Codec<String> {\n\t/** Default supported character set is UTF-8  */\n\tpublic final static Charset DEFAULT_CHARSET = Charset.forName (\"UTF-8\");\n\t/**  */\n\t@SuppressWarnings(\"unused\")\n    private final Charset charSet; // java 1.6\n\t/**\n\t * \n\t */\n\tpublic DefaultStringCodec() {\n\t\tthis(DEFAULT_CHARSET);\n\t}\n\t/**\n\t * @param charset\n\t */\n\tpublic DefaultStringCodec(Charset charset){\n\t\tthis.charSet = charset;\n\t}\n\n\t/* (non-Javadoc)\n     * @see org.jredis.Codec#decode(byte[])\n     */\n    @Override\n    public String decode (byte[] bytes) {\n        return new String(bytes);\n//        return new String(bytes, charSet);  // java 1.6\n    }\n\n\t/* (non-Javadoc)\n     * @see org.jredis.Codec#encode(java.lang.Object)\n     */\n    @Override\n    public byte[] encode (String value) {\n\t\treturn value.getBytes();\n//\t\treturn value.getBytes(charSet);\n    }\n\n\t/* (non-Javadoc)\n     * @see org.jredis.Codec#supports(java.lang.Class)\n     */\n    @Override\n    public boolean supports (Class<?> type) {\n        return type.equals(String.class) ? true : false;\n    }\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/semantics/GZipCompressedStringCodec.java",
    "content": "package org.jredis.ri.alphazero.semantics;\n\nimport static org.jredis.ri.alphazero.support.GZip.compress;\nimport static org.jredis.ri.alphazero.support.GZip.decompress;\n\n/**\n * \n * @author  Joubin (alphazero@sensesay.net)\n * @version alpha.0, Aug 23, 2009\n * @since   alpha.0\n * \n */\npublic class GZipCompressedStringCodec extends DefaultStringCodec {\n\n\t/* (non-Javadoc)\n     * @see org.jredis.Codec.DefaultStringCodec#decode(byte[])\n     */\n    @Override\n    public String decode (byte[] bytes) {\n        return super.decode(decompress(bytes));\n    }\n\n\t/* (non-Javadoc)\n     * @see org.jredis.Codec.DefaultStringCodec#encode(java.lang.String)\n     */\n    @Override\n    public byte[] encode (String value) {\n        return compress(super.encode(value));\n    }\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/Assert.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Formatter;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 02, 2009\n * @since   alpha.0\n * \n */\npublic class Assert {\n\n\t/**\n\t * assert identical based on content.\n\t * @param <E>\n\t * @param a\n\t * @param b\n\t * @param clazz\n\t */\n\tpublic static final <E extends RuntimeException>\n\tvoid isEquivalent (byte[] a, byte[] b) {\n\t\tisEquivalent(a, b, RuntimeException.class);\n\t}\n\t/**\n\t * assert identical based on content.\n\t * @param <E>\n\t * @param a\n\t * @param b\n\t * @param clazz\n\t */\n\tpublic static final <E extends RuntimeException>\n\tvoid isEquivalent (byte[] a, byte[] b, Class<E> clazz) {\n\t\tnotNull(a, \"arg a\", clazz);\n\t\tnotNull(b, \"arg b\", clazz);\n\t\tif(a.length != b.length) { \n\t\t\tthrowIt(\"byte arrays being compared are of unequal length\", clazz);\n\t\t}\n\t\tfor(int i=0; i<a.length; i++){\n\t\t\tif(a[i]!=b[i]){\n\t\t\t\tthrowIt(\"byte arrays being compared differ beginning at index \" + i, clazz);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t * <b>Usage</b>: <pre><code>\n\t * // ... somewhere within the bowels of your code ..\n\t * //\n\t * Assert.notNull (aReference, YourRuntimeException.class);\n\t * </code> </pre>\n\t * @param <T>\n\t * @param <E>\n\t * @param obj\n\t * @param clazz\n\t * @return\n\t * @throws E\n\t */\n\tpublic static final <T, E extends RuntimeException> \n\tT notNull\n\t\t(T obj, Class<E> clazz)\n\tthrows E\n\t{\n\t\tif(null == obj){ throwIt(\"null reference\", clazz);}\n\t\treturn obj;\n\t}\n\t\n\t/**\n\t * <b>Usage</b>: <pre><code>\n\t * // ... somewhere within the bowels of your code ..\n\t * //\n\t * Assert.notNull (inputRecord, \"inputRecord\", YourRuntimeException.class);\n\t * </code> </pre>\n\t * @param <T>\n\t * @param <E>\n\t * @param obj\n\t * @param info\n\t * @param clazz\n\t * @return\n\t * @throws E\n\t */\n\tpublic static final <T, E extends RuntimeException> \n\tT notNull\n\t\t(T obj, String info, Class<E> clazz)\n\tthrows E\n\t{\n\t\tif(null == obj){ throwIt(\"null reference:{\"+info+\"}\", clazz);}\n\t\treturn obj;\n\t}\n\t\n\t@SuppressWarnings(\"boxing\")\n\tpublic static final <T, E extends RuntimeException> \n\tT notNull\n\t\t(T obj, int idx, Class<E> clazz)\n\tthrows E\n\t{\n\t\tif(null == obj){ throwIt(String.format(\"null reference: arg {%d}\", idx), clazz);}\n\t\treturn obj;\n\t}\n\t\n\t/**\n\t * <b>Usage</b>: <pre><code>\n\t * // ... somewhere within the bowels of your code ..\n\t * //\n\t * Assert.isTrue (conn.isReady(), \"connection is ready\", YourRuntimeException.class);\n\t * </code> </pre>\n\t * @param <E>\n\t * @param fact\n\t * @param claim\n\t * @param clazz\n\t * @throws E\n\t */\n\tpublic static final <E extends RuntimeException> \n\tvoid isTrue\n\t\t(boolean fact, String claim, Class<E> clazz) \n\tthrows E \n\t{\n\t\tif(!fact) { throwIt(\"its not true that \\\"\" + claim + \"\\\"\", clazz);}\n\t}\n\t\n\t/**\n\t * <b>Usage</b>: <pre><code>\n\t * // ... somewhere within the bowels of your code ..\n\t * //\n\t * Assert.isTrue (conn.isReady(), YourRuntimeException.class);\n\t * </code> </pre>\n\t * @param <E> is what you wish thrown - must be related to {@link RuntimeException}\n\t * @param fact\n\t * @param clazz\n\t * @throws E\n\t */\n\tpublic static final <E extends RuntimeException> \n\tvoid isTrue\n\t\t(boolean fact, Class<E> clazz) \n\tthrows E \n\t{\n\t\tif(!fact) { throwIt(\"Factual error \", clazz);}\n\t}\n\t\n\t/**\n\t * @param <E>\n\t * @param n\n\t * @param from\n\t * @param to\n\t * @param info\n\t * @param clazz\n\t * @return\n\t * @throws E\n\t */\n\tpublic static final <E extends RuntimeException> \n\tlong inRange\n\t\t(long n, long from, long to, String info, Class<E> clazz)\n\tthrows E\n\t{\n\t\tif(n > to || n < from ){ throwIt(\"exceeds valid range :{\"+info+\"}\", clazz);}\n\t\treturn n;\n\t}\n\t/**\n\t * Note: asserts n is in the range from->to, inclusive.\n\t * @param <E>\n\t * @param n\n\t * @param from\n\t * @param to\n\t * @param info\n\t * @param clazz\n\t * @return\n\t * @throws E\n\t */\n\tpublic static final <E extends RuntimeException> \n\tint inRange\n\t\t(int n, int from, int to, String info, Class<E> clazz)\n\tthrows E\n\t{\n\t\tif(n > to || n < from ){ throwIt(\"exceeds valid range :{\"+info+\"}\", clazz);}\n\t\treturn n;\n\t}\n//\tObject obj = Assert.isType(T obj, Class<T> clazz, \"\", RuntimeException.class);\n\n\t/**\n\t * Tests to see if the object can be cast to the specified type.\n\t * Will not test to see arguments are not null.\n\t * @param <T> the type\n\t * @param <E> the thrown exception type\n\t * @param obj the object to be cast\n\t * @param clazz of the the target type\n\t * @param info the message for the exception thrown\n\t * @param throwable specified if not\n\t * @return the cast object if successful\n\t * @throws E\n\t */\n\tpublic static final <T, E extends RuntimeException> \n\tT cast\n\t\t(Object obj, Class<T> clazz, String info, Class<E> throwable)\n\tthrows E\n\t{\n\t\tT t = null;\n\t\ttry {\n\t\t\tt = clazz.cast(obj);\n\t\t}\n\t\tcatch (ClassCastException e) {\n\t\t\tString actual = obj.getClass().getCanonicalName();\n\t\t\tthrowIt(info + \" [object type: \"+ actual +\" target: \" + clazz.getCanonicalName() +\"]\", throwable);\n\t\t}\n\t\treturn t;\n\t}\n\t\n\t/**\n\t * Not really intended for external use since you could simply throw new E (msg). \n\t * <p>\n\t * <b>Usage</b> (if you must): <pre><code>\n\t * // ... somewhere within the bowels of your code ..\n\t * //\n\t * Assert.throwIt (\"why am i calling Assert.throwIt() when I could be throwing myself?\", YourRuntimeException.class);\n\t * </code> </pre>\n\t * @param <E> {@link RuntimeException} subclass to to throw\n\t * @param msg message to set in the exception\n\t * @param clazz the Class of E\n\t * @throws E your requested exception (unless reflection instantiate failed, \n\t *        in which case it will be a plain old {@link RuntimeException})\n\t */\n\tprivate static final <E extends RuntimeException> \n\tvoid throwIt \n\t\t(String msg, Class<E> clazz) \n\tthrows E \n\t{\n\t\t// TODO: isolate parts of this for our logger\n\t\t// TODO: hey - a simple logger ...\n\t\t// 1 - get the current stack trace and filter it\n\t\t//\n\t\tint fidx = 0;\n\t\tStackTraceElement ste[] =Thread.currentThread().getStackTrace();\n\t\tint j=0;\n\t\tfor(StackTraceElement e : ste){\n\t\t\tj++;\n\t\t\tif(e.getClassName().equals(Assert.class.getName())) fidx = j;\n\t\t}\n\t\tStackTraceElement[] filtered = new StackTraceElement[ste.length-fidx];\n\t\tfor(int i=fidx; i<ste.length; i++) filtered[i-fidx]=ste[i];\n\n\t\t// 2- get info about the source of the call (aka where the assertion failed)\n\t\t//\n\t\tStackTraceElement src = filtered[0];\n\t\tString simpleClassName = src.getClassName().substring(src.getClassName().lastIndexOf('.')+1);\n\t\tint scni = src.getClassName().indexOf(simpleClassName) > 0 ? src.getClassName().indexOf(simpleClassName)-1 : 0;\n\t\tString packageName = src.getClassName().substring(0, scni);\n\t\t\n\t\t@SuppressWarnings(\"boxing\")\n\t\tString info = new Formatter().format(\"%s in method %s.%s() [file: %s line:%d - package: %s]\", msg,\n\t\t\t\tsimpleClassName, src.getMethodName(), src.getFileName(), src.getLineNumber(), packageName).toString();\n\n\t\t// 3- throw the exception\n\t\t//\n\t\tRuntimeException rte = new IllegalArgumentException(info); // in case we can't instantiate the E class\n\t\ttry {\n\t\t\trte = clazz.getDeclaredConstructor(String.class, Throwable.class).newInstance(info, rte);\n\t\t}\n\t\tcatch (InstantiationException e) { e.printStackTrace(); }\n\t\tcatch (IllegalAccessException e) { e.printStackTrace(); }\n\t\tcatch (IllegalArgumentException e) { e.printStackTrace(); }\n\t\tcatch (SecurityException e) { e.printStackTrace(); }\n\t\tcatch (InvocationTargetException e) { e.printStackTrace(); }\n\t\tcatch (NoSuchMethodException e) { e.printStackTrace(); }\n\t\t\n\t\t// 4- use the filtered stacktrace from (1)\n\t\trte.setStackTrace(filtered);\n\t\t\n\t\t// 5- its coming your way ... catch!\n\t\tthrow rte;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/Convert.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\n\n/**\n * Perhaps a silly hack, but proven to speed things up.\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 02, 2009\n * @since   alpha.0\n * \n */\npublic class Convert {\n\t\n\t// ------------------------------------------------------------------------\n\t// Constants\n\t// ------------------------------------------------------------------------\n\tpublic static final int \t\tINT_P_65535 = 65535;\n\tpublic static final int \t\tINT_N_65535 = 0 - INT_P_65535;\n\tprivate static final byte[][]   i2b_65535 = new byte[INT_P_65535+1][];\n\tprivate static final byte       BYTE_MINUS = (byte) '-';\n\tprivate static final byte       BYTE_PLUS = (byte) '+';\n\tprivate static final byte\t    BYTE_ZERO = (byte) '0';\n\tprivate static final byte\t    BYTE_NINE = (byte) '9';\n\n\tprivate static final int\tMAX_POSITIVE_32_BIT_DIGITS\t= 10;\n\tprivate static final int\tMAX_POSITIVE_64_BIT_DIGITS\t= 19;\n\t\n\t// ------------------------------------------------------------------------\n\t// public Interface\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * return the bytes of the string representation of the integer.  Perhaps\n\t * should be called getNumberBytes, or perhaps getHumanReadableBytes()  \n\t * Ex:  444 => \"444\".getBytes() => new byte[3]={52, 52, 52}\n\t * \n\t * If representation is not in our cache or too high (larger than Convert#INT_P_65535 )\n\t * then it will return whatever we would get from {@link Convert#toBytes(int)} which is\n\t * using JDK libs for the same.  \n\t * \n\t * The whole point here is to be faster since we need to convert numbers to the byte array \n\t * of their string representation a lot in JRedis for the protocol and to cut out the \n\t * unnecessary step of creating a new string simply because there apparently isn't any other\n\t * way in JDK to go from a number to the bytes of its textual representation. (!)  \n\t * \n\t * @param i\n\t * @param signed\n\t * @return\n\t */ \n\tpublic static final byte[] toBytes(int i){\n\t\tif(i < INT_N_65535 || i > INT_P_65535) {\n\t\t\treturn Integer.toString(i).getBytes();\n\t\t}\n\t\tfinal int absi = Math.abs(i);\n\t\tfinal byte[] cachedData = i2b_65535[absi];\n\t\tfinal byte[] data;\n\t\tif(cachedData == null) {\n\t\t\tdata = Integer.toString(absi).getBytes();\n\t\t\ti2b_65535[absi] = data;\n\t\t}\n\t\telse {\n\t\t\tdata = cachedData;\n\t\t}\n\t\treturn i >= 0 ? data : getNegativeNumberBytes(data);\n\t}\n\n\t/**\n\t * Will delegate to {@link Convert#getBytes(int)} if the 'long' number is actually\n\t * within the range of our int cache, otherwise it will return the bytes using std\n\t * JDK mechanisms.\n\t * @param lnum\n\t * @return\n\t */\n\tpublic static final byte[] toBytes(long lnum){\n\t\tif(lnum >= INT_N_65535 && lnum <= INT_P_65535) \n\t\t\treturn toBytes((int)lnum);\n\t\t\n\t\treturn Long.toString(lnum).getBytes();\n\t}\n\t\n\tpublic static final byte[] toBytes(double dnum){\n\t\treturn Double.toString(dnum).getBytes();\n\t}\n\t/**\n\t * Converts the byte[]s of the ASCII representation of a decimal number to an int.  \n\t * \n\t * <p>Expects a byte array of no more than {@link Convert#MAX_POSITIVE_32_BIT_DIGITS} bytes in length\n\t * after accounting for potential leading byte indicating the sign of the number representation.\n\t * 9 bytes (for a positive integer).  \n\t *\n\t * @param potentiallySignedAsciiBytes, for example {49, 49, 52} (\"114\")\n\t * @return\n\t * @throw IllegalArgumentException if buffer contains anything other than values 48 to 57\n\t */\n\tpublic static final int toInt(final byte[] potentiallySignedAsciiBytes, final int offsetin, final int len) throws IllegalArgumentException\n\t{\n\t\tint offset = offsetin;\n\t\tfinal byte[] buff = potentiallySignedAsciiBytes; // lets use a sensible name ;)\n\t\tif(null == buff) throw new IllegalArgumentException (\"Null input\");\n\t\tif(len > buff.length) throw new IllegalArgumentException (\"buffer length of \" + buff.length + \" less than the spec'd len \" + len);\n\n\t\tboolean negative = false;\n\t\tint digitCnt = len;\n\t\tfinal byte bs = buff[offset];\n\t\tif(bs ==BYTE_MINUS || bs == BYTE_PLUS){\n\t\t\tif(bs == BYTE_MINUS) negative = true;\n\t\t\toffset++;\n\t\t\tdigitCnt--;\n\t\t}\n\t\tif(digitCnt > MAX_POSITIVE_32_BIT_DIGITS) throw new IllegalArgumentException (\"This \\\"int\\\" has more digits than a 32 bit signed number:\" + digitCnt);\n\t\t\n\t\t// lets do it\n\t\tint value = 0;\n\t\tfor(int p = 0; p < digitCnt; p++){\n\t\t\tfinal byte b = buff[offset+p];\n\t\t\tif(b < BYTE_ZERO || b > BYTE_NINE) throw new IllegalArgumentException(\"That's not a number!  byte value: \" + b);\n\t\t\tvalue = value*10 + b - BYTE_ZERO;\n\t\t}\n\t\tif(negative) value = 0 - value;\n\t\t\n\t\treturn value;\n\t}\n\t\n\t/**\n\t * Its just like (really! :) {@link Convert#toInt(byte[], int, int)} but for {@link Long} values.  Max number of digits \n\t * is now {@link Convert#MAX_POSITIVE_64_BIT_DIGITS}.  \n\t * \n\t * @param potentiallySignedAsciiBytes\n\t * @param offset\n\t * @param len\n\t * @return\n\t * @throws IllegalArgumentException\n\t */\n\tpublic static final long toLong(byte[] potentiallySignedAsciiBytes, final int offsetin, int len) throws IllegalArgumentException\n\t{\n\t\tint offset = offsetin;\n\t\tfinal byte[] buff = potentiallySignedAsciiBytes; // lets use a sensible name ;)\n\t\tif(null == buff) throw new IllegalArgumentException (\"Null input\");\n\t\tif(len > buff.length) throw new IllegalArgumentException (\"buffer length of \" + buff.length + \" less than the spec'd len \" + len);\n\n\t\tboolean negative = false;\n\t\tint digitCnt = len;\n\t\tfinal byte bs = buff[offset];\n\t\tif(bs ==BYTE_MINUS || bs == BYTE_PLUS){\n\t\t\tif(buff[offset]==BYTE_MINUS) negative = true; \n\t\t\toffset++;\n\t\t\tdigitCnt--;\n\t\t}\n\t\tif(digitCnt > MAX_POSITIVE_64_BIT_DIGITS) throw new IllegalArgumentException (\"This \\\"int\\\" has more digits than a 32 bit signed number:\" + digitCnt);\n\t\t\n\t\t// lets do it\n\t\tlong value = 0;\n\t\tfor(int p = 0; p < digitCnt; p++){\n\t\t\tfinal byte b = buff[offset+p];\n\t\t\tif(b < BYTE_ZERO || b > BYTE_NINE) throw new IllegalArgumentException(\"That's not a number!  byte value: \" + b);\n\t\t\tvalue = value*10 + b - BYTE_ZERO;\n\t\t}\n\t\tif(negative) value = 0 - value;\n\t\t\n\t\treturn value;\n\t}\n\t\n\t/**\n\t * @param potentiallySignedBytes\n\t * @return\n\t * @throws IllegalArgumentException\n\t */\n\tpublic static final int toInt(byte[] potentiallySignedBytes) throws IllegalArgumentException\n\t{\n\t\tif(null == potentiallySignedBytes) throw new IllegalArgumentException (\"null input\");\n\t\treturn toInt(potentiallySignedBytes, 0, potentiallySignedBytes.length);\n\t}\n\t\n\t/**\n\t * @param potentiallySignedBytes\n\t * @return\n\t * @throws IllegalArgumentException\n\t */\n\tpublic static final long toLong(byte[] potentiallySignedBytes) throws IllegalArgumentException\n\t{\n\t\tif(null == potentiallySignedBytes) throw new IllegalArgumentException (\"null input\");\n\t\treturn toLong(potentiallySignedBytes, 0, potentiallySignedBytes.length);\n\t}\n\t\n\t/**\n\t * TODO: optimize.\n\t * @param potentiallySignedBytes\n\t * @return\n\t * @throws IllegalArgumentException\n\t */\n\tpublic static final double toDouble (byte[] stringRepOfDoublePrecisionBytes) throws IllegalArgumentException\n\t{\n\t\tdouble dnum = 0;\n\t\tif(null == stringRepOfDoublePrecisionBytes) throw new IllegalArgumentException (\"null input\");\n\t\ttry {\n\t\t\tdnum = Double.parseDouble(new String(stringRepOfDoublePrecisionBytes));\n\t\t}\n\t\tcatch (Exception e){\n\t\t\tthrow new IllegalArgumentException(\"\", e);\n\t\t}\n\t\treturn dnum;\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Inner ops\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @param unsigned\n\t * @return\n\t */\n\tprivate static final byte[] getNegativeNumberBytes(byte[] unsigned){\n\t\tint unsigned_length = unsigned.length;\n\t\tbyte[] data = new byte[unsigned_length+1];\n\t\tdata [0] = BYTE_MINUS;\n\t\tSystem.arraycopy(unsigned, 0, data, 1, unsigned_length);\n\t\treturn data;\n\t}\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/DefaultCodec.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.io.Serializable;\nimport java.io.UnsupportedEncodingException;\nimport java.nio.charset.Charset;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.jredis.JRedis;\nimport org.jredis.semantics.KeyCodec;\n\n/**\n * Note that this is the one element of this package that is most likely to change\n * drastically.  It is provided, for now, as a helper for using {@link JRedis}.\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, 04/02/09\n * @since   alpha.0\n * \n */\npublic class DefaultCodec {\n\tpublic static class Keys<K extends Object> implements KeyCodec<K>{\n\t\tpublic enum SupportedType {\n\t\t\tSTRING (),\n\t\t\tBYTES ();\n\t\t}\n\n\t\t/* (non-Javadoc)  @see org.jredis.Codec#decode(byte[]) */\n\t\t@Override\n\t\tpublic K decode(byte[] bytes) {\n\t\t\tthrow new RuntimeException(\"TODO Auto-generated Codec<K>#decode stub -- NOT IMPLEMENTED\");\n\t\t}\n\n\t\t/* (non-Javadoc)  @see org.jredis.Codec#encode(java.lang.Object) */\n\t\t@Override\n\t\tpublic byte[] encode(K object) {\n\t\t\tthrow new RuntimeException(\"TODO Auto-generated Codec<K>#encode stub -- NOT IMPLEMENTED\");\n\t\t}\n\n\t\t/* (non-Javadoc)  @see org.jredis.Codec#supports(java.lang.Class) */\n\t\t@Override\n\t\tpublic boolean supports(Class<?> type) {\n\t\t\tthrow new RuntimeException(\"TODO Auto-generated Codec<K>#supports stub -- NOT IMPLEMENTED\");\n\t\t}\n\t}\n\n\tpublic final static String SUPPORTED_CHARSET_NAME = \"UTF-8\";\t// this is for jdk 1.5 compliance\n\tpublic final static Charset SUPPORTED_CHARSET = Charset.forName (\"UTF-8\");\n\t\n\t/**\n\t * This helper method is mainly intended for use with a list of\n\t * keys returned from Redis, given that it will use the UTF-8\n\t * {@link Charset} in decoding the byte array.  Typical use would\n\t * be to convert from the List<byte[]> output of {@link JRedis#keys()}\n\t * \n\t * @param bytearray\n\t * @return\n\t */\n\tpublic static final List<String> toStr (List<byte[]> bytearray) {\n\t\tif(null == bytearray) return null;\n\t\tList<String> list = new ArrayList<String>(bytearray.size());\n\t\tfor(byte[] b : bytearray) \n\t\t\tif(null!= b) \n\t\t\t\tlist.add(toStr(b)); \n\t\t\telse \n\t\t\t\tlist.add(null);\n\t\treturn list;\n\t}\n\tpublic static final Map<String, byte[]> toDataDictionary (Map<byte[], byte[]> binaryMap) {\n\t\tif(null == binaryMap) return null;\n\t\tMap<String, byte[]> dict = new HashMap<String, byte[]>(binaryMap.size());\n\t\tfor(byte[] bkey : binaryMap.keySet()) \n\t\t\tif(null!= bkey) \n\t\t\t\tdict.put(toStr(bkey), binaryMap.get(bkey)); \n\t\treturn dict;\n\t}\n\t/**\n\t * @param bytes\n\t * @return new {@link String#String(byte[])} or null if bytes is null. \n\t */\n\tpublic static final String toStr (byte[] bytes) {\n        String str = null;\n        if(null != bytes) {\n\t\t\ttry {\n\t\t\t\tstr = new String(bytes, SUPPORTED_CHARSET_NAME);\n\t        }\n\t        catch (UnsupportedEncodingException e) {\n\t\t        e.printStackTrace();\n\t        }\n        }\n        return str;\n//\t\treturn new String(bytes, SUPPORTED_CHARSET); // Java 1.6 only\n\t}\n\t\n\tpublic static final byte[] encode(String value) {\n\t\tbyte[] bytes = null;\n\t\ttry {\n\t        bytes = value.getBytes(SUPPORTED_CHARSET_NAME);\n        }\n        catch (UnsupportedEncodingException e) {\n\t        // TODO Auto-generated catch block\n\t        e.printStackTrace();\n        }\n        return bytes;\n//\t\treturn value.getBytes(SUPPORTED_CHARSET);\n\t}\n\t\n//\t/**\n//\t * @param bytes\n//\t * @return\n//\t */\n//\t@Deprecated\n//\tpublic static final Integer toInt (byte[]  bytes) {\n//\t\treturn new Integer(toStr (bytes));\n//\t}\n\n\t/**\n\t * NOTE: Isn't this already in {@link Convert#toLong(byte[])}?\n\t * TODO: get rid of this method\n\t * This helper method will convert the byte[] to a {@link Long}.\n\t * @param bytes\n\t * @return\n\t */\n//\t@Deprecated\n\t@SuppressWarnings(\"boxing\")\n\tpublic static final Long toLong (byte[]  bytes) {\n//\t\treturn new Long (toStr (bytes));\n\t\treturn Convert.toLong(bytes);\n\t}\n\t\n\t@SuppressWarnings(\"boxing\")\n\tpublic static final List<Long> toLong(List<byte[]> bytearray){\n\t\tif(null == bytearray) return null;\n\t\tList<Long> list = new ArrayList<Long>(bytearray.size());\n\t\tfor(byte[] b : bytearray) list.add(Convert.toLong(b));\n\t\treturn list;\n\t}\n\n\t/**\n     * @param bs bytes of the ascii string representation of a double number. E.g. \"2.002\".getBytes()\n     * @return\n     */\n    public static double toDouble (byte[] bs) {\n\t    return Convert.toDouble(bs);\n    }\n\t@SuppressWarnings(\"boxing\")\n\tpublic static final List<Double> toDouble(List<byte[]> bytearray){\n\t\tif(null == bytearray) return null;\n\t\tList<Double> list = new ArrayList<Double>(bytearray.size());\n\t\tfor(byte[] b : bytearray) list.add(Convert.toDouble(b));\n\t\treturn list;\n\t}\n\n\t/**\n\t * This helper method will assume the List<byte[]> being presented is the list returned\n\t * from a {@link JRedis} method such as {@link JRedis#smembers(String)}, and that this\n\t * list contains the {@link DefaultCodec#encode(Serializable)}ed bytes of the parametric type <code>T</code>.\n\t * <p>\n\t * Specifically, this method will instantiate an {@link ArrayList} for type T, of equal \n\t * size to the size of bytelist {@link List}.  Then it will iterate over the byte list \n\t * and for each byte[] list item call {@link DefaultCodec#decode(byte[])}.\n\t * <p>\n\t * <b>Usage example:</b>\n\t * <pre><code>\n\t * List<byte[]>  memberBytes = redis.smembers(\"my-object-set\");\n\t * List<MySerializableClass>  members = decode (memberBytes);\n\t * </code></pre>\n\t * @param <T>\n\t * @param byteList\n\t * @return\n\t */\n\t@SuppressWarnings(\"unchecked\")\n\tpublic static final <T extends Serializable>  \n\tList<T> decode (List<byte[]> byteList) {\n\t\tif(null == byteList) return null;\n\t\tList<T>\t\tobjectList = new ArrayList<T>(byteList.size());\n\t\tfor (byte[] bytes : byteList) {\n\t\t\tif(null != bytes){\n\t\t\t\tT object = (T) decode(bytes);\n\t\t\t\tobjectList.add (object);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tobjectList.add(null);\n\t\t\t}\n\t\t}\n\t\treturn objectList;\n\t}\n\t/**\n\t * This helper method will assume that the byte[] provided are the serialized\n\t * bytes obtainable for an instance of type T obtained from {@link ObjectOutputStream}\n\t * and subsequently stored as a value for a Redis key (regardless of key type). \n\t * <p>Specifically, this method will simply do:\n\t * <pre><code>\n\t * ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(bytes));\n\t * t = (T) oin.readObject();\n\t * </code></pre>\n\t * and returning the reference <i>t</i>, and throwing any exceptions encountered along\n\t * the way.\n\t * <p>\n\t * This method is the decoding peer of {@link DefaultCodec#encode(Serializable)}, and it is\n\t * assumed (and certainly recommended) that you use these two methods in tandem.\n\t * <p>\n\t * Naturally, all caveats, rules, and considerations that generally apply to {@link Serializable}\n\t * and the Object Serialization specification apply.\n\t * @param <T>\n\t * @param bytes\n\t * @return the instance for <code><b>T</b></code>\n\t */\n\t@SuppressWarnings(\"unchecked\")\n\tpublic static final <T extends Serializable>  \n\tT  decode(byte [] bytes) \n\t{\n\t\tT t = null;\n\t\tException thrown = null;\n\t\ttry {\n\t\t\tObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(bytes));\n\t\t\tt = (T) oin.readObject();\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t\tthrown = e;\n\t\t}\n\t\tcatch (ClassNotFoundException e) {\n\t\t\te.printStackTrace();\n\t\t\tthrown = e;\n\t\t}\n\t\tcatch (ClassCastException e) {\n\t\t\te.printStackTrace();\n\t\t\tthrown = e;\n\t\t}\n\t\tfinally {\n\t\t\tif(null != thrown)\n\t\t\t\tthrow new RuntimeException(\n\t\t\t\t\t\t\"Error decoding byte[] data to instantiate java object - \" +\n\t\t\t\t\t\t\"data at key may not have been of this type or even an object\", thrown\n\t\t\t\t);\n\t\t}\n\t\treturn t;\n\t}\n\t\n\t/**\n\t * This helper method will serialize the given serializable object of type T\n\t * to a byte[], suitable for use as a value for a redis key, regardless of the key\n\t * type.\n\t * \n\t * @param <T>\n\t * @param obj\n\t * @return\n\t */\n\tpublic static final <T extends Serializable>  byte[]  encode(T obj) {\n\t\tbyte[] bytes = null;\n\t\ttry {\n\t\t\tByteArrayOutputStream bout = new ByteArrayOutputStream();\n\t\t\tObjectOutputStream out = new ObjectOutputStream(bout);\n\t\t\tout.writeObject(obj);\n\t\t\tbytes = bout.toByteArray();\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t\tthrow new RuntimeException(\"Error serializing object\"+obj+\" => \" + e);\n\t\t}\n\t\treturn bytes;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/FastBufferedInputStream.java",
    "content": "package org.jredis.ri.alphazero.support;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport org.jredis.ProviderException;\n\n/**\n * Extension of {@link java.io.InputStream} that uses the enclosing instance's\n * {@link InputStream} its data source. This is not supposed to be a general purpose\n * implementation.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Sep 5, 2009\n * @since   alpha.0\n * \n */\npublic final class FastBufferedInputStream extends java.io.InputStream {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/** data buffer (cache) */\n\tprivate byte[] buffer;\n\n\t/** current (read) offset of {@link FastBufferedInputStream#buffer} */\n\tprivate int   offset = 0;\n\n\t/** \n\t * underlying input stream read buffer -- the size of this buffer determines the\n\t * maximum bytes read  \n\t */\n\tfinal \n\tprivate byte[] iobuffer;\n\n\t/** underying input stream */\n\tfinal\n\tprivate InputStream in;\n\n\t// ------------------------------------------------------------------------\n\t// Constructor\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @param in the input source\n\t * @param bufferSize size of the {@link FastBufferedInputStream#iobuffer}\n\t * \n\t */\n\tpublic FastBufferedInputStream (InputStream in, int bufferSize) {\n\t\tthis.in = in;\n\t\tbuffer = new byte [0];\n\t\tiobuffer = new byte[bufferSize];\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Inner Ops\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Get more bytes from the underling {@link InputStream}.  \n\t * Only reads from input source if len exceeds available data in \n\t * {@link FastBufferedInputStream#buffer}.\n\t * <p>\n\t * This call will block until (minimally) len bytes have been read.\n\t * \n\t * @param len\n\t * @throws IOException if a read on the underlying stream returns 0 length bytes.\n\t * This (obviously) shouldn't happen but if it does, it would be treated as an exception.\n\t */\n\t@SuppressWarnings(\"boxing\")\n\tprivate final int getMoreBytes (int len) throws IOException {\n\n\t\t// hit the date source until we have enough bytes\n\t\t// compact (reset offset to 0) on first copy\n\t\tint rlen = 0;\n\t\twhile (len > buffer.length - offset) {\n\t\t\tint c = in.read(iobuffer, 0, iobuffer.length);\n\t\t\tif(c==-1) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\telse if(c > 0){\n\t\t\t\tint bufflen = buffer.length - offset;\n\t\t\t\trlen+=c;\n\t\t\t\tbyte[] newbuffer = new byte[bufflen + c];\n\t\t\t\tSystem.arraycopy(buffer, offset, newbuffer, 0, bufflen);\n\t\t\t\tSystem.arraycopy(iobuffer, 0, newbuffer, bufflen, c);\n\t\t\t\toffset = 0;\n\t\t\t\tbuffer = newbuffer;\n\t\t\t}\n\t\t\telse {// should never happen per contract of inputstream ...\n\t\t\t\tLog.bug (String.format(\"ZERO! <= %d\\n\", c));\n\t\t\t\tthrow new IOException (\"input stream read return 0 bytes!\");\n\t\t\t}\n\t\t}\n\t\treturn rlen;\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface: InputStream\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * <b>Note:</b><br>\n\t * Breaks the contract of the {@link InputStream#read(byte[], int, int)} \n\t * to the extent that <b>call will block</b> on the underlying {@link InputStream} \n\t * until it gets all the <code>len</code> bytes specified.\n\t * <p>\n\t * Also, this call will return -1 if and only if it (a) needs to get more \n\t * data by calling {@link FastBufferedInputStream#getMoreBytes(int)},\n\t * and (b) that call returns -1.  Note that it is possible, in a general \n\t * context, that -1 is returned but there is previously accumulated data in \n\t * {@link FastBufferedInputStream#buffer} and thus \n\t * {@link FastBufferedInputStream#available()} returns a non zero positive \n\t * integer which is less than specified <b>len</b>.  But that is not expected\n\t * in the specific context of Redis protocol.\n\t * \n\t * @see java.io.InputStream#read(byte[], int, int)\n\t */\n\tint maxRead = 0;\n\t@Override\n\tpublic int read (byte[] b, int off, int len) throws IOException {\n\t\tif (off < 0 || off >= b.length || len < 0 || off + len > b.length) {\n\t\t\tthrow new ArrayIndexOutOfBoundsException();\n\t\t}\n\t\tint available = buffer.length - offset;\n\t\tif(len > available) {\n\t\t\tint c = getMoreBytes (len);  // this is a potentially blocking call\n\t\t\tif(c==-1) return -1;\n\t\t\telse if(c < len - available) \n\t\t\t\tthrow new ProviderException (\"Bug: getMoreBytes() returned less bytes than requested.  c=\"+c+\" len=\" + len + \"available=\" + available);\n\t\t}\n\n\t\tif(len == 1){\n\t\t\tb[off] = buffer[offset];\n\t\t}\n\t\telse {\n\t\t\tSystem.arraycopy(buffer, offset, b, off, len);\n\t\t}\n\n\t\toffset += len;\n\t\treturn len;\n\t}\n\t\n\t/** \n\t * @return the length of data available without making call\n\t * to the underlying stream.\n\t * @see java.io.InputStream#available()\n\t */\n\t@Override\n\tpublic int available () throws IOException {\n\t\treturn buffer.length - offset;\n\t}\n\n\t/**\n\t * {@link InputStream#mark(int)} is <b>not supported</b>.\n\t * @see java.io.InputStream#markSupported()\n\t */\n\t@Override\n\tpublic boolean markSupported () { return false; }\n\n\t/* (non-Javadoc)\n\t * @see java.io.InputStream#read(byte[])\n\t */\n\t@Override\n\tpublic int read (byte[] b) throws IOException { return read (b, 0, b.length); }\n\n\t/* (non-Javadoc)\n\t * @see java.io.InputStream#read()\n\t */\n\t@Override\n\tpublic int read () throws IOException { \n\t\tbyte[] b = new byte[1];\n\t\tint c = read(b, 0, 1);\n\t\tif(c == -1) return -1;\n\t\treturn b[0];\n\t}\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/GZip.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.util.zip.GZIPInputStream;\nimport java.util.zip.GZIPOutputStream;\n\n/**\n * GZip (de)compression utility methods.\n * @author  Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Aug 24, 2009\n * @since   alpha.0\n * \n */\n\npublic class GZip {\n    /**\n     * @param data\n     * @return\n     */\n    public static final byte[] compress(byte[] data){\n    \tByteArrayOutputStream out = new ByteArrayOutputStream();\n    \ttry {\n            GZIPOutputStream gzipOutputtStream = new GZIPOutputStream(out);\n            gzipOutputtStream.write(data);\n            gzipOutputtStream.close();\n        }\n        catch (IOException e) {\n\t\t\tthrow new RuntimeException(\"Failed to GZip compress data\", e);\n        }\n        return out.toByteArray();\n    }\n    \n    /**\n     * @param data\n     * @return\n     */\n    public static final byte[] decompress(byte[] data){\n\t\tByteArrayOutputStream buffer = null;\n\t\tGZIPInputStream gizpInputStream= null;\n\t\ttry {\n\t\t\tbuffer = new ByteArrayOutputStream();\n\t\t\tgizpInputStream = new GZIPInputStream(new ByteArrayInputStream(data));\n\t\t\tint n=-1;\n\t\t\t@SuppressWarnings(\"unused\")\n\t\t\tint tot = 0;\n\t\t\tbyte[] _buffer = new byte[1024 * 12];\n\t\t\twhile(-1 != (n = gizpInputStream.read(_buffer))){\n\t\t\t\tbuffer.write(_buffer, 0, n);\n\t\t\t\ttot += n;\n\t\t\t}\n\t\t\tgizpInputStream.close();\n\t\t\tbuffer.close();\n\t\t} \n\t\tcatch (IOException e) {\n\t\t\tthrow new RuntimeException(\"Failed to GZip decompress data\", e);\n\t\t} \n\t\treturn buffer.toByteArray();\n    }\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/Log.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\nimport java.util.Date;\nimport java.util.logging.Level;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\n\n/**\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 02, 2009-2011\n * @since   alpha.0\n * \n */\npublic class Log {\n\n\tpublic final static Logger logger = Logger.getLogger(\"JRedis\");\n\tstatic {\n\t\tlogger.setUseParentHandlers(false);\n\t\tfinal Handler handler = new Log.Handler();\n\t\tfinal Formatter formatter = new Log.Formatter();\n\t\thandler.trySetFormatter(formatter);\n\t\tlogger.addHandler(handler);\n\t}\n\tpublic enum Category { INFO, DEBUG, ERROR, PROBLEM, BUG }\n\n\t// the various 'just FYI's ...\n\tpublic static final void log (String msg)   { log (msg, (Object[])null); }\n\tpublic static final void log (String format, Object...args)   { \n\t\tlogger.info(String.format(format, args)); \n\t}\n\tpublic static final void debug (String msg) { debug(msg, (Object[])null); }\n\tpublic static final void debug (String format, Object...args) { \n\t\tlogger.log(Level.FINE, String.format(format, args)); \n\t}\n\n\t// the various 'error! run for covers', ... \n\tpublic static final void error (String msg)   { _error (Category.ERROR, msg); }\n\tpublic static final void error (String msg, Throwable t)   { logger.log(Level.SEVERE, msg, t); }\n\tpublic static final void error (String msg, Object...args) { _error (Category.ERROR, msg, args); }\n\n\tpublic static final void problem (String msg) { _error (Category.PROBLEM, msg); }\n\tpublic static final void problem (String msg, Object...args) { _error (Category.PROBLEM, msg, args); }\n\n\tpublic static final void bug (String msg)     { _error (Category.BUG, msg); }\n\tpublic static final void bug (String msg, Object...args) { _error (Category.BUG, msg, args); }\n\n\tprivate static final void _error (final Category cat, final String msg, final Object...args) {\n\t\tfinal String _msg = String.format(msg, args);\n\t\tif(cat.equals(Category.ERROR))\n\t\t\tlogger.severe(String.format(\"%s\", _msg));\n\t\telse\n\t\t\tlogger.log(Level.WARNING, String.format(\"%s: %s\", cat, _msg));\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Inner Classes | formatter and handler\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Default handler for JRedis.Log\n\t * @author alphazero\n\t */\n\tpublic static class Handler extends java.util.logging.Handler {\n\t\t/**\n\t\t * Try and set the formatter -- may not be possible if\n\t\t * run in containers, etc. due to security checks.\n\t\t * @param fmt \n\t\t */\n\t\tprivate java.util.logging.Formatter formatter;\n\t\tfinal void trySetFormatter(Formatter fmt){\n\t\t\ttry {\n\t\t\t\tsuper.setFormatter(fmt);\n\t\t\t} catch (Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tfinally {\n\t\t\t\tformatter = getFormatter();\n\t\t\t}\n\t\t}\n\t\t@Override final\n\t\tpublic void publish(LogRecord record) {\n\t\t\tSystem.err.print(formatter.format(record));\n\t\t\tflush();\n\t\t}\n\t\t@Override final\n\t\tpublic void flush() {\n\t\t\tSystem.err.flush();\n\t\t}\n\t\t@Override final\n\t\tpublic void close() throws SecurityException {\n\t\t\tflush();\n\t\t}\n\t}\n\t/**\n\t * simple formatter for a single line log out.\n\t * @author alphazero\n\t */\n\tpublic static class Formatter extends java.util.logging.Formatter {\n\t\tfinal String LINESEP = System.getProperty(\"line.separator\");\n\t\t@SuppressWarnings(\"boxing\")\n\t\t@Override final\n\t\tpublic String format(LogRecord record) {\n\t\t\t// TODO: clean up the mess above and fix this.\n\t\t\tfinal Level level = record.getLevel();\n\t\t\tfinal String logger = record.getLoggerName();\n\t\t\tfinal String msg = record.getMessage();\n\t\t\tfinal Object[] msgparams = record.getParameters();\n\t\t\tfinal int tid = record.getThreadID();\n\t\t\tfinal long time = record.getMillis();\n\t\t\t\n\t\t\tString _msg = null;\n\t\t\tif(msgparams != null && msgparams.length > 0){\n\t\t\t\t_msg = String.format(msg, msgparams);\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_msg = msg;\n\t\t\t}\n\t\t\t\n\t\t\tfinal Date d = new Date(time);\n\t\t\treturn String.format(\"%014d %s %s[tid:%d] <%s>: %s%s\", time, d, logger, tid, level.getLocalizedName(), _msg, LINESEP);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/Signal.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.Condition;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * Non-reusable (disposable) signal class.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Oct 15, 2009\n * @since   alpha.0\n * \n */\npublic class Signal {\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/** underlying lock used for implementation */\n\tfinal Lock lock = new ReentrantLock();\n\t/** condition based on lock */\n\tfinal Condition signalled = lock.newCondition();\n\t/** Signal state */\n\tboolean isSignalled = false;\n\t\n\t// ------------------------------------------------------------------------\n\t// Public interface \n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * Blocking call awaits the signal for the specified duration.  \n\t * Multiple threads may call this method to wait signal. Ordering is not maintained.   \n\t * @param time duration in time units\n\t * @param unit time unit\n\t * @return true if timedout.  \n\t * @throws InterruptedException\n\t * @see Signal#signal()\n\t */\n\tpublic boolean await (long time, TimeUnit unit) throws InterruptedException {\n\t\tboolean timedout = false;\n\t\tlong nanosTimeout = unit.toNanos(time);\n\t\tlong timecheck = System.nanoTime();\n\t\tlock.lock();\n\t\ttry {\n\t\t\twhile(!isSignalled && nanosTimeout > 0L) {\n\t\t\t\ttimedout = signalled.await(time, unit);\n\t\t\t\tlong now = System.nanoTime();\n\t\t\t\tnanosTimeout -= now - timecheck;\n\t\t\t\ttimecheck = now;\n\t\t\t}\n\t\t}\n\t\tfinally { lock.unlock(); }\n\t\treturn timedout | isSignalled;\n\t}\n\t\n\t/**\n\t * Blocking call awaits the signal.  Multiple threads may call this method to wait signal.\n\t * Ordering is not maintained.   \n\t * @throws InterruptedException if interrupted while waiting\n\t * @see Signal#signal()\n\t */\n\tpublic void await () throws InterruptedException {\n\t\tlock.lock();\n\t\ttry {\n\t\t\twhile(!isSignalled) \n\t\t\t\tsignalled.await();\n\t\t}\n\t\tfinally { lock.unlock(); }\n\t}\n\t\n\t/**\n\t * Signals.  All waiters are signaled.\n\t */\n\tpublic void signal () {\n\t\tlock.lock();\n\t\ttry {\n\t\t\tisSignalled = true;\n\t\t\tsignalled.signalAll();\n\t\t}\n\t\tfinally { lock.unlock(); }\n\t}\n\t\n\t/**\n\t * Non-blocking call immediately returns with the current status of the signal.\n\t * @return true if signaled. \n\t */\n\tpublic boolean isSignalled() {\n\t\tboolean state = false;\n\t\tlock.lock();\n\t\ttry {\n\t\t\tstate = isSignalled;\n\t\t}\n\t\tfinally { lock.unlock(); }\n\t\treturn state;\n\t}\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/SortSupport.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.Future;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.RedisException;\nimport org.jredis.Sort;\nimport org.jredis.protocol.Command;\nimport org.jredis.ri.alphazero.semantics.DefaultKeyCodec;\n\n\npublic abstract class SortSupport implements Sort {\n\tprotected volatile boolean stores = false;\n//\tprotected final String key;\n\tprotected final byte[] keyBytes;\n//\tprotected SortSupport (String key, byte[] validatedKeyBytes){\n\tprotected SortSupport (byte[] validatedKeyBytes){\n//\t\tAssert.notNull(key, \"key for sort\", ClientRuntimeException.class);\n//\t\tthis.key = key;\n\t\tthis.keyBytes = validatedKeyBytes;\n\t}\n\t\n    public static final byte[]  CRLF = {(byte) 13, (byte)10};\n    public static final byte[]  SPACE = {(byte) 32};\n    public static final int     CRLF_LEN = CRLF.length;\n    public static final int     DELIMETER_LEN = SPACE.length;\n    public static final byte    ERR_BYTE    = (byte) 45; // -\n    public static final byte    OK_BYTE     = (byte) 43; // +\n    public static final byte    COUNT_BYTE  = (byte) 42; // *\n    public static final byte    SIZE_BYTE   = (byte) 36; // $\n    public static final byte    NUM_BYTE    = (byte) 58; // :\n    public static final byte    ASCII_ZERO  = (byte) 48; // 0\n\t    \n\tprivate List<byte[]> alphaSpec = new ArrayList<byte[]>();\n\tprivate List<byte[]> descSpec = new ArrayList<byte[]>();\n\tprivate List<byte[]> getSpec = new ArrayList<byte[]>();\n\tprivate List<byte[]> bySpec = new ArrayList<byte[]>();\n\tprivate List<byte[]> limitSpec = new ArrayList<byte[]>();\n\tprivate List<byte[]> storeSpec = new ArrayList<byte[]>();\n\t\n\tpublic Sort ALPHA() {\n//\t  String alphaSpecName = Command.Option.ALPHA.name();\n\t  alphaSpec.add(Command.Option.ALPHA.bytes);\n\t  return this; \n\t}\n\t\n\tpublic Sort DESC() {\n//      String sortSpecName = Command.Option.DESC.name();\n      descSpec.add(Command.Option.DESC.bytes);\n\n\t  return this;\n\t}\n\t\n\tpublic <K extends Object> Sort BY(K pattern) {\n//\t   String bySpecName = Command.Option.BY.name();\n\t   bySpec.add(Command.Option.BY.bytes);\n\t   bySpec.add(DefaultKeyCodec.provider().encode(pattern));\n\t   \n\t   return this; \n\t }\n\t\n\tpublic <K extends Object> Sort GET(K pattern) {\n//      String getSpecName = Command.Option.GET.name();\n      getSpec.add(Command.Option.GET.bytes);\n      getSpec.add(DefaultKeyCodec.provider().encode(pattern));\n      \n\t  return this;\n\t}\n\t\n\tpublic Sort LIMIT(long from, long count) {\n\t\tif(from < 0) {\n\t\t  throw new ClientRuntimeException(\"from in LIMIT clause: \" + from);\n\t\t}\n\t\t\n\t\tif(count <= 0) {\n\t\t  throw new ClientRuntimeException(\"count in LIMIT clause: \" + from);\n\t\t}\n\t\t\n//\t\tString limitSpecName = Command.Option.LIMIT.name();\n\t    String fromString = new Long(from).toString();\n\t    String countString = new Long(count).toString();\n\t    \n\t    limitSpec.add(Command.Option.LIMIT.bytes);\n\t    limitSpec.add(fromString.getBytes());\n\t    limitSpec.add(countString.getBytes());\n\t\t\n\t\treturn this;\n\t}\n\t\n\t/** Store the sort results in another key */\n\tpublic <K extends Object> Sort STORE (K destKey) {\n\t\tAssert.notNull(destKey, \"deskKey is null\", ClientRuntimeException.class);\n\t\t\n//\t\tString storeSpecName = Command.Option.STORE.name();\n\t\tstoreSpec.add(Command.Option.STORE.bytes);\n\t\tstoreSpec.add(DefaultKeyCodec.provider().encode(destKey));\n\t\t\n\t\tstores = true;\n\t\t\n\t\treturn this;\n\t}\n\t\n\tprivate final byte[][] buildSortCmd() {\n\t  ArrayList<byte[]> sortSpecs = new ArrayList<byte[]>();\n\t  \n\t  sortSpecs.addAll(bySpec);\n\t  sortSpecs.addAll(limitSpec);\n\t  sortSpecs.addAll(getSpec);\n\t  sortSpecs.addAll(descSpec);\n\t  sortSpecs.addAll(alphaSpec);\n\t  sortSpecs.addAll(storeSpec);\n\n\t  byte[][] sortCmd = new byte[sortSpecs.size() + 1][];\n\t  sortCmd[0] = keyBytes;\n\t  for (int i = 0; i < sortSpecs.size(); i++) {\n\t    sortCmd[i+1] = sortSpecs.get(i);//.getBytes();\n\t  }\n  \t  return sortCmd;\n\t}\n\n\t\n\tpublic List<byte[]> exec() throws IllegalStateException, RedisException {\n//\t    System.out.format(\"sort spec: [%S %S %S %S %S %S]\\n\", bySpec, limitSpec, getSpec, descSpec, alphaSpec, storeSpec);\n\t\tList<byte[]> res = null;\n\t\tif(!stores)\n\t\t\tres = execSort(buildSortCmd());\n\t\telse \n\t\t\tres = execSortStore(buildSortCmd());\n\t\treturn res;\n\t}\n\tpublic Future<List<byte[]>> execAsync() {\n//\t\tSystem.out.format(\"sort spec: [%S %S %S %S %S %S]\\n\", bySpec, limitSpec, getSpec, descSpec, alphaSpec, storeSpec);\n\t\tFuture<List<byte[]>>  res = null;\n\t\tif(!stores)\n\t\t\tres = execAsyncSort (buildSortCmd());\n\t\telse \n\t\t\tres = execAsyncSortStore(buildSortCmd());\n\t\treturn res;\n\t}\n\tprotected abstract List<byte[]> execSort (byte[]... fullSortCmd) throws IllegalStateException, RedisException;\n\tprotected abstract List<byte[]> execSortStore (byte[]... fullSortCmd) throws IllegalStateException, RedisException;\n\tprotected abstract Future<List<byte[]>> execAsyncSort (byte[]... fullSortCmd);\n\tprotected abstract Future<List<byte[]>> execAsyncSortStore (byte[]... fullSortCmd);\n}"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/alphazero/support/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * Utility classes to support this implementation.\n */\npackage org.jredis.ri.alphazero.support;"
  },
  {
    "path": "core/ri/src/main/java/org/jredis/ri/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * This the top level package for the reference implementations of JRedis.\n * This package may in the future itself contain support classes for the\n * {@link org.jredis.JRedis} interface and other types in the root package\n * as barebones clients to redis.\n * <p>\n * Child packages contain reference implementations of optional packages\n * of JRedis.   \n */\npackage org.jredis.ri;"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/JRedisTestSuiteBase.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri;\n\nimport static org.testng.Assert.fail;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.Set;\n\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.BeforeSuite;\nimport org.testng.annotations.Parameters;\n\n/**\n * The grand daddy of all TestNG test classes for the RI test suites and classes,\n * this class will get loaded with all the <b>general</b> parameters we use for \n * testing, namely host, port, password, and the DBs we will use to test (which \n * will be flushed!)\n * <p>\n * Defaults for values are defined in this class so no testng.xml is required. Change\n * values in master pom as required.\n * <p>\n * [Note: as of now, these are defined in the master pom.]\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 17, 2009\n * @since   alpha.0\n * \n */\n\n//TODO: get rid of NG in class name\n\npublic abstract class JRedisTestSuiteBase<T> extends ProviderTestBase<T>{\n\t// ------------------------------------------------------------------------\n\t// General RI Test Suite Parameters with default values\n\t// ------------------------------------------------------------------------\n\tprotected String password = \"jredis\";\n\tprotected String host = \"localhost\";\n\tprotected int port = 6379;\n\tprotected int db1 = 13;\n\tprotected int db2 = 10;\n\n\t// ------------------------------------------------------------------------\n\t// General RI Test Suite Parameters with default values to avoid XML\n\t// ------------------------------------------------------------------------\n\tprotected int\tSMALL_DATA =  128;\n\tprotected int\tMEDIUM_DATA = 1024 * 2;\n\tprotected int\tLARGE_DATA =  1024 * 512;\n\tprotected int\tSMALL_CNT = 10;\n\tprotected int\tMEDIUM_CNT = 1000;\n\tprotected int\tLARGE_CNT = 100000;\n\n\tprotected int\texpire_secs = 1;\n\tprotected long\texpire_wait_millisecs = 1;\n\n\tprotected final Random random = new Random(System.currentTimeMillis());\n\n\t// we'll use these for values \n\tprotected final byte[]\t\t\temptyBytes = new byte[0];\n\tprotected final String\t\t\temptyString = \"\";\n\tprotected final List<byte[]>\tdataList = new ArrayList<byte[]>();\n\tprotected final List<byte[]>\tsparseList = new ArrayList<byte[]>();\n\tprotected final List<TestBean>\tobjectList = new ArrayList<TestBean>();\n\tprotected final List<String>\tstringList = new ArrayList<String>();\n\tprotected final List<String>\tpatternList = new ArrayList<String>();\n\tprotected final List<Integer>\tintList = new ArrayList<Integer>();\n\tprotected final List<Long>\t\tlongList= new ArrayList<Long>();\n\tprotected final List<Double>\tdoubleList= new ArrayList<Double>();\n\n\tprotected final Set<String>\t\tuniqueSet = new HashSet<String> ();\n\tprotected final Set<String>\t\tcommonSet = new HashSet<String> ();\n\tprotected final Set<String>\t\tset1 = new HashSet<String> ();\n\tprotected final Set<String>\t\tset2 = new HashSet<String> ();\n\n\n\tprotected final String\t\t\tpatternA = \"_AAA_\";\n\n\tprotected final byte[]\t\t\tsmallData = getRandomBytes(SMALL_DATA);\n\tprotected final byte[]\t\t\tmediumData = getRandomBytes(MEDIUM_DATA);\n\tprotected final byte[]\t\t\tlargeData = getRandomBytes(LARGE_DATA);\n\n\tprotected final List<String>\tkeys = new ArrayList<String>();\n\n\tprotected int\t \t\tcnt;\n\tprotected String \t\tkey = null;\n\n\t@SuppressWarnings(\"unused\")\n\tprivate byte   \t\tbytevalue;\n\n\t@SuppressWarnings(\"unused\")\n\tprivate String\t\tstringvalue;\n\n\t@SuppressWarnings(\"unused\")\n\tprivate int\t\t\tintValue;\n\n\t@SuppressWarnings(\"unused\")\n\tprivate long\t\tlongValue;\n\n\t@SuppressWarnings(\"unused\")\n\tprivate TestBean \tobjectvalue;\n\n\n\n\t// ------------------------------------------------------------------------\n\t// General RI Test Suite Parameters init\n\t// ------------------------------------------------------------------------\n\t/**\n\t * This method sets up all the general test parameters for all\n\t * classes that inherit from it.\n\t * @param password password we'll use to authenticate\n\t * @param host host name\n\t * @param port port number\n\t * @param db1 db index for testing - will be flushed\n\t * @param db2 db index for testing - will be flushed\n\t */\n\t@Parameters({ \n\t\t\"jredis.test.password\", \n\t\t\"jredis.test.host\", \n\t\t\"jredis.test.port\",\n\t\t\"jredis.test.db.1\",\n\t\t\"jredis.test.db.2\",\n\n\t\t\"jredis.test.datasize.small\",\n\t\t\"jredis.test.datasize.medium\",\n\t\t\"jredis.test.datasize.large\",\n\t\t\"jredis.test.cnt.small\",\n\t\t\"jredis.test.cnt.medium\",\n\t\t\"jredis.test.cnt.large\",\n\t\t\"jredis.test.expire.secs\",\n\t\t\"jredis.test.expire.wait.millisecs\"\n\n\t})\n\t@BeforeSuite\n\tpublic void suiteParametersInit(\n\t\t\tString password, \n\t\t\tString host, \n\t\t\tint port,\n\t\t\tint db1,\n\t\t\tint db2,\n\n\t\t\tint small_data,\n\t\t\tint medium_data,\n\t\t\tint large_data,\n\t\t\tint small_cnt,\n\t\t\tint medium_cnt,\n\t\t\tint large_cnt,\n\t\t\tint expire_secs,\n\t\t\tint expire_wait_millisecs\n\t) \n\t{\n\t\tthis.password = password;\n\t\tthis.host = host;\n\t\tthis.port = port;\n\t\tthis.db1 = db1;\n\t\tthis.db2 = db2;\n\n\t\tthis.SMALL_DATA = small_data;\n\t\tthis.MEDIUM_DATA = medium_data;\n\t\tthis.LARGE_DATA = large_data;\n\t\tthis.SMALL_CNT = small_cnt;\n\t\tthis.MEDIUM_CNT = medium_cnt;\n\t\tthis.LARGE_CNT = large_cnt;\n\t\tthis.expire_secs = expire_secs;\n\t\tthis.expire_wait_millisecs = expire_wait_millisecs;\n\n\t\tLog.log(\"Suite parameters initialized <suiteParametersInit>\");\n\n\t\tsetupTestSuiteData();\n\t}\t\n\n\t// ------------------------------------------------------------------------\n\t// Test data setup methods\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * All providers to be tested with the same degree of test data.\n\t * We're using random data and can't guarantee exact teset data.\n\t * TODO: flip switch to use random or deterministic data.\n\t */\n\t@SuppressWarnings(\"boxing\")\n\tprivate final void setupTestSuiteData () {\n\t\t/** setup data */\n\t\tcnt = MEDIUM_CNT;\n\t\tbyte[] zerobytes = new byte[0];\n\t\tfor(int i=0; i<cnt; i++){\n\t\t\tkeys.add(getRandomAsciiString (48));\n\t\t\tpatternList.add(getRandomAsciiString(random.nextInt(10)+2) + patternA + getRandomAsciiString(random.nextInt(10)+2));\n\t\t\tuniqueSet.add(getRandomAsciiString(48));\n\t\t\tcommonSet.add(getRandomAsciiString(48));\n\t\t\tset1.add(\"set_1\" + getRandomAsciiString(20));\n\t\t\tset2.add(\"set_2\" + getRandomAsciiString(20));\n\t\t\tdataList.add(getRandomBytes (128));\n\t\t\tif(random.nextBoolean())\n\t\t\t\tsparseList.add(zerobytes);\n\t\t\telse\n\t\t\t\tsparseList.add(getRandomBytes (128));\n\t\t\t\n\t\t\tstringList.add(getRandomAsciiString (128));\n\t\t\tobjectList.add(new TestBean(\"testbean.\" + i));\n\t\t\tintList.add(random.nextInt());\n\t\t\tlongList.add(random.nextLong());\n\t\t\tdoubleList.add(random.nextDouble());\n\t\t}\n\t\tfor(String m : commonSet) {\n\t\t\tset1.add(m);\n\t\t\tset2.add(m);\n\t\t}\n\t\tLog.log(\"TEST-SUITE-INIT: JRedis Provider Test Suite random test data created\");\n\n\t}\n\n\tprotected final void prepTestDBs() {\n\t\t//\ttry {\n\t\t//\t\tjredis.auth(password);\n\t\t//\t\tLog.log(\"TEST-PREP: AUTH with password %s\" + password);\n\t\t//\t} \n\t\t//\tcatch (RedisException e) {\n\t\t//\t\tLog.error(\"AUTH with password \" + password + \" => \" + e.getLocalizedMessage());\n\t\t//\t\tfail(\"AUTH with password: \" + password, e);\n\t\t//\t}\n\t\t//\ttry {\n\t\t//\t\tjredis.select(db1).flushdb().select(db2).flushdb().select(db1);\n\t\t//\t\tLog.log(\"TEST-PREP: %s:%d Redis server DB %d & %d flushed\", host, port, db1, db2);\n\t\t//\t} \n\t\t//\tcatch (RedisException e) {\n\t\t//\t\tLog.error(\"SELECT/FLUSHDB for test prep\" + password);\n\t\t//\t\tfail(\"SELECT/FLUSHDB for test prep\", e);\n\t\t//\t}\n\t}\n\t// ------------------------------------------------------------------------\n\t// Helper methods\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Creates a random ascii string\n\t * @param length\n\t * @return\n\t */\n\tprotected String getRandomAsciiString (int length) {\n\t\tStringBuilder builder = new  StringBuilder(length);\n\t\tfor(int i = 0; i<length; i++){\n\t\t\tchar c = (char) (random.nextInt(126-33) + 33);\n\t\t\tbuilder.append(c);\n\t\t}\n\t\treturn builder.toString();\n\t}\n\t/**\n\t * Creates a buffer of given size filled with random byte values\n\t * @param size\n\t * @return\n\t */\n\tprotected byte[] getRandomBytes(int size) {\n\t\tint len = size;\n\t\tbyte[]\tbuff = new byte[len];\n\t\trandom.nextBytes(buff);\n\t\treturn buff;\n\t}\n\n\tprotected final <FAULT extends RuntimeException> void assertDidRaiseRuntimeError (Runnable test, Class<FAULT> errtype){\n\t\tboolean didRaiseError = false;\n\t\ttry { test.run(); }\n\t\tcatch (RuntimeException t){\n\t\t\tif(errtype.isAssignableFrom(t.getClass()))\n\t\t\t\tdidRaiseError = true; \n\t\t}\n\t\tcatch (Exception e){ fail(\"Unexpected exception\", e); }\n\t\tfinally {\n\t\t\tif(!didRaiseError) { fail(\"Failed to raise expected RuntimeError \" + errtype.getCanonicalName()); }\n\t\t}\n\t}\n\t// ------------------------------------------------------------------------\n\t// INNER TYPES USED FOR TESTING\n\t// ============================================================== TestBean\n\t// ------------------------------------------------------------------------\n\t/**\n\t * This is a simple {@link Serializable} class that we use to test object\n\t * values.  \n\t *\n\t * @author  Joubin Houshyar (alphazero@sensesay.net)\n\t * @version alpha.0, Apr 18, 2009\n\t * @since   alpha.0\n\t * \n\t */\n\tpublic static class TestBean implements Serializable {\n\t\t/**  */\n\t\tprivate static final long\tserialVersionUID\t= 4457509786469904810L;\n\t\tpublic final long getCreated_on() {return named_on;}\n\t\tpublic final void setCreated_on(long created_on) {this.named_on = created_on;}\n\t\tpublic final String getName() {return name;}\n\t\tpublic final void setName(String name) {this.name = name;}\n\t\tpublic final byte[] getData() { return data;}\n\t\tpublic final void setData(byte[] data) { this.data = data;}\n\t\tprivate long   named_on;\n\t\tprivate String name;\n\t\tprivate byte[] data;\n\t\tpublic TestBean() {\n\t\t\t//\t\t\tnamed_on = System.currentTimeMillis();\n\t\t}\n\t\tpublic TestBean(String string) { \n\t\t\tthis(); name = string;\n\t\t\tnamed_on = System.currentTimeMillis();\n\t\t}\n\t\t@Override public String toString() { return \"[\" + getClass().getSimpleName() + \" | name: \" + getName() + \" created on: \" + getCreated_on() + \"]\"; }\n\t\t@Override public boolean equals (Object o) {\n\t\t\tif(o instanceof TestBean) {\n\t\t\t\tTestBean isItMe = (TestBean) o;\n\t\t\t\treturn isItMe.getName().equals(name) && isItMe.getCreated_on()==this.named_on;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t@Override public int hashCode() {\n\t\t\treturn name.hashCode() ^ (int)named_on;\n\t\t}\n\t}\n\t// ------------------------------------------------------------------------\n\t// Test support - mildly enhanced TESTNG Assert semantics\n\t// ------------------------------------------------------------------------\n// TODO: check latest version of testng\t\n//\t// notNull\n//\tpublic static final void assertNotNull(Object object, String msgfmt, Object...optionalFmtArgs){\n//\t\tString message = String.format(msgfmt, optionalFmtArgs);\n//\t\tAssert.assertNotNull (object, message);\n//\t}\n//\t// null\n//\tpublic static final void assertNull(Object object, String msgfmt, Object...optionalFmtArgs){\n//\t\tString message = String.format(msgfmt, optionalFmtArgs);\n//\t\tAssert.assertNull (object, message);\t\t// << has bug.  reports a boolean comp result -- TODO: fix and patch.\n//\t}\n//\t\n//\t// equals\n//\tpublic static final void assertEquals(Object actual, Object expected, String msgfmt, Object...optionalFmtArgs){\n//\t\tString message = String.format(msgfmt, optionalFmtArgs);\n//\t\tAssert.assertEquals (actual, expected, message);\t\t\n//\t}\n//\tpublic static final void assertEquals(byte[] actual, byte[] expected, String msgfmt, Object...optionalFmtArgs){\n//\t\tString message = String.format(msgfmt, optionalFmtArgs);\n//\t\tAssert.assertEquals (actual, expected, message);\t\t\n//\t}\n//\t\n//\t// true/false\n//\tpublic static final void assertTrue(boolean condition, String msgfmt, Object...optionalFmtArgs){\n//\t\tString message = String.format(msgfmt, optionalFmtArgs);\n//\t\tAssert.assertTrue (condition, message);\n//\t}\n//\tpublic static final void assertFalse(boolean condition, String msgfmt, Object...optionalFmtArgs){\n//\t\tString message = String.format(msgfmt, optionalFmtArgs);\n//\t\tAssert.assertFalse (condition, message);\n//\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/ProviderTestBase.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri;\n\nimport org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.BeforeTest;\n\n/**\n * Support for tests of interface <code>T</code> implementation providers.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Oct 10, 2009\n * @since   alpha.0\n * \n */\n\npublic abstract class ProviderTestBase <T> {\n\t\n\t// ========================================================================\n\t// Test Properties\n\t// ========================================================================\n\t\n\t/** the JRedis implementation being tested */\n\tprotected T provider = null;\n\t\n\t// ------------------------------------------------------------------------\n\t// JRedisFuture Provider initialize methods\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Sets the {@link JRedis} implementation provider for the test suite\n\t */\n\t@BeforeTest\n\tpublic void setProvider () {\n\t\ttry {\n\t\t\tT provider = newProviderInstance();\n\n\t\t\tsetProviderInstance (provider);\n\t\t\tLog.log(\"%s.setProvider - done\", this.getClass().getSimpleName());\n        }\n        catch (ClientRuntimeException e) {\n        \tLog.error(e.getLocalizedMessage());\n        }\n\t}\n\t\n\t/**\n\t * Extension point:  Tests for specific implementations of <code>T</code> \n\t * implement this method to create the provider instance.\n\t * @return <code>T</code> implementation instance\n\t */\n\tprotected abstract T newProviderInstance () ;\n\t\n\t/**\n\t * Must be called by a BeforeTest method to set the jredis parameter.\n\t * @param provider that is being tested.\n\t */\n\tprivate final void setProviderInstance (T provider) {\n\t\tthis.provider = provider;\n\t\tLog.log(\"\\n\\nTEST: \" +\n\t\t\t\t\"\\n\\t-----------------------------------------------\\n\" +\n\t\t\t\t\"\\tProvider Class: %s\" +\n\t\t\t\t\"\\n\\t-----------------------------------------------\\n\", \n\t\t\t\tprovider.getClass().getCanonicalName());\n\t}\n\t/**\n\t * @return the <code>T</code> instance used for the provider tests\n\t */\n\tprotected final T getProviderInstance() {\n\t\treturn provider;\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/adhoc/AdHocTestChunkPipeline.java",
    "content": "package org.jredis.ri.adhoc;\n\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\n\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisChunkedPipeline;\nimport org.jredis.ri.alphazero.JRedisPipeline;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\n@SuppressWarnings(\"unused\")\npublic class AdHocTestChunkPipeline {\n\tstatic final int MAX_ITER = Integer.MAX_VALUE;\n\tpublic static void main(String[] args) throws Throwable {\n\t\ttry {\n\t\t\tAdHocTestChunkPipeline tester = new AdHocTestChunkPipeline();\n\t\t\tint iter = 0;\n\t\t\twhile(iter < MAX_ITER){\n\t\t\t\ttester.run();\n\t\t\t\titer++;\n\t\t\t}\n\t\t\ttester.stop();\n\t\t} catch (Exception e) {\n\t\t\te.printStackTrace();\n//\t\t\tLog.error(\"fault\", e); // TODO: \n\t\t}\n\t}\n\tfinal ConnectionSpec spec;\n\tfinal JRedisFuture jredis;\n\tpublic AdHocTestChunkPipeline() {\n\t\tspec = DefaultConnectionSpec.newSpec().setCredentials(\"jredis\").setDatabase(11);\n\t\tjredis = new JRedisChunkedPipeline(spec);\n//\t\tjredis = new JRedisPipeline(spec);\n\t}\n\t\n\tstatic final int wcnt = 2;\n\tstatic final int reqnums = 150000;\n\t\n\tprivate void stop() {\n\t\tjredis.quit();\n\t}\n\tprivate void run() {\n\t\tfinal Thread[] workers = new Thread[wcnt];\n\t\tfor(int i=0;i< workers.length; i++){\n\t\t\tString tname = String.format(\"w-%02d\", i);\n\t\t\tworkers[i] = worker(jredis, tname);\n\t\t}\n\t\tfinal long start = System.currentTimeMillis();\n\t\tfor(Thread t : workers){\n\t\t\tt.start();\n\t\t}\n\t\tfor(Thread t : workers){\n\t\t\ttry {\n\t\t\t\tt.join();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\tLog.log(\"%d x %d @ %d msecs\", wcnt, reqnums, System.currentTimeMillis() - start);\n\t}\n\t\n\tprivate Thread worker (final JRedisFuture jredis, String tname) {\n\t\tfinal Runnable task = task(jredis);\n\t\treturn new Thread(task, tname);\n\t}\n\t\n//\t@SuppressWarnings(\"unused\")\n\tprivate Runnable task (final JRedisFuture jredis) {\n\t\treturn new Runnable() {\n\t\t\tfinal JRedisFuture conn = jredis;\n\t\t\t@Override public void run() {\n\t\t\t\tfinal String tname = Thread.currentThread().getName();\n\t\t\t\tfinal byte[] key = tname.getBytes();\n\t\t\t\tfinal byte[] cntr = (tname + \"#\").getBytes();\n\t\t\t\tFuture<Long> fCntr = null;\n\t\t\t\tfor(int i=0; i<reqnums; i++) {\n\t\t\t\t\ttry {\n//\t\t\t\t\tconn.set(key, key);\n//\t\t\t\t\tconn.get(key);\n//\t\t\t\t\tconn.ping();\n\t\t\t\t\tfCntr = conn.incr(cntr);\n\t\t\t\t\t} catch (Throwable t){\n//\t\t\t\t\t\tt.printStackTrace();\n\t\t\t\t\t\tSystem.exit(1);\n\t\t\t\t\t}\n\t\t\t\t}\n//\t\t\t\tconn.flush();\n\n\t\t\t\ttry {\n\t\t\t\t\tLong counter = fCntr.get();\n//\t\t\t\t\tLog.log(\"%s:%016d\", tname, counter);\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t} catch (ExecutionException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/adhoc/AdHocTestInfo.java",
    "content": "package org.jredis.ri.adhoc;\n\nimport java.util.Map;\n\nimport org.jredis.JRedis;\nimport org.jredis.JRedisFuture;\nimport org.jredis.RedisInfo;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisClient;\nimport org.jredis.ri.alphazero.JRedisPipeline;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Assert;\nimport org.jredis.ri.alphazero.support.Log;\n\npublic class AdHocTestInfo {\n\tpublic static void main(String[] args) throws Throwable {\n\t\ttry {\n\t\t\tnew AdHocTestInfo(Connection.Modality.Asynchronous).run();\n\t\t} catch (Exception e) {\n\t\t\tLog.error(e.getMessage());\n\t\t}\n\t}\n\t\n\tfinal ConnectionSpec spec;\n\tfinal Connection.Modality connmode;\n\tJRedisFuture jredis_async;\n\tJRedis jredis;\n\tpublic AdHocTestInfo(final Connection.Modality connmode) throws Throwable{\n\t\tthis.connmode = Assert.notNull(connmode, \"connmode\", IllegalArgumentException.class);\n\t\tthis.spec = DefaultConnectionSpec.newSpec().setCredentials(\"jredis\".getBytes());\n\t\tswitch (connmode) {\n\t\tcase Asynchronous:\n\t\t\tjredis_async = new JRedisPipeline(spec);\n\t\t\tjredis = null;\n\t\t\tbreak;\n\t\tcase Synchronous:\n\t\t\tjredis_async = null;\n\t\t\tjredis = new JRedisClient(spec);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new IllegalArgumentException(\"only sync and async modes are supported\");\n\t\t}\n\t}\n\tfinal public void run() {\n\t\ttry {\n\t\t\tswitch (connmode) {\n\t\t\tcase Asynchronous:\n\t\t\t\trunasync();\n\t\t\t\tbreak;\n\t\t\tcase Synchronous:\n\t\t\t\trunsync();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new RuntimeException(\"BUG: should not be reachable\");\n\t\t\t}\n\t\t} catch (RuntimeException rte) {\n\t\t\tLog.error(\"oops: fault: %s - bye!\", rte.getMessage());\n\t\t}\n\t}\n\tfinal public void runsync() {\n\t\ttry {\n\t\t\tMap<String, String> infomap = jredis.info();\n\t\t\tfor (String k : infomap.keySet()) {\n\t\t\t\tSystem.out.format(\"%s\\n\", k);\n\t\t\t}\n\t\t} catch (Throwable e) {\n\t\t\te.printStackTrace();\n\t\t\tLog.error(\"synch run error\", e);\n\t\t\tthrow new RuntimeException(e);\n\t\t} finally {\n\t\t\tjredis.quit();\n\t\t}\n\t\t\n\t}\n\tpublic void runasync() {\n\t\ttry {\n\t\t\tMap<String, String> infomap = jredis_async.info().get();\n\t\t\tfor(String k : infomap.keySet()){\n\t\t\t\tSystem.out.format(\"%s => %s\\n\", k, infomap.get(k));\n\t\t\t}\n\t\t\t\n\t\t\tSystem.out.format(\"\\n\\n### InfoMap needs to be updated to include ###\\n\");\n\t\t\tfor (RedisInfo info : RedisInfo.values()){\n\t\t\t\tif(infomap.get(info.name()) == null)\n\t\t\t\t\tLog.log(\"%s IS MISSING\", info.name());\n\t\t\t}\n\n\t\t\tfor(String k : infomap.keySet()){\n\t\t\t\ttry {\n\t\t\t\t\tRedisInfo.valueOf(k);\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException e){\n\t\t\t\t\tSystem.out.format(\"%s,\\n\", k);\n\t\t\t\t}\n\t\t\t}\n\t\t\tSystem.out.format(\"### END ###\\n\");\n\t\t\t\n\t\t} catch (Throwable t) {\n\t\t\tt.printStackTrace();\n\t\t}\n\t\tfinally {\n\t\t\tjredis_async.quit();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/adhoc/AdHocTestNoConnection.java",
    "content": "package org.jredis.ri.adhoc;\n\nimport java.util.concurrent.Future;\n\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisPipeline;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\npublic class AdHocTestNoConnection {\n\tprivate static final int NOT_A_USUAL_REDIS_PORT = 9999;\n\tpublic static void main(String[] args) throws Throwable {\n\t\ttry {\n\t\t\tnew AdHocTestNoConnection().run();\n\t\t} catch (Exception e) {\n\t\t\tLog.error(e.getMessage());\n\t\t}\n\t}\n\tfinal ConnectionSpec spec;\n\tJRedisFuture jredis = null;\n\tpublic AdHocTestNoConnection() throws Throwable{\n\t\tspec = DefaultConnectionSpec.newSpec(\"localhost\", NOT_A_USUAL_REDIS_PORT, 11, \"jredis\".getBytes());\n\t\tjredis = new JRedisPipeline(spec);\n\t}\n\t/** this is not supposed to get called unless you actually run redis on port 9999 :P */\n\tpublic void run() {\n\t\tfinal byte[] key = \"foo\".getBytes();\n\t\tfor(;;){\n\t\t\ttry {\n\t\t\t\t@SuppressWarnings(\"unused\")\n\t\t\t\tFuture<Long> fcntr = jredis.incr(key);\n\t\t\t} catch (Throwable t) {\n\t\t\t\tt.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/ConcurrentJRedisProviderTestsBase.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport static org.testng.Assert.*;\nimport static org.jredis.ri.alphazero.support.DefaultCodec.*;\n\nimport org.jredis.JRedis;\nimport org.jredis.RedisException;\nimport org.jredis.protocol.Command;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.Test;\n\n/**\n * Tests {@link JRedis} implementations that support concurrent access.  Will\n * not run the full suite of tests (per {@link JRedisProviderTestsBase} concurrently. \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 7, 2009\n * @since   alpha.0\n * \n */\n\npublic abstract class ConcurrentJRedisProviderTestsBase extends JRedisProviderTestsBase {\n\n\t/*\n\t\tswitch (command.responseType){\n\t\t\tcase BULK:\n\t\t\tcase MULTI_BULK:\n\t\t\tcase STATUS:\n\t\t\tcase STRING:\n\t\t\tcase VIRTUAL:\n\t\t\t\tbreak;\n\t */\n\t@Test(invocationCount=20, threadPoolSize=5, singleThreaded=false)\n\tpublic void testConcurrentBulkCommands() {\n\t\tString cmd = Command.GET.responseType.name();\n\t\tString threadName = Thread.currentThread().getName();\n\t\tString key = threadName + \"::\" + keys.get(0);\n\t\tLog.log(\"CONCURRENT TEST: %s resp type command | key: %s\", cmd, key);\n\t\ttry {\n\t\t\tprovider.del(key);\n\t\t\tprovider.set (key, threadName);\n\t\t\tassertTrue (provider.exists(key), \"key should exist\");\n\t\t\tString value = toStr (provider.get(key));\n\t\t\tassertTrue(value.endsWith(threadName), \"value of key should be the thread name\");\n\t\t\tprovider.del(key);\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * \n\t */\n\t@Test(invocationCount=20, threadPoolSize=5, singleThreaded=false)\n\tpublic void testConcurrentBooleanCommands() {\n\t\tString cmd = Command.EXISTS.responseType.name();\n\t\tString threadName = Thread.currentThread().getName();\n\t\tString key = threadName + \"::\" + keys.get(0);\n\t\tLog.log(\"CONCURRENT TEST: %s resp type command | key: %s\", cmd, key);\n\t\ttry {\n\t\t\tprovider.set (key, threadName);\n//\t\t\tassertTrue (provider.del (key), \"del response should be OK\");\n\t\t\tassertEquals (provider.del(key), 1, \"del response should be 1 for one key deleted\");\n\t\t\tassertFalse (provider.exists(key), \"deleted key response should not exist\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * \n\t */\n\t@Test(invocationCount=20, threadPoolSize=5, singleThreaded=false)\n\tpublic void testConcurrentNumberCommands() {\n\t\tString cmd = Command.INCR.responseType.name();\n\t\tString cntr_key = Thread.currentThread().getName() + \"::\" + keys.get(0);\n\t\tLog.log(\"CONCURRENT TEST: %s resp type command | key: %s\", cmd, cntr_key);\n\t\ttry {\n\t\t\tprovider.del(cntr_key);\n\t\t\tfor(int i = 1; i<50; i++)\n\t\t\t\tassertEquals(i, provider.incr(cntr_key));\n\t\t\t\n\t\t\tprovider.del(cntr_key);\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisAsyncClientTest.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport static org.testng.Assert.fail;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.AfterTest;\nimport org.testng.annotations.Test;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 6, 2009\n * @since   alpha.0\n * \n */\n@Test(sequential = true, suiteName=\"JRedisAsyncClient-tests\")\npublic class JRedisAsyncClientTest extends JRedisFutureProviderTestsBase {\n\n\t// ------------------------------------------------------------------------\n\t// TEST SETUP \n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc)\n\t * @see org.jredis.ri.ProviderTestBase#newProviderInstance()\n\t */\n\t@Override\n\tprotected JRedisFuture newProviderInstance () {\n\t\tJRedisFuture provider = null;\n\t\ttry {\n\t\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(this.host, this.port, this.db2, this.password.getBytes());\n\t\t\tprovider = new JRedisAsyncClient(connectionSpec);\n        }\n        catch (ClientRuntimeException e) {\n        \tLog.error(e.getLocalizedMessage());\n        }\n        return provider;\n\t}\n\t// ------------------------------------------------------------------------\n\t// The Tests\n\t// ========================================================= JRedisClient\n\t/**\n\t * We define and run any additional, provider specific tests here.  The\n\t * basic generally applicable JRedis interface method test are defined \n\t * in the super class.\n\t * \n\t * Here we test Quit in a post test method to insure all tests have been\n\t * completed.\n\t */\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Pipeline quit.  \n\t * We first ping and await the response to insure pipeline has processed\n\t * all pending responses, and then issue the quit command.\n\t */\n\t@AfterTest\n\tpublic void testQuit() {\n\t\ttry {\n\t\t\tJRedisFuture pipeline = getProviderInstance();\n\t\t\tpipeline.ping().get();\n\t\t\tpipeline.quit().get();\n\t\t} \n\t\tcatch (Exception e) {\n\t\t\tfail(\"QUIT\" + e);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisChunkedPipelineClientTest.java",
    "content": "/*\n *   Copyright 2009-2012 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport static org.testng.Assert.fail;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.AfterTest;\nimport org.testng.annotations.Test;\n\n/**\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Jan 18, 2012\t\n * \n */\n//@Test(invocationCount=20, threadPoolSize=5, sequential=false)\n@Test(singleThreaded = false, suiteName=\"JRedisChunkedPipeline-tests\", invocationCount=20, threadPoolSize=5)\npublic class JRedisChunkedPipelineClientTest extends JRedisFutureProviderTestsBase {\n\n\t// ------------------------------------------------------------------------\n\t// TEST SETUP \n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc)\n\t * @see org.jredis.ri.ProviderTestBase#newProviderInstance()\n\t */\n\t@Override\n\tprotected JRedisFuture newProviderInstance () {\n\t\tJRedisFuture provider = null;\n\t\ttry {\n\t\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(this.host, this.port, this.db2, this.password.getBytes());\n\t\t\tprovider = new JRedisChunkedPipeline(connectionSpec);\n        }\n        catch (ClientRuntimeException e) {\n        \tLog.error(e.getLocalizedMessage());\n        }\n        return provider;\n\t}\n\t// ------------------------------------------------------------------------\n\t// The Tests\n\t// ========================================================= JRedisClient\n\t/**\n\t * We define and run any additional, provider specific tests here.  The\n\t * basic generally applicable JRedis interface method test are defined \n\t * in the super class.\n\t * \n\t * Here we test Quit in a post test method to insure all tests have been\n\t * completed.\n\t */\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Pipeline quit.  \n\t * We first ping and await the response to insure pipeline has processed\n\t * all pending responses, and then issue the quit command.\n\t */\n\t@AfterTest()\n\tpublic void testQuit() {\n\t\ttry {\n\t\t\tJRedisFuture pipeline = getProviderInstance();\n\t\t\tpipeline.quit();\n\t\t} \n\t\tcatch (Exception e) {\n\t\t\tfail(\"QUIT\" + e);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisClientTest.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport static org.testng.Assert.fail;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.AfterTest;\nimport org.testng.annotations.Test;\n\n/**\n * For testing the JRedis test suite for {@link JRedisClient} implementation.\n * TODO: should also do a minimal test using {@link ConnectionSpec}.\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 17, 2009\n * @since   alpha.0\n * \n */\n\n//TODO: get rid of NG in class name\n\n@Test(singleThreaded = true, suiteName=\"JRedisClient-tests\")\npublic class JRedisClientTest extends JRedisProviderTestsBase {\n\n\t// ------------------------------------------------------------------------\n\t// TEST SETUP \n\t// ------------------------------------------------------------------------\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.ri.alphazero.JRedisProviderTestNGBase#newJRedisProviderInstance()\n\t */\n\tprotected JRedis newProviderInstance () {\n\t\tJRedis provider = null;\n\t\ttry {\n\t\t\tprovider = new JRedisClient (this.host, this.port, this.password, this.db1);\n        }\n        catch (ClientRuntimeException e) {\n        \tLog.error(e.getLocalizedMessage());\n        }\n        return provider;\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// The Tests\n\t// ========================================================= JRedisClient\n\t/**\n\t * We define and run any additional, provider specific tests here.  The\n\t * basic generally applicable JRedis interface method test are defined \n\t * in the super class.\n\t * \n\t * Here we test Quit in a post test method to insure all tests have been\n\t * completed.\n\t */\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#auth(java.lang.String)}.\n\t */\n\t@AfterTest\n\tpublic void testQuit() {\n\t\tLog.log(\"TEST: QUIT command\");\n\t\ttry {\n\t\t\tJRedis provider = getProviderInstance();\n\t\t\tprovider.quit ();\n\t\t} \n\t\tcatch (Exception e) {\n\t\t\tfail(\"QUIT\" + e);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisFutureProviderTestsBase.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport static org.jredis.ri.alphazero.support.DefaultCodec.toStr;\nimport static org.testng.Assert.assertEquals;\nimport static org.testng.Assert.assertFalse;\nimport static org.testng.Assert.assertNotNull;\nimport static org.testng.Assert.assertNull;\nimport static org.testng.Assert.assertTrue;\nimport static org.testng.Assert.fail;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedisFuture;\nimport org.jredis.ObjectInfo;\nimport org.jredis.Query;\nimport org.jredis.RedisException;\nimport org.jredis.RedisType;\nimport org.jredis.ZSetEntry;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.JRedisTestSuiteBase;\nimport org.jredis.ri.alphazero.support.Convert;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.Test;\n\n/**\n * [TODO: cleanup the unit test comments]\n * \n * Provides the comprehensive set of tests of all {@link JRedisFuture} methods.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Oct 10, 2009\n * @since   alpha.0\n * \n */\n\npublic abstract class JRedisFutureProviderTestsBase extends JRedisTestSuiteBase<JRedisFuture> {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\t/** JRedis Command being tested -- for log info */\n\tprivate String cmd;\n\t\n\t// ------------------------------------------------------------------------\n\t// The Tests\n\t// ======================================================= JRedisFuture ===\n\t/*\n\t * We define and run provider agnostic tests here.  This means we run a set\n\t * of JRedisFuture interface method tests that every connected JRedisFuture\n\t * implementation should be able to support. \n\t * \n\t * The following commands are omitted:\n\t * 1 - QUIT: since we may be testing a multi-connection provier\n\t * 2 - SHUTDOWN: for the same reason as QUIT \n\t * 3 - MOVE and SELECT\n\t */\n\t// ------------------------------------------------------------------------\n\n\n//\t@Test\n//\tpublic void testTemplate() throws InterruptedException {\n//\t\tcmd = Command.PING.code + \" | \" + Command.SETNX.code + \" byte[] | \" + Command.GET;\n//\t\tLog.log(\"TEST: %s command\", cmd);\n//\t\t\n//\t\ttry {\n//\t\t\tprovider.flushdb();\n//\t\t\ttry {\n//\t\t\t}\n//\t\t\tcatch(ExecutionException e){\n//\t\t\t\tThrowable cause = e.getCause();\n//\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n//\t\t\t}\n//\t\t} \n//\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n//\t}\n\n\t@Test\n\tpublic void testSrandmember () throws InterruptedException {\n\t\tcmd = Command.SRANDMEMBER.code + \" String | \" + Command.SMEMBERS;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\t\n\t\t\tList<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tsaddResponses.add (provider.sadd(setkey, stringList.get(i)));\n\t\t\t\n\t\t\tFuture<List<byte[]>>  smembersResponse = provider.smembers(setkey);\n\t\t\tFuture<byte[]>\t      srandmemberResponse = provider.srandmember(setkey);\n\t\t\t\n\t\t\ttry {\n\t\t\t\t\n\t\t\t\tfor(Future<Boolean> resp : saddResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"sadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tList<String>  members = toStr(smembersResponse.get());\n\t\t\t\tassertEquals(members.size(), SMALL_CNT, \"set members count should be SMALL_CNT\");\n\t\t\t\t\n\t\t\t\tString randmember = toStr(srandmemberResponse.get());\n\t\t\t\t\n\t\t\t\tboolean found = false;\n\t\t\t\tfor(String m : members) {\n\t\t\t\t\tif(m.equals(randmember)) {\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tassertTrue(found, \"random member should have been part of the members list\");\n\n\t\t\t\t// edge cases\n\t\t\t\t\n\t\t\t\t// empty set\n\t\t\t\tString emptyset = \"empty-set\";\n\t\t\t\tprovider.sadd(emptyset, \"delete-me\");\n\t\t\t\tprovider.srem(emptyset, \"delete-me\");\n\t\t\t\tassertEquals(provider.smembers(emptyset).get(), Collections.EMPTY_LIST, \"smembers should return an empty list\");\n\t\t\t\tassertEquals(provider.srandmember(emptyset).get(), null, \"random member of empty set should be null\");\n\t\t\t\t\n\t\t\t\t// non existent key\n\t\t\t\tString nonsuch = \"no-such-key\";\n\t\t\t\tassertEquals(provider.smembers(nonsuch).get(), Collections.EMPTY_LIST, \"members of non existent key set should be empty\");\n\t\t\t\tassertEquals (provider.srandmember(nonsuch).get(), null, \"random member of non existent key set should be null\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\n\t@Test\n\tpublic void testSmoveStringByteArray() throws InterruptedException{\n\t\tcmd = Command.SMOVE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\tprovider.flushdb();\n\t\t\n\t\tString srckey = keys.get(0);\n\t\tString destkey = keys.get(1);\n\t\t\n\t\tList<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();\n\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\tsaddResponses.add (provider.sadd(srckey, dataList.get(i)));\n\t\t\n\t\tList<Future<Boolean>> smoveResponses = new ArrayList<Future<Boolean>>();\n\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\tsmoveResponses.add (provider.smove(srckey, destkey, dataList.get(i)));\n\t\t\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : saddResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"sadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tfor(Future<Boolean> resp : smoveResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"smove of element should have been true\");\n\t\t\t\t\n\t\t\t\tfor(int i=0;i<MEDIUM_CNT; i++){\n\t\t\t\t\tassertTrue  (provider.sismember(destkey, dataList.get(i)).get(), \"@ [\" + i +\"] should be a member of the dest after move\");\n\t\t\t\t\tassertFalse (provider.sismember(srckey, dataList.get(i)).get(), \"@ [\" + i +\"] should NOT be a member of the src after move\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testScard() throws InterruptedException {\n\t\tcmd = Command.SCARD.code + \" Java Object\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\tprovider.flushdb();\n\t\t\n\t\tString setkey = keys.get(0);\n\t\n\t\tList<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();\n\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\tsaddResponses.add (provider.sadd(setkey, objectList.get(i)));\n\t\t\n\t\tFuture<Long> scardResp = provider.scard(setkey);\n\t\t\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : saddResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"sadd of random object should have been true\");\n\t\t\t\t\n\t\t\t\tassertEquals (scardResp.get().longValue(), MEDIUM_CNT, \"scard value should have been MEDIUM_CNT\");\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testZcard() throws InterruptedException {\n\t\tcmd = Command.ZCARD.code + \" Java Object\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\tprovider.flushdb();\n\t\t\n\t\tString setkey = keys.get(0);\n\t\n\t\tList<Future<Boolean>> zaddResponses = new ArrayList<Future<Boolean>>();\n\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\tzaddResponses.add (provider.zadd(setkey, i, objectList.get(i)));\n\t\t\n\t\tFuture<Long> zcardResp = provider.zcard(setkey);\n\t\t\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : zaddResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random object should have been true\");\n\t\t\t\t\n\t\t\t\tassertEquals (zcardResp.get().longValue(), MEDIUM_CNT, \"zcard value should have been MEDIUM_CNT\");\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testSismemberStringByteArray() throws InterruptedException {\n\t\tcmd = Command.SISMEMBER.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\tString setkey = keys.get(0);\n\t\t\n\t\tprovider.flushdb();\n\t\t\n\t\tList<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();\n\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\tsaddResponses.add (provider.sadd(setkey, dataList.get(i)));\n\t\t\n\t\tList<Future<Boolean>> sismemberResponses = new ArrayList<Future<Boolean>>();\n\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\tsaddResponses.add (provider.sismember(setkey, dataList.get(i)));\n\t\t\n\t\t\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : saddResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"sadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tfor(Future<Boolean> resp : sismemberResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"set membership test should have been true\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testSmembers() throws InterruptedException{\n\t\tcmd = Command.SMEMBERS.code + \" byte[] | \" + Command.SADD + \"| \" + Command.SCARD;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> saddResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tsaddResponses.add (provider.sadd(setkey, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<Long> scardResp = provider.scard(setkey);\n\t\t\tFuture<List<byte[]>> smembersResp = provider.smembers(setkey);\t\t\t\n\n\t\t\tString setkey2 = keys.get(2);\n\t\t\tprovider.sadd(setkey2, dataList.get(0));\n\t\t\tprovider.srem(setkey2, dataList.get(0));\n\t\t\tFuture<Long> scardResp2 = provider.scard(setkey2);\n\t\t\tFuture<List<byte[]>> smembersResp2 = provider.smembers(setkey2);\t\t\t\n\t\t\t\n\t\t\t\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : saddResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"sadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tList<byte[]> members = smembersResp.get();\n\t\t\t\tassertTrue(members.size() == SMALL_CNT, \"smembers should have returned a list of SMALL_CNT size\");\n\t\t\t\tassertTrue(members.size() == scardResp.get().longValue(), \"smembers should have returned a list of scard size\");\n\t\t\t\t\n\t\t\t\tList<byte[]> members2 = smembersResp2.get();\n\t\t\t\tassertEquals(scardResp2.get().longValue(), 0, \"setkey2 should be zero\");\n\t\t\t\tassertEquals(members2, Collections.EMPTY_LIST, \"smembers should have returned empty\");\n//\t\t\t\tassertTrue(members2.size() == scardResp2.get().longValue(), \"smembers should have returned a list of scard size\");\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t@Test\n\tpublic void testZremStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZADD.code + \" byte[] | \" + Command.ZREM.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tList<Future<Boolean>> expectedOKRemResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedOKRemResponses.add (provider.zrem(setkey, dataList.get(i)));\n\t\t\t\n\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tfor(Future<Boolean> resp : expectedOKRemResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of existing element should have been false\");\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t@Test\n\tpublic void testZaddStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZADD.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, random.nextDouble(), dataList.get(i)));\n\t\t\t\n\t\t\tList<Future<Boolean>> expectedErrorResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedErrorResponses.add (provider.zadd(setkey, random.nextDouble(), dataList.get(i)));\n\t\t\t\n\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tfor(Future<Boolean> resp : expectedErrorResponses)\n\t\t\t\t\tassertFalse (resp.get().booleanValue(), \"zadd of existing element should have been false\");\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t@Test\n\tpublic void testZscoreAndZincrbyStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZSCORE.code + \" byte[] | \" + Command.ZINCRBY.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, doubleList.get(i), dataList.get(i)));\n\t\t\t\n\t\t\tList<Future<Double>> scores = new ArrayList<Future<Double>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tscores.add (provider.zscore(setkey, dataList.get(i)));\n\t\t\t\n\t\t\tdouble increment = 0.05;\n\t\t\tList<Future<Double>> incrementedScores = new ArrayList<Future<Double>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tincrementedScores.add (provider.zincrby(setkey, increment, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<Double>  noneSuchKeyScore = provider.zscore(setkey, \"no such member\");\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tint i=0;\n\t\t\t\tfor(Future<Double> score : scores){\n\t\t\t\t\tassertEquals (score.get(), doubleList.get(i), \"zscore of element should have been \" + doubleList.get(i));\n\t\t\t\t\ti++;\n\t\t\t\t}\t\n\t\t\t\t\n\t\t\t\ti=0;\n\t\t\t\tfor(Future<Double> score : incrementedScores){\n\t\t\t\t\tassertEquals (score.get(), doubleList.get(i) + increment, \"zincr of element should be \" + doubleList.get(i) + increment);\n\t\t\t\t\ti++;\n\t\t\t\t}\t\n\t\t\t\t\n\t\t\t\tassertNull(noneSuchKeyScore.get(), \"zscore of none existent member of sorted set should be null\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testZrangebyscoreStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZRANGEBYSCORE.code + \" byte[] | \" + Command.ZSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<List<byte[]>> frRange = provider.zrangebyscore(setkey, 0, SMALL_CNT); \n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tList<byte[]> range = frRange.get();\n\t\t\t\tassertTrue(range.size() > 0, \"should have non empty results for range by score here\");\n\t\t\t\t\n\t\t\t\tfor(int i=0;i<SMALL_CNT-1; i++){\n\t\t\t\t\tassertEquals(range.get(i), dataList.get(i), \"expected value in the range by score missing\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testZremrangebyscoreStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZREMRANGEBYSCORE.code + \" byte[] | \" + Command.ZSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<Long> frRemCnt = provider.zremrangebyscore(setkey, 0, SMALL_CNT); \n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tlong remCnt = frRemCnt.get().longValue();\n\t\t\t\tassertTrue(remCnt > 0, \"should have non-zero number of rem cnt for zremrangebyscore\");\n\t\t\t\tassertEquals(remCnt, SMALL_CNT+1, \"should have specific number of rem cnt for zremrangebyscore\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testZcountStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZCOUNT.code + \" byte[] | \" + Command.ZADD.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<Long> frCount = provider.zcount(setkey, 0, SMALL_CNT); \n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tlong remCnt = frCount.get().longValue();\n\t\t\t\tassertTrue(remCnt > 0, \"should have non-zero number of rem cnt for zremrangebyscore\");\n\t\t\t\tassertEquals(remCnt, SMALL_CNT+1, \"should have specific number for zcount\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testZremrangebyrankStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZREMRANGEBYRANK.code + \" byte[] | \" + Command.ZSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<Long> frRemCnt = provider.zremrangebyrank(setkey, 0, SMALL_CNT); \n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tlong remCnt = frRemCnt.get().longValue();\n\t\t\t\tassertTrue(remCnt > 0, \"should have non-zero number of rem cnt for zremrangebyrank\");\n\t\t\t\tassertEquals(remCnt, SMALL_CNT+1, \"should have specific number of rem cnt for zremrangebyrank\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testZrankStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZRANK.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\t\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tList<Future<Long>> rankingResps = new ArrayList<Future<Long>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\trankingResps.add(provider.zrank(setkey, dataList.get(i)));\n\n\t\t\tFuture<Long>  frRankForMissingElement = provider.zrank(setkey, dataList.get(SMALL_CNT+1));\n\t\t\tFuture<Long>  frRankForNoSuchSet = provider.zrank(\"no-such-set\", dataList.get(0));\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tint i=0;\n\t\t\t\tfor(Future<Long> resp : rankingResps)\n\t\t\t\t\tassertEquals (resp.get().longValue(), i++, \"zrank of element\");\n\t\t\t\t\n\t\t\t\tassertEquals (frRankForMissingElement.get().longValue(), -1, \"zrank against non-existent member should be -1\");\n\t\t\t\tassertEquals (frRankForNoSuchSet.get().longValue(), -1, \"zrank against non-existent key should be -1\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t\n\t@Test\n\tpublic void testZrevrankStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZREVRANK.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\t\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<=SMALL_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tList<Future<Long>> rankingResps = new ArrayList<Future<Long>>();\n\t\t\tfor(int i=0;i<=SMALL_CNT; i++)\n\t\t\t\trankingResps.add(provider.zrevrank(setkey, dataList.get(i)));\n\n\t\t\tFuture<Long>  frRankForMissingElement = provider.zrevrank(setkey, dataList.get(SMALL_CNT+1));\n\t\t\tFuture<Long>  frRankForNoSuchSet = provider.zrevrank(\"no-such-set\", dataList.get(0));\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tint i=0;\n\t\t\t\tfor(Future<Long> resp : rankingResps)\n\t\t\t\t\tassertEquals (resp.get().longValue(), SMALL_CNT - i++, \"zrevrank of element\");\n\t\t\t\t\n\t\t\t\tassertEquals (frRankForMissingElement.get().longValue(), -1, \"zrevrank against non-existent member should be -1\");\n\t\t\t\tassertEquals (frRankForNoSuchSet.get().longValue(), -1, \"zrevrank against non-existent key should be -1\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t@Test\n\tpublic void testZrangeWithscoresStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZRANGE$OPTS.code + \" byte[] | \" + Command.ZSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<List<byte[]>> frZValues = provider.zrange(setkey, 0, SMALL_CNT); \n\t\t\tFuture<List<ZSetEntry>> frSubset = provider.zrangeSubset(setkey, 0, SMALL_CNT); \n\t\t\t\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tList<byte[]> zvalues = frZValues.get();\n\t\t\t\tList<ZSetEntry> zsubset = frSubset.get();\n\t\t\t\tfor(int i=0;i<SMALL_CNT; i++){\n\t\t\t\t\tassertEquals(zsubset.get(i).getValue(), dataList.get(i), \"value of element from zrange_withscore\");\n\t\t\t\t\tassertEquals(zsubset.get(i).getValue(), zvalues.get(i), \"value of element from zrange_withscore compared with zscore with same range query\");\n\t\t\t\t\tassertEquals (zsubset.get(i).getScore(), (double)i, \"score of element from zrange_withscore\");\n\t\t\t\t\tassertTrue(zsubset.get(i).getScore() <= zsubset.get(i+1).getScore(), \"range member score should be smaller or equal to previous range member.  idx: \" + i);\n\t\t\t\t\tif(i>0) assertTrue(zsubset.get(i).getScore() >= zsubset.get(i-1).getScore(), \"range member score should be bigger or equal to previous range member.  idx: \" + i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testZrevrangeWithscoresStringByteArray() throws InterruptedException{\n\t\tcmd = Command.ZREVRANGE$OPTS.code + \" byte[] | \" + Command.ZSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.zadd(setkey, i, dataList.get(i)));\n\t\t\t\n\t\t\tFuture<List<byte[]>> frZValues = provider.zrevrange(setkey, 0, SMALL_CNT); \n\t\t\tFuture<List<ZSetEntry>> frSubset = provider.zrevrangeSubset(setkey, 0, SMALL_CNT); \n\t\t\t\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"zadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tList<byte[]> zvalues = frZValues.get();\n\t\t\t\tList<ZSetEntry> zsubset = frSubset.get();\n\t\t\t\tfor(int i=0;i<SMALL_CNT; i++){\n\t\t\t\t\tassertEquals(zsubset.get(i).getValue(), dataList.get(MEDIUM_CNT-i-1), \"value of element from zrange_withscore\");\n\t\t\t\t\tassertEquals(zsubset.get(i).getValue(), zvalues.get(i), \"value of element from zrange_withscore compared with zscore with same range query\");\n\t\t\t\t\tassertEquals (zsubset.get(i).getScore(), (double)MEDIUM_CNT-i-1, \"score of element from zrange_withscore\");\n\t\t\t\t\tassertTrue(zsubset.get(i).getScore() >= zsubset.get(i+1).getScore(), \"range member score should be smaller or equal to previous range member.  idx: \" + i);\n\t\t\t\t\tif(i>0) assertTrue(zsubset.get(i).getScore() <= zsubset.get(i-1).getScore(), \"range member score should be bigger or equal to previous range member.  idx: \" + i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testSaddStringByteArray() throws InterruptedException{\n\t\tcmd = Command.SADD.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tString setkey = keys.get(0);\n\t\t\tList<Future<Boolean>> expectedOKResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedOKResponses.add (provider.sadd(setkey, dataList.get(i)));\n\t\t\t\n\t\t\tList<Future<Boolean>> expectedErrorResponses = new ArrayList<Future<Boolean>>();\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\texpectedErrorResponses.add (provider.sadd(setkey, dataList.get(i)));\n\t\t\t\n\n\t\t\ttry {\n\t\t\t\tfor(Future<Boolean> resp : expectedOKResponses)\n\t\t\t\t\tassertTrue (resp.get().booleanValue(), \"sadd of random element should have been true\");\n\t\t\t\t\n\t\t\t\tfor(Future<Boolean> resp : expectedErrorResponses)\n\t\t\t\t\tassertFalse (resp.get().booleanValue(), \"sadd of existing element should have been false\");\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testSort() throws InterruptedException{\n\t\tcmd = Command.SORT.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\tfinal String setkey = \"set-key\";\n\t\tfinal String listkey = \"list-key\";\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++){\n\t\t\t\tprovider.sadd(setkey, stringList.get(i));\n\t\t\t\tprovider.lpush(listkey, stringList.get(i));\n\t\t\t}\n\t\t\t\n\t\t\tint cnt1 = MEDIUM_CNT, cnt2 = 9, cnt3 = 1;\n\t\t\tFuture<List<byte[]>> sortListResp1 = provider.sort(listkey).ALPHA().LIMIT(0, cnt1).DESC().execAsync();\n\t\t\tFuture<List<byte[]>> sortListResp2 = provider.sort(listkey).ALPHA().LIMIT(10, cnt2).DESC().execAsync();\n\t\t\tFuture<List<byte[]>> sortListResp3 = provider.sort(listkey).ALPHA().LIMIT(MEDIUM_CNT-1, cnt3).DESC().execAsync();\n\t\t\t\n\t\t\tFuture<List<byte[]>> sortSetResp = provider.sort(setkey).ALPHA().LIMIT(0, 555).DESC().execAsync();\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertEquals(sortListResp1.get().size(), cnt1, \"expecting sort results of size MEDIUM_CNT\");\n\t\t\t\tassertEquals(sortListResp2.get().size(), cnt2, \"expecting sort results of size 9\");\n\t\t\t\tassertEquals(sortListResp3.get().size(), cnt3, \"expecting sort results of size 1\");\n\t\t\t\t\n\t\t\t\tLog.log(\"TEST: SORTED LIST \");\n\t\t\t\tfor(String s : toStr(sortListResp1.get()))\n\t\t\t\t\tSystem.out.format(\"[t.1] %s\\n\", s);\n\t\t\t\t\n\t\t\t\tLog.log(\"TEST: SORTED LIST \");\n\t\t\t\tfor(String s : toStr(sortListResp2.get()))\n\t\t\t\t\tSystem.out.format(\"[t.1] %s\\n\", s);\n\t\t\t\t\n\t\t\t\tLog.log(\"TEST: SORTED LIST \");\n\t\t\t\tfor(String s : toStr(sortListResp3.get()))\n\t\t\t\t\tSystem.out.format(\"[t.1] %s\\n\", s);\n\t\t\t\t\n\t\t\t\tLog.log(\"TEST: SORTED SET \");\n\t\t\t\tfor(String s : toStr(sortSetResp.get()))\n\t\t\t\t\tSystem.out.format(\"%s\\n\", s);\n\t\t\t\t\n\t\t\t\tString destKey = String.format(\"%s_store\", listkey);\n\t\t\t\tList<byte[]> ssres = provider.sort(listkey).ALPHA().LIMIT(0, MEDIUM_CNT).DESC().STORE(destKey).execAsync().get();\n\t\t\t\tassertNotNull(ssres, \"result of srot with STORE should be non-null\");\n\t\t\t\tassertEquals(ssres.size(), 1, \"result of sort with STORE should be a list of single entry (the stored list's size)\");\n\t\t\t\tlong sortedListSize = Query.Support.unpackValue(ssres);\n\t\t\t\tassertEquals(sortedListSize, MEDIUM_CNT);\n\t\t\t\tRedisType type = provider.type(destKey).get();\n\t\t\t\tassertEquals(type, RedisType.list, \"dest key of SORT .. STORE should be a LIST\");\n\t\t\t\tlong sslistSize = provider.llen(destKey).get();\n\t\t\t\tassertEquals(sslistSize, sortedListSize, \"result of SORT ... STORE and LLEN of destkey list should be same\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t\t\n\t\t// force errors\n\t\t\n\t\t// count can't be zero\n\t\tRunnable invalidLimitSpec = new Runnable() {\n\t\t\tpublic void run() {\n\t\t\t\ttry { provider.sort(listkey).ALPHA().LIMIT(0, 0).DESC().exec(); }\n                catch (Throwable t) { throw new RuntimeException (\"\", t); }\n\t\t\t}\n\t\t};\n\t\tassertDidRaiseRuntimeError(invalidLimitSpec, RuntimeException.class);\n\t\t\n\t\t// LIMIT from must be positive, {0...n}\n\t\tRunnable invalidLimitSpec2 = new Runnable() {\n\t\t\tpublic void run() {\n\t\t\t\ttry { provider.sort(listkey).ALPHA().LIMIT(-1, 1).DESC().exec(); }\n                catch (Throwable t) { throw new RuntimeException (\"\", t); }\n\t\t\t}\n\t\t};\n\t\tassertDidRaiseRuntimeError(invalidLimitSpec2, RuntimeException.class);\n\t\t\n\t}\n\t\n\t@Test\n\tpublic void testLsetStringIntByteArray() throws InterruptedException {\n\t\tcmd = Command.LSET.code + \" byte[] | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a MEDIUM list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\t\n\t\t\t// now we'll change their values\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lset(listkey, i, dataList.get(SMALL_CNT+i));\n\t\t\tFuture<List<byte[]>>  lrangeResp1 = provider.lrange(listkey, 0, LARGE_CNT);\n\t\t\t\n\t\t\t// now we'll change their values using the negative index mode\n\t\t\tint lim = SMALL_CNT*-1;\n\t\t\tfor(int i=-1; i>lim; i--)\n\t\t\t\tprovider.lset(listkey, i, dataList.get(i*-1));\n\t\t\tFuture<List<byte[]>>  lrangeResp2 = provider.lrange(listkey, 0, LARGE_CNT);\n\n\t\t\t// test edge conditions\n\t\t\t// out of range\n\t\t\tFuture<ResponseStatus> expectedErrorResp =  provider.lset(listkey, SMALL_CNT, dataList.get(0)); \n\n\t\t\ttry {\n\t\t\t\tassertTrue (llenResp.get().longValue() == SMALL_CNT, \"list length should be SMALL_CNT\");\n\t\t\t\t\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\t\tassertEquals (dataList.get(SMALL_CNT+i), lrangeResp1.get().get(i), \"after LSET the expected and range item differ at idx: \" + i);\n\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\t\tassertEquals (dataList.get(SMALL_CNT-i), lrangeResp2.get().get(i), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\t\n\t\t\t\tboolean expectedError = false;\n\t\t\t\ttry {\n\t\t\t\t\tLog.log(\"Expecting an out of range ERROR for LSET here..\");\n\t                expectedErrorResp.get(); // wait for response\n\t\t\t\t}\n\t            catch (ExecutionException e) {\n\t            \texpectedError = true;\n\t            \tThrowable cause = e.getCause();\n\t            \tif(cause instanceof RedisException)\n\t            \t\tLog.log(\"%s (as excepted)\", cause);\n\t            \telse\n\t            \t\tfail(\"FAULT: the cause of ExecutionException was expected to be a RedisException\");\n\t            }\n\t\t\t\tassertTrue(expectedError, \"was expecting a Expecting an out of range ERROR for LSET here\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testLremStringByteArrayInt() throws InterruptedException {\n\t\tcmd = Command.LREM.code + \" byte[] | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a MEDIUM list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\t\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\t\n\t\t\t// everysingle one of these should work and remove exactly 1 item\n\t\t\tFuture<Long> lremResp1 = provider.lrem(listkey, dataList.get(0), 0);\n\t\t\tFuture<Long> lremResp2 = provider.lrem(listkey, dataList.get(1), -1);\n\t\t\tFuture<Long> lremResp3 = provider.lrem(listkey, dataList.get(2), 1);\n\t\t\tFuture<Long> lremResp4 = provider.lrem(listkey, dataList.get(3), 2);\n\t\t\tFuture<Long> lremResp5 = provider.lrem(listkey, dataList.get(4), -2);\n\t\t\t\n\t\t\t// everysingle one of these should work and remove NOTHING\n\t\t\tFuture<Long> lremResp6 = provider.lrem(listkey, dataList.get(0), 0);\n\t\t\tFuture<Long> lremResp7 = provider.lrem(listkey, dataList.get(1), -1);\n\t\t\tFuture<Long> lremResp8 = provider.lrem(listkey, dataList.get(2), 1);\n\t\t\tFuture<Long> lremResp9 = provider.lrem(listkey, dataList.get(3), 2);\n\t\t\tFuture<Long> lremResp10 = provider.lrem(listkey, dataList.get(4), -2);\n\t\t\t\n\t\t\ttry {\n\t\t\t\tlong listcnt = llenResp.get();\n\t\t\t\tassertTrue (listcnt == MEDIUM_CNT, \"list length should be MEDIUM_CNT\");\n\t\t\t\t\n\t\t\t\tassertEquals(1, lremResp1.get().longValue());\n\t\t\t\tassertEquals(1, lremResp2.get().longValue());\n\t\t\t\tassertEquals(1, lremResp3.get().longValue());\n\t\t\t\tassertEquals(1, lremResp4.get().longValue());\n\t\t\t\tassertEquals(1, lremResp5.get().longValue());\n\t\t\t\tassertEquals(0, lremResp6.get().longValue());\n\t\t\t\tassertEquals(0, lremResp7.get().longValue());\n\t\t\t\tassertEquals(0, lremResp8.get().longValue());\n\t\t\t\tassertEquals(0, lremResp9.get().longValue());\n\t\t\t\tassertEquals(0, lremResp10.get().longValue());\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testLrange() throws InterruptedException {\n\t\tcmd = Command.LRANGE.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a MEDIUM list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\t\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\tFuture<List<byte[]>>  lrangeResp = provider.lrange(listkey, 0, MEDIUM_CNT-1);\n\n\t\t\ttry {\n//\t\t\t\tprovider.ping().get();\n\t\t\t\t// sanity check\n\t\t\t\tlong listcnt = llenResp.get();\n\t\t\t\tassertTrue (listcnt == MEDIUM_CNT, \"list length should be MEDIUM_CNT\");\n\t\t\t\t\n\t\t\t\tList<byte[]> items = lrangeResp.get();\n\t\t\t\tassertEquals (items.size(), MEDIUM_CNT, \"list range 0->MEDIUM_CNT length should be MEDIUM_CNT\");\n\t\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\t\tassertEquals(items.get(i), dataList.get(i), \n\t\t\t\t\t\t\t\"nth items of range 0->CNT should be the same as nth dataitem, where n is \" + i);\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testSubstr() throws InterruptedException {\n\t\tcmd = Command.SUBSTR.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString key = keys.get(0);\n\t\t\tbyte[] value = dataList.get(0);\n\t\t\tprovider.set(key, value);\n\t\t\t\n\t\t\tList<Future<byte[]>> frBytesRespList = new ArrayList<Future<byte[]>>();\n\t\t\tfor(int i=0; i<value.length; i++){\n\t\t\t\tfrBytesRespList.add(provider.substr(key, i, i));\n\t\t\t}\n\t\t\t\n\t\t\tFuture<byte[]> frFullValue1 = provider.substr(key, 0, -1);\n\t\t\tFuture<byte[]> frFullValue2 = provider.substr(key, 0, value.length);\n\t\t\tFuture<byte[]> frExpectedNull = provider.substr(key, -1, 0);\n\n\t\t\ttry {\n\t\t\t\tassertEquals(frFullValue1.get(), value, \"full range substr should be equal to value\");\n\t\t\t\tassertEquals(frFullValue2.get(), value, \"full range substr should be equal to value\");\n\t\t\t\tassertEquals(frExpectedNull.get(), new byte[0], \"substr with -1 from idx should be zero-length array\");\n\t\t\t\tfor(int i=0; i<value.length; i++){\n\t\t\t\t\tassertTrue(frBytesRespList.get(i).get().length == 1, \"checking size: using substr to iterate over value bytes @ idx \" + i);\n\t\t\t\t\tassertEquals(frBytesRespList.get(i).get()[0], value[i], \"checking value: using substr to iterate over value bytes @ idx \" + i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testRpop() throws InterruptedException {\n\t\tcmd = Command.RPOP.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lpush(listkey, dataList.get(i)); \n\t\t\t\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\t\n\t\t\tList<Future<byte[]>>  rpops = new ArrayList<Future<byte[]>>();\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\trpops.add(provider.rpop(listkey)); \n\t\t\t\n\t\t\ttry {\n\t\t\t\tlong listcnt = llenResp.get();\n\t\t\t\t// sanity check\n\t\t\t\tassertTrue (listcnt == SMALL_CNT, \"list length should be SMALL_CNT\");\n\t\t\t\t\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\t\tassertEquals(rpops.get(i).get(), dataList.get(i), \n\t\t\t\t\t\t\t\"nth popped tail should be the same as nth dataitem, where n is \" + i);\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testLpop() throws InterruptedException {\n\t\tcmd = Command.LPOP.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); \n\t\t\t\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\tList<Future<byte[]>>  lpops = new ArrayList<Future<byte[]>>();\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tlpops.add(provider.lpop(listkey)); \n\t\t\t\n\t\t\ttry {\n\t\t\t\tlong listcnt = llenResp.get();\n\t\t\t\t// sanity check\n\t\t\t\tassertTrue (listcnt == SMALL_CNT, \"list length should be SMALL_CNT\");\n\t\t\t\t\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\t\tassertEquals(lpops.get(i).get(), dataList.get(i), \n\t\t\t\t\t\t\t\"nth popped head should be the same as nth dataitem, where n is \" + i);\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testLindex() throws InterruptedException {\n\t\tcmd = Command.LINDEX.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); \n\t\t\t\n\t\t\ttry {\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\t\tassertEquals (provider.lindex(listkey, i).get(), dataList.get(i), \"list items should match ref data\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testLtrim() throws InterruptedException {\n\t\tcmd = Command.LTRIM.code + \" | \" + Command.LLEN.code + \" | \" + Command.LRANGE.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); \n\t\t\t\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\ttry {\n\t\t\t\tlong listcnt = llenResp.get();\n\t\t\t\t// sanity check\n\t\t\t\tassertTrue (listcnt == SMALL_CNT, \"list length should be SMALL_CNT\");\n\t\t\t\t\n\t\t\t\tprovider.ltrim(listkey, 0,listcnt-1);\t// trim nothing\n\t\t\t\tassertTrue (provider.llen(listkey).get() == listcnt, \"trim from end to end - no delta expected\");\n\t\t\t\t\n\t\t\t\tprovider.ltrim(listkey, 1, listcnt-1); \t// remove the head\n\t\t\t\tassertTrue (provider.llen(listkey).get() == listcnt-1, \"trim head - len should be --1 expected\");\n\t\t\t\t\n\t\t\t\tlistcnt = provider.llen(listkey).get();\n\t\t\t\tassertEquals(listcnt, SMALL_CNT - 1, \"list length should be SMALL_CNT - 1\");\n\t\t\t\tfor(int i=0; i<SMALL_CNT-1; i++)\n\t\t\t\t\tassertEquals(provider.lindex(listkey, i).get(), dataList.get(i+1), \"list items should match ref data shifted by 1 after removing head\");\n\t\t\t\t\n\t\t\t\tprovider.ltrim(listkey, -2, -1);\n\t\t\t\tassertTrue (provider.llen(listkey).get() == 2, \"list length should be 2\");\n\t\t\t\t\n\t\t\t\tprovider.ltrim(listkey, 0, 0);\n\t\t\t\tassertTrue (provider.llen(listkey).get() == 1, \"list length should be 1\");\n\n\t\t\t\tbyte[] lastItem = provider.lpop(listkey).get();\n\t\t\t\tassertNotNull(lastItem, \"last item should not have been null\");\n\t\t\t\tassertTrue (provider.llen(listkey).get() == 0, \"expecting empty list after trims and pop\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testLpushStringByteArray() throws InterruptedException {\n\t\tcmd = Command.LPUSH.code + \" byte[] | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tbyte[] nil = null;\n\t\t\t\tprovider.lpush(\"foo\", nil);\n\t\t\t}\n\t\t\tcatch(IllegalArgumentException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting exception for null value to RPUSH\");\n\t\t\t\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.lpush(listkey, dataList.get(i));\n\t\t\t}\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\tFuture<List<byte[]>> lrangeResp = provider.lrange(listkey, 0, SMALL_CNT);\n\n\t\t\ttry {\n\t\t\t\t// use LLEN: size should be small count\n\t\t\t\tassertTrue(llenResp.get()==SMALL_CNT, \"LLEN after LPUSH is wrong\");\n\t\t\t\t\n\t\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\t\tList<byte[]> range = lrangeResp.get();\n\t\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after LPUSH is wrong\");\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\t\tassertEquals (dataList.get(i), range.get(r), \"range and reference list differ at i: \" + i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t@Test\n\tpublic void testLpoppushStringByteArray() throws InterruptedException {\n\t\tcmd = Command.RPOPLPUSH.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.lpush(listkey, dataList.get(i));\n\t\t\t}\n\t\t\t\n\t\t\tFuture<Long> llenRespBefore = provider.llen(listkey);\n\t\t\tList<Future<byte[]>> poppushResponses = new ArrayList<Future<byte[]>>();\n\t\t\t\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tpoppushResponses.add(provider.rpoplpush (listkey, listkey));\n\t\t\t}\n\t\t\t\n\t\t\tFuture<Long> llenRespAfter = provider.llen(listkey);\n\t\t\ttry {\n\t\t\t\t// use LLEN: size should be small count\n\t\t\t\tassertTrue(llenRespBefore.get()==SMALL_CNT, \"LLEN after LPUSH is wrong\");\n\t\t\t\t\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\t\tassertEquals (poppushResponses.get(i).get(), dataList.get(i), \"RPOPLPUSH result and reference list differ at i: \" + i);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// use LLEN: size should be small count\n\t\t\t\tassertTrue(llenRespAfter.get()==SMALL_CNT, \"LLEN after RPOPLPUSH is wrong\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testRpushStringByteArray() throws InterruptedException {\n\t\tcmd = Command.RPUSH.code + \" byte[] | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tbyte[] nil = null;\n\t\t\t\tprovider.rpush(\"foo\", nil);\n\t\t\t}\n\t\t\tcatch(IllegalArgumentException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting exception for null value to RPUSH\");\n\t\t\t\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.rpush(listkey, dataList.get(i));\n\t\t\t}\n\t\t\t\n\t\t\tFuture<Long> llenResp = provider.llen(listkey);\n\t\t\tFuture<List<byte[]>> lrangeResp = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\t\n\t\t\ttry {\n\t\t\t\t// use LLEN: size should be small count\n\t\t\t\tassertTrue(llenResp.get()==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\t\n\t\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\t\tList<byte[]> range = lrangeResp.get();\n\t\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\t\tassertEquals (dataList.get(i), range.get(i), \"range and reference list differ at i: \" + i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t@Test\n\tpublic void testMget() throws InterruptedException {\n\t\tcmd = Command.MGET.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.set (keys.get(i), dataList.get(i));\n\t\t\t}\n\t\t\tFuture<List<byte[]>> mgetResp1 = provider.mget(keys.get(0));\n\t\t\tFuture<List<byte[]>> mgetResp2 = provider.mget(keys.get(0), keys.get(1)); \n\t\t\tFuture<List<byte[]>> mgetResp3 = provider.mget(keys.get(0), keys.get(1), keys.get(2));\n\t\t\tFuture<List<byte[]>> mgetResp4 = provider.mget(\"foo\", \"bar\", \"paz\"); \n\t\t\t\n\t\t\ttry {\n\t\t\t\tList<byte[]>  values = null;\n\t\t\t\t\n\t\t\t\tvalues = mgetResp1.get();\n\t\t\t\tassertEquals(values.size(), 1, \"one value expected\");\n\t\t\t\tfor(int i=0; i<1; i++)\n\t\t\t\t\tassertEquals(values.get(i), dataList.get(i));\n\t\t\t\t\n\t\t\t\tvalues = mgetResp2.get();\n\t\t\t\tassertEquals(values.size(), 2, \"2 values expected\");\n\t\t\t\tfor(int i=0; i<2; i++)\n\t\t\t\t\tassertEquals(values.get(i), dataList.get(i));\n\t\t\t\t\n\t\t\t\tvalues = mgetResp3.get();\n\t\t\t\tassertEquals(values.size(), 3, \"3 values expected\");\n\t\t\t\tfor(int i=0; i<3; i++)\n\t\t\t\t\tassertEquals(values.get(i), dataList.get(i));\n\t\t\t\t\n\t\t\t\tvalues = mgetResp4.get();\n\t\t\t\tassertEquals(values.size(), 3, \"3 values expected\");\n\t\t\t\tfor(int i=0; i<3; i++)\n\t\t\t\t\tassertEquals(values.get(i), null, \"nonexistent key value in list should be null\");\n\t\t\t\t\n\t\t\t\t// edge cases\n\t\t\t\t// all should through exceptions\n\t\t\t\tboolean didRaiseEx;\n\t\t\t\tdidRaiseEx = false;\n\t\t\t\ttry {\n\t\t\t\t\tString[] keys = null;\n\t\t\t\t\tprovider.mget(keys).get();\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\t\tdidRaiseEx = false;\n\t\t\t\ttry {\n\t\t\t\t\tString[] keys = new String[0];\n\t\t\t\t\tprovider.mget(keys).get();\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\t\tdidRaiseEx = false;\n\t\t\t\ttry {\n\t\t\t\t\tString[] keys = new String[3];\n\t\t\t\t\tkeys[0] = stringList.get(0);\n\t\t\t\t\tkeys[1] = null;\n\t\t\t\t\tkeys[2] = stringList.get(2);\n\t\t\t\t\tprovider.mget(keys).get();\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testDel() throws InterruptedException {\n\t\tcmd = Command.DEL.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString key = this.keys.get(0);\n\t\t\tprovider.set (key, dataList.get(0));\n\t\t\tFuture<Boolean> existsResp1 = provider.exists(key); \n\t\t\tFuture<Long> delResp = provider.del(key);\n\t\t\tFuture<Boolean> existsResp2 = provider.exists(key); \n\n\t\t\ttry {\n\t\t\t\tassertEquals(delResp.get().longValue(), 1, \"one key should been deleted\");\n\t\t\t\tassertTrue (existsResp1.get(), \"After set key should exist\");\n\t\t\t\tassertFalse (existsResp2.get(), \"After del key should not exist\");\n\t\t\t\t\n\t\t\t\t// delete many keys\n\t\t\t\tprovider.flushdb();\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++) provider.set(stringList.get(i), dataList.get(i));\n\n\t\t\t\tString[] keysToDel = new String[SMALL_CNT];\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++) keysToDel[i] = stringList.get(i);\n\n\t\t\t\tFuture<Long> delCnt1 = provider.del(keysToDel);\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++) assertFalse (provider.exists(stringList.get(i)).get(), \"key should have been deleted\");\n\t\t\t\tassertEquals(delCnt1.get().longValue(), SMALL_CNT, \"SMALL_CNT keys were deleted\");\n\t\t\t\t\n\t\t\t\t// delete many keys but also spec one non existent keys - delete result should be less than key cnt\n\t\t\t\tprovider.flushdb();\n\t\t\t\tfor(int i=0; i<SMALL_CNT-1; i++) provider.set(stringList.get(i), dataList.get(i));\n\n\t\t\t\tkeysToDel = new String[SMALL_CNT];\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++) keysToDel[i] = stringList.get(i);\n\n\t\t\t\tFuture<Long> delCnt2 = provider.del(keysToDel);\n\t\t\t\tfor(int i=0; i<SMALL_CNT; i++) assertFalse (provider.exists(stringList.get(i)).get(), \"key should have been deleted\");\n\t\t\t\tassertEquals(delCnt2.get().longValue(), SMALL_CNT-1, \"SMALL_CNT-1 keys were actually deleted\");\n\n\t\t\t\t// edge cases\n\t\t\t\t// all should through exceptions\n\t\t\t\tboolean didRaiseEx;\n\t\t\t\tdidRaiseEx = false;\n\t\t\t\ttry {\n\t\t\t\t\tString[] keys = null;\n\t\t\t\t\tprovider.del(keys).get();\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\t\tdidRaiseEx = false;\n\t\t\t\ttry {\n\t\t\t\t\tString[] keys = new String[0];\n\t\t\t\t\tprovider.del(keys).get();\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\t\tdidRaiseEx = false;\n\t\t\t\ttry {\n\t\t\t\t\tString[] keys = new String[3];\n\t\t\t\t\tkeys[0] = stringList.get(0);\n\t\t\t\t\tkeys[1] = null;\n\t\t\t\t\tkeys[2] = stringList.get(2);\n\t\t\t\t\tprovider.del(keys).get();\n\t\t\t\t}\n\t\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testIncrAndDecr() throws InterruptedException {\n\t\tcmd = Command.INCR.code + \" | \" + Command.DECR.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tString cntr_key = keys.get(0);\n\n\t\t\tprovider.flushdb();\n\n\t\t\tFuture<Long> incrResp = null;\n\t\t\tfor(int i = 0; i<MEDIUM_CNT; i++){\n\t\t\t\tincrResp = provider.incr(cntr_key);\n\t\t\t}\n\t\t\tFuture<Long> decrResp = null;\n\t\t\tfor(int i = 0; i<MEDIUM_CNT; i++){\n\t\t\t\tdecrResp = provider.decr(cntr_key);\n\t\t\t}\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertEquals(incrResp.get().longValue(), MEDIUM_CNT, \"INCR should have counted counter to MEDIUM_CNT\");\n\t\t\t\tassertEquals(decrResp.get().longValue(), 0, \"DECR should have counted counter to zero\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testIncrbyAndDecrby() throws InterruptedException {\n\t\tcmd = Command.INCRBY.code + \" |\" + Command.DECRBY.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tString cntr_key = keys.get(0);\n\n\t\t\tprovider.flushdb();\n\n\t\t\tFuture<Long> incrbyResp = null;\n\t\t\tfor(int i = 0; i<MEDIUM_CNT; i++){\n\t\t\t\tincrbyResp = provider.incrby(cntr_key, 10);\n\t\t\t}\n\t\t\tFuture<Long> decrbyResp = null;\n\t\t\tfor(int i = 0; i<MEDIUM_CNT; i++){\n\t\t\t\tdecrbyResp = provider.decrby(cntr_key, 10);\n\t\t\t}\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertEquals(incrbyResp.get().longValue(), MEDIUM_CNT*10, \"INCRBY should have counted counter to MEDIUM_CNT*10\");\n\t\t\t\tassertEquals(decrbyResp.get().longValue(), 0, \"DECRBY should have counted counter to zero\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testGetSetStringByteArray() throws InterruptedException {\n\t\tcmd = Command.SET.code + \" | \" + Command.GETSET.code + \" byte[] \";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tprovider.set(keys.get(0), dataList.get(0));\n\t\t\tFuture<byte[]> getResp = provider.get(keys.get(0));\n\t\t\tFuture<byte[]> getsetResp1 = provider.getset(keys.get(0), dataList.get(1));\n\t\t\tFuture<byte[]> getsetResp2 = provider.getset(keys.get(1), dataList.get(2));\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertEquals(getResp.get(), dataList.get(0), \"get results doesn't match the expected data\");\n\t\t\t\tassertEquals(getsetResp1.get(), dataList.get(0), \"getset results doesn't match the expected data\");\n\t\t\t\tassertEquals(getsetResp2.get(), null, \"getset result for new key should have been null\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t@Test\n\tpublic void testHsetHget() throws InterruptedException {\n\t\tcmd = Command.HSET.code + \" | \" + Command.HGET + \" | \" + Command.HEXISTS;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tFuture<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));\n\t\t\tFuture<Boolean> hexistsResp1 = provider.hexists(keys.get(0), keys.get(1));\n\t\t\tFuture<Boolean> hexistsResp2 = provider.hexists(keys.get(0), keys.get(2));\n\t\t\tFuture<Boolean> hsetResp1_1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));\n\t\t\tFuture<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));\n\t\t\tFuture<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tFuture<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));\n\t\t\t\n\t\t\tFuture<byte[]> hgetResp1 = provider.hget(keys.get(0), keys.get(1));\n\t\t\tFuture<byte[]> hgetResp2 = provider.hget(keys.get(0), keys.get(2));\n\t\t\tFuture<byte[]> hgetResp3 = provider.hget(keys.get(0), keys.get(3));\n\t\t\tFuture<byte[]> hgetResp4 = provider.hget(keys.get(0), keys.get(4));\n\t\t\t\n\t\t\tFuture<Long> hlenResp1 = provider.hlen(keys.get(0));\n\n\t\t\tFuture<Boolean> hdelResp1 = provider.hdel(keys.get(0), keys.get(1));\n\t\t\tFuture<Boolean> hdelResp2 = provider.hdel(keys.get(0), keys.get(1));\n\t\t\t\n\t\t\tFuture<Long> hlenResp2 = provider.hlen(keys.get(0));\n\t\t\tFuture<Long> hlenResp3 = provider.hlen(\"some-random-key\");\n\t\t\t\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertTrue (hsetResp1.get(), \"hset using byte[] value\");\n\t\t\t\tassertTrue (hexistsResp1.get(), \"hexists of field should be true\");\n\t\t\t\tassertTrue (!hexistsResp2.get(), \"hexists of non existent field should be false\");\n\t\t\t\tassertTrue (!hsetResp1_1.get(), \"second hset using byte[] value should return false\");\n\t\t\t\tassertTrue (hsetResp2.get(), \"hset using String value\");\n\t\t\t\tassertTrue (hsetResp3.get(), \"hset using Number value\");\n\t\t\t\tassertTrue (hsetResp4.get(), \"hset using Object value\");\n\t\t\t\t\n\t\t\t\tassertEquals (hgetResp1.get(), dataList.get(0), \"hget of field with byte[] value\");\n\t\t\t\tassertEquals (DefaultCodec.toStr(hgetResp2.get()), stringList.get(0), \"hget of field with String value\");\n\t\t\t\tassertEquals (DefaultCodec.toLong(hgetResp3.get()).longValue(), 222, \"hget of field with Number value\");\n\t\t\t\tTestBean objval = DefaultCodec.decode(hgetResp4.get());\n\t\t\t\tassertEquals (objval.getName(), objectList.get(0).getName(), \"hget of field with Object value\");\n\t\t\t\t\n\t\t\t\tassertTrue (hdelResp1.get(), \"hdel of field should be true\");\n\t\t\t\tassertTrue (!hdelResp2.get(), \"hdel of non-existent field should be false\");\n\t\t\t\t\n\t\t\t\tassertEquals (hlenResp1.get().longValue(), 4, \"hlen of hash should be 4\");\n\t\t\t\tassertEquals (hlenResp2.get().longValue(), 3, \"hlen of hash should be 3\");\n\t\t\t\tassertEquals (hlenResp3.get().longValue(), 0, \"hlen of non-existant hash should be 0\");\n\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\n\t@Test\n\tpublic void testHIncrBy() throws InterruptedException {\n\t\tcmd = Command.HSET.code + \" | \" + Command.HGET + \" | \" + Command.HINCRBY;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tFuture<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), 41);\n\t\t\tFuture<Long> hincrBy1 = provider.hincrby(keys.get(0), keys.get(1), 1);\n\t\t\tFuture<byte[]> hget = provider.hget(keys.get(0), keys.get(1));\n\t\t\t\t\t\t\n\t\t\tFuture<Long> hincrBy2 = provider.hincrby(keys.get(0), keys.get(2), 4);\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertTrue (hsetResp1.get(), \"hset using byte[] value\");\n\t\t\t\tassertEquals (hincrBy1.get(), (Long)42l, \"hexists of field should be true\");\n\t\t\t\tassertEquals(hget.get(), Convert.toBytes(42l));\n\t\t\t\tassertEquals(hincrBy2.get(), (Long)4l);\n\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testHkeys() throws InterruptedException {\n\t\tcmd = Command.HSET.code + \" | \" + Command.HKEYS;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tFuture<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));\n\t\t\tFuture<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));\n\t\t\tFuture<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tFuture<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));\n\t\t\t\n\t\t\t// get keys\n\t\t\tFuture<List<byte[]>> hkeysResp1 = provider.hkeys(keys.get(0));\n\t\t\t// alright - empty the hash\n\t\t\tfor(int i=1; i<5; i++)\n\t            try {\n\t                assertTrue(provider.hdel(keys.get(0), keys.get(i).getBytes()).get());\n                }\n                catch (ExecutionException e) {\n    \t\t\t\tThrowable cause = e.getCause();\n    \t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n                }\n\t\t\t// get keys again\n\t\t\tFuture<List<byte[]>> hkeysResp2 = provider.hkeys(keys.get(0));\n\t\t\t// nil case\n\t\t\tFuture<List<byte[]>> hkeysResp3 = provider.hkeys(\"no-such-hash\");\n\t\t\t\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertTrue (hsetResp1.get(), \"hset using byte[] value\");\n\t\t\t\tassertTrue (hsetResp2.get(), \"hset using String value\");\n\t\t\t\tassertTrue (hsetResp3.get(), \"hset using Number value\");\n\t\t\t\tassertTrue (hsetResp4.get(), \"hset using Object value\");\n\t\t\t\t\n\t\t\t\tList<byte[]> hkeys = hkeysResp1.get(); \n\t\t\t\tassertEquals (hkeys.size(), 4, \"keys list size should be 4\");\n\t\t\t\tassertEquals(hkeysResp2.get(), Collections.EMPTY_LIST, \"result should be empty\");\n\t\t\t\tassertEquals(hkeysResp3.get(), Collections.EMPTY_LIST, \"list of keys of non-existent hash should be empty\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t@Test\n\tpublic void testSetBitGetBit() throws InterruptedException {\n\t\tcmd = Command.SETBIT.code + \" | \" + Command.GETBIT;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tFuture<Boolean> setbit1 = provider.setbit(keys.get(0), 1, true);\n\t\t\tFuture<Boolean> setbit32 = provider.setbit(keys.get(0), 32, true);\n\n\t\t\tFuture<Boolean> getbit1 = provider.getbit(keys.get(0), 1);\n\t\t\tFuture<Boolean> getbit2 = provider.getbit(keys.get(0), 2);\n\t\t\tFuture<Boolean> getbit32 = provider.getbit(keys.get(0), 32);\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertFalse (setbit1.get(), \"original bit at 1\");\n\t\t\t\tassertFalse (setbit32.get(), \"original bit at 32\");\n\t\t\t\tassertTrue (getbit1.get(), \"getbit at 1\");\n\t\t\t\tassertFalse (getbit2.get(), \"getbit at 2\");\n\t\t\t\tassertTrue (getbit32.get(), \"getbit at 32\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\n\t@Test\n\tpublic void testHvals() throws InterruptedException {\n\t\tcmd = Command.HSET.code + \" | \" + Command.HVALS;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tFuture<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));\n\t\t\tFuture<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));\n\t\t\tFuture<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tFuture<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));\n\t\t\t\n\t\t\t// get values\n\t\t\tFuture<List<byte[]>> hvalsResp1 = provider.hvals(keys.get(0));\n\t\t\t// alright - empty the hash\n\t\t\tfor(int i=1; i<5; i++)\n\t            try {\n\t                assertTrue(provider.hdel(keys.get(0), keys.get(i)).get());\n                }\n                catch (ExecutionException e) {\n    \t\t\t\tThrowable cause = e.getCause();\n    \t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n                }\n\t\t\t// get values again\n    \t\t\t// get values\n\t\t\tFuture<List<byte[]>> hvalsResp2 = provider.hvals(keys.get(0));\n\t\t\t// nil case\n\t\t\tFuture<List<byte[]>> hvalsResp3 = provider.hvals(\"no-such-hash\");\n\t\t\t\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertTrue (hsetResp1.get(), \"hset using byte[] value\");\n\t\t\t\tassertTrue (hsetResp2.get(), \"hset using String value\");\n\t\t\t\tassertTrue (hsetResp3.get(), \"hset using Number value\");\n\t\t\t\tassertTrue (hsetResp4.get(), \"hset using Object value\");\n\t\t\t\t\n\t\t\t\tList<byte[]> hvals = hvalsResp1.get(); \n\t\t\t\tassertEquals(hvals.size(), 4, \"values list size should be 4\");\n\t\t\t\tassertEquals(hvalsResp2.get(), Collections.EMPTY_LIST, \"values list size should be empty\");\n\t\t\t\tassertEquals(hvalsResp3.get(), Collections.EMPTY_LIST, \"list of values of non-existent hash should be empty\");\n\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\n\t@Test\n\tpublic void testHgetall() throws InterruptedException {\n\t\tcmd = Command.HSET.code + \" | \" + Command.HGETALL;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tFuture<Boolean> hsetResp1 = provider.hset(keys.get(0), keys.get(1), dataList.get(0));\n\t\t\tFuture<Boolean> hsetResp2 = provider.hset(keys.get(0), keys.get(2), stringList.get(0));\n\t\t\tFuture<Boolean> hsetResp3 = provider.hset(keys.get(0), keys.get(3), 222);\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tFuture<Boolean> hsetResp4 = provider.hset(keys.get(0), keys.get(4), objectList.get(0));\n\t\t\t\n\t\t\t// get keys\n\t\t\tFuture<List<byte[]>> frHkeys = provider.hkeys(keys.get(0));\n\t\t\t\n\t\t\t// get all\n\t\t\tFuture<Map<byte[], byte[]>> frHmap1 = provider.hgetall(keys.get(0));\n\t\t\t\n\t\t\t// delete all keys\n\t\t\tfor(int i =1; i<5; i++) {\n\t            try {\n\t                provider.hdel(keys.get(0), keys.get(i)).get();\n                }\n                catch (ExecutionException e) {\n    \t\t\t\tThrowable cause = e.getCause();\n    \t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n                }\n\t\t\t}\n\t\t\t// get all again\n\t\t\tFuture<Map<byte[], byte[]>> frHmap2 = provider.hgetall(keys.get(0));\n    \t\t\t\n\t\t\t// get all for non-existent hash\n\t\t\tFuture<Map<byte[], byte[]>> frHmap3 = provider.hgetall(\"no-such-hash\");\n        \t\t\t\n\t\t\ttry {\n\t\t\t\tassertTrue (hsetResp1.get(), \"hset using byte[] value\");\n\t\t\t\tassertTrue (hsetResp2.get(), \"hset using String value\");\n\t\t\t\tassertTrue (hsetResp3.get(), \"hset using Number value\");\n\t\t\t\tassertTrue (hsetResp4.get(), \"hset using Object value\");\n\t\t\t\t\n\t\t\t\tassertEquals( frHmap1.get().size(), 4, \"hash map length\");\n\t\t\t\tassertEquals( frHkeys.get().size(), 4, \"keys list length\");\n\n\t\t\t\tMap<String, byte[]> hmap = DefaultCodec.toDataDictionary(frHmap1.get());\n\t\t\t\tassertEquals(hmap.get(keys.get(1)), dataList.get(0), \"byte[] value mapping should correspond to prior HSET\");\n\t\t\t\tassertEquals(DefaultCodec.toStr(hmap.get(keys.get(2))), stringList.get(0), \"String value mapping should correspond to prior HSET\");\n\t\t\t\tassertEquals(DefaultCodec.toLong(hmap.get(keys.get(3))).longValue(), 222, \"Number value mapping should correspond to prior HSET\");\n\t\t\t\tassertEquals(DefaultCodec.decode(hmap.get(keys.get(4))), objectList.get(0), \"Object value mapping should correspond to prior HSET\");\n\t\t\t\t\n\t\t\t\tMap<String, byte[]> hmap2 = DefaultCodec.toDataDictionary(frHmap2.get());\n\t\t\t\tassertEquals(hmap2, Collections.EMPTY_MAP, \"result should be empty\");\n\t\t\t\t\n\t\t\t\tMap<String, byte[]> hmap3 = DefaultCodec.toDataDictionary(frHmap3.get());\n\t\t\t\tassertEquals(hmap3, Collections.EMPTY_MAP, \"hgetall for non existent hash should be empty\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, byte[])}.\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testSetStringByteArray() throws InterruptedException {\n\t\tcmd = Command.SET.code + \" | \" + Command.SETNX.code + \" byte[] | \" + Command.GET;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tprovider.set(keys.get(keys.size()-1), emptyBytes);\n\t\t\tFuture<byte[]> getResp = provider.get(keys.get(keys.size()-1));\n\t\t\tFuture<Boolean> setnxResp1 = provider.setnx(keys.get(1), dataList.get(1));\n\t\t\tFuture<Boolean> setnxResp2 = provider.setnx(keys.get(1), dataList.get(2));\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertEquals(getResp.get(), emptyBytes, \"set and get results for empty byte[]\");\n\t\t\t\tassertTrue(setnxResp1.get());\n\t\t\t\tassertFalse(setnxResp2.get());\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t\n\t/**\n\t * Test method for {@link JRedisFuture#append(String, String)}\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testAppendStringString() throws InterruptedException {\n\t\tcmd = Command.APPEND.code + \" | \" + Command.GET.code + \" String\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// append to a non-existent key\n\t\t\t// as of Redis 1.3.7 it behaves just like set but returns value len instead of status\n\t\t\tString key1 = keys.get(0);\n\t\t\t\n\t\t\tFuture<Long> frLen0 = provider.append(key1, emptyString);\n\t\t\tFuture<byte[]> frGet0 = provider.get(key1);\n\t\t\t\n\t\t\tFuture<Long> frLen1 = provider.append(key1, stringList.get(0));\n\t\t\tFuture<byte[]> frGet1 = provider.get(key1);\n\t\t\t\n\t\t\tFuture<Long> frLen2 = provider.append(key1, stringList.get(1));\n\t\t\tFuture<byte[]> frGet2 = provider.get(key1);\n\t\t\t\n\t\t\tprovider.sadd(keys.get(1), stringList.get(0));\n\t\t\tFuture<Long>   frExpectedError = provider.append(keys.get(1), stringList.get(0));\n\t\t\t\n\t\t\ttry {\n\t\t\t\tassertEquals(frLen0.get().longValue(), 0, \"append of emtpy string to new key should be zero\");\n\t\t\t\tassertEquals(DefaultCodec.toStr(frGet0.get()), emptyString, \"get results after append to new key for empty string\");\n\t\t\t\t\n\t\t\t\tassertEquals(frLen1.get().longValue(), stringList.get(0).length(), \"append of emtpy string to new key should be zero\");\n\t\t\t\tassertEquals(DefaultCodec.toStr(frGet1.get()), stringList.get(0), \"get results after append to new key for empty string\");\n\t\t\t\t\n\t\t\t\tassertEquals(frLen2.get().longValue(), stringList.get(0).length() + stringList.get(1).length(), \"append of emtpy string to new key should be zero\");\n\t\t\t\tStringBuffer appendedString = new StringBuffer();\n\t\t\t\tappendedString.append(stringList.get(0));\n\t\t\t\tappendedString.append(stringList.get(1));\n\t\t\t\tassertEquals(DefaultCodec.toStr(frGet2.get()), appendedString.toString(), \"get results after append to new key for empty string\");\n\t\t\t\t\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\n\t\t\t\n\t\t\t// check see if we got the expected RedisException\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tfrExpectedError.get();\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tif(cause instanceof RedisException)\n\t\t\t\t\texpected = true;\n\t\t\t\telse\n\t\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t\tassertTrue(expected, \"expecting RedisException for append to a non-string key\");\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rename(java.lang.String, java.lang.String)}.\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testRename() throws InterruptedException {\n\t\tcmd = Command.RENAME.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\t\n\t\t\tString newkey = null;\n\t\t\tbyte[] value = dataList.get(0);\n\t\t\tkey = getRandomAsciiString (random.nextInt(24)+2);\n\t\t\tnewkey = getRandomAsciiString (random.nextInt(24)+2);\n\t\t\t\n\t\t\tFuture<ResponseStatus> \tflushResp = provider.flushdb();\n\t\t\tFuture<ResponseStatus> \tsetResp = provider.set (key, value);\n\t\t\tFuture<byte[]> \t\t\tgetOldResp = provider.get(key);\n\t\t\tFuture<ResponseStatus> \treanmeResp = provider.rename (key, newkey);\n\t\t\tFuture<byte[]> \t\t\tgetNewResp = provider.get(newkey);\n\t\t\t\n\t\t\ttry {\n\t\t\t\tflushResp.get();\n\t\t\t\tsetResp.get();\n\t\t\t\tassertEquals(value, getOldResp.get());\n\t\t\t\treanmeResp.get();\n\t\t\t\tassertEquals(value, getNewResp.get());\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\t// errors in response \n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rename(java.lang.String, java.lang.String)}.\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testRenamenx() throws InterruptedException {\n\t\tcmd = Command.RENAMENX.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\t// flush db and set a key\n\t\t\tprovider.flushdb();\n\t\t\tprovider.set (keys.get(0), dataList.get(0));\n\t\t\t\n\t\t\t// this should return true in future\n\t\t\tFuture<Boolean> \treanmenxResp1 = provider.renamenx (keys.get(0), keys.get(2));\n\n\t\t\t// flush db again and set 2 keys\n\t\t\tprovider.flushdb();\n\t\t\tprovider.set (keys.get(1), dataList.get(1));\n\t\t\tprovider.set (keys.get(2), dataList.get(2));\n\t\t\t\n\t\t\t// this should return false in future\n\t\t\tFuture<Boolean> \treanmenxResp2 = provider.renamenx (keys.get(1), keys.get(2));\n\t\t\t\n\t\t\ttry {\n\t\t\t\t// note that we don't have to 'get' the future results for \n\t\t\t\t// commands we are not interested in.\n\t\t\t\tassertTrue (reanmenxResp1.get(), \"1st renamenx should have been true\");\n\t\t\t\tassertFalse (reanmenxResp2.get(), \"2nd renamenx should have been false\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\t// errors in response \n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) {  fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e);  }\n\t}\n\n\t/**\n\t * Test settting a key in a flushed db, and then checking\n\t * exists, flushing again, and finally keys().  \n\t * Will invoke commands asynchronously, and after \n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testSetAndFlushdbAndExistsAndKeys() throws InterruptedException {\n\t\tcmd = \n\t\t\tCommand.FLUSHDB.code + \" | \" +\n\t\t\tCommand.SET.code + \" | \" +\n\t\t\tCommand.EXISTS.code + \" | \" +\n\t\t\tCommand.FLUSHDB.code + \" | \" +\n\t\t\tCommand.KEYS.code;\n\t\t\t\n\t\tLog.log(\"TEST: %s commands\", cmd);\n\t\ttry {\n\t\t\tkey = \"woof\";\n\t\t\tFuture<ResponseStatus> flushResp = provider.flushdb();\n\t\t\tFuture<ResponseStatus> setResp = provider.set(key, \"meow\");\n\t\t\tFuture<Boolean> existsResp = provider.exists(key);\n\t\t\tFuture<ResponseStatus> flush2Resp = provider.flushdb();\n\t\t\tFuture<List<byte[]>>  keysResp = provider.keys();\n\t\t\t\n\t\t\ttry {\n\t\t\t\tflushResp.get(); // no need to check status; if error exception is raised\n\t\t\t\tsetResp.get();\n\t\t\t\tassertTrue(existsResp.get(), \"key should exists at this point\");\n\t\t\t\tflush2Resp.get();\n\t\t\t\tassertTrue(keysResp.get().size() == 0, \"keys should have returned list of 0 items\");\n\t\t\t}\n\t\t\tcatch(ExecutionException e){\n\t\t\t\t// errors in response \n\t\t\t\tThrowable cause = e.getCause();\n\t\t\t\tfail(cmd + \" ERROR => \" + cause.getLocalizedMessage(), e); \n\t\t\t}\n\t\t} \n\t\tcatch (ClientRuntimeException e) { \n\t\t\t// errors in request time\n\t\t\tfail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e); \n\t\t}\n\t}\n\t\n\t/**\n\t * Tests to force RedisExceptions against various response types.\n\t * First we queue the requests and then we get the responses for all.\n\t * This tests both the primary goal and the correct behaviour of asynch\n\t * provider to queue the responses.\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testElicitErrors() throws InterruptedException {\n\t\tLog.log(\"TEST: Elicit errors\");\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString key = keys.get(0);\n\t\t\ttry {\n\t            provider.set(key, smallData).get();\n            }\n            catch (ExecutionException e) {\n            \tfail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); \n            }\n\t\t\t\n            // queue a few commands -- all are expected to result in ExecutionExcetion on Future.get()\n            //\n\t\t\tFuture<Boolean>\tfSaddResp = provider.sadd(key, dataList.get(0)); \n\t\t\tFuture<Long>\tfScardResp = provider.scard(key); \n\t\t\tFuture<byte[]>  fLpopResp = provider.lpop(key); \n\t\t\tFuture<List<byte[]>> fSmembersResp = provider.smembers(key); \n\t\t\t\n\t\t\tboolean expectedError;\n\t\t\t\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"1 - Expecting an operation against key holding the wrong kind of value ERROR for SADD..\");\n\t\t\t\tfSaddResp.get();\n\t\t\t}\n\t\t\tcatch (ExecutionException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"2 - Expecting an operation against key holding the wrong kind of value ERROR for SCARD..\");\n\t\t\t\tfScardResp.get();\n\t\t\t}\n\t\t\tcatch (ExecutionException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"3 - Expecting an operation against key holding the wrong kind of value ERROR for LPOP ..\");\n\t\t\t\tfLpopResp.get();\n\t\t\t}\n\t\t\tcatch (ExecutionException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"4 - Expecting an operation against key holding the wrong kind of value ERROR for SMEMBERS ..\");\n\t\t\t\tfSmembersResp.get();\n\t\t\t}\n\t\t\tcatch (ExecutionException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\t\n\t\t} \n\t\tcatch (ClientRuntimeException e) { fail(cmd + \" Runtime ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * Asynchronous responses must provide reference to {@link RedisException}\n\t * through the {@link ExecutionException#getCause()} per {@link Future} semantics.\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testExecutionExceptionCauseType() throws InterruptedException {\n\t\tboolean expectedError;\n\t\tString key = keys.get(0);\n\t\ttry {\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\t\n\t\t\t\tprovider.set(key, smallData);  // don't wait for response ..\n\t\t\t\tFuture<Boolean> fBool = provider.sadd(key, dataList.get(0));\n\t\t\t\t@SuppressWarnings(\"unused\")\n                boolean response = fBool.get(); // wait for response\n\t\t\t}\n            catch (ExecutionException e) {\n            \texpectedError = true;\n            \tThrowable cause = e.getCause();\n            \tif(cause instanceof RedisException)\n            \t\tLog.log(\"%s (as excepted)\", cause);\n            \telse\n            \t\tfail(\"FAULT: the cause of ExecutionException was expected to be a RedisException\");\n            }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t}\n\t\tfinally {\n\t\t\t\n\t\t}\n\t}\n\t\n\t/**\n\t * Test {@link JRedisFuture#ping()}\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testPing () throws InterruptedException {\n\t\tFuture<ResponseStatus> frStatus = null;\n\t\tcmd = Command.PING.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tfrStatus = provider.ping();\n\t\t\tResponseStatus status = frStatus.get();\n\t\t\tassertTrue(!status.isError(), \"ping return status\");\n\t\t}\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n\t        fail(cmd + \" FAULT: \" + e.getCause().getLocalizedMessage(), e);\n        }\n\t}\n\t/**\n\t * Test {@link JRedisFuture#flushdb()}\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testFlushDb () throws InterruptedException {\n\t\tFuture<ResponseStatus> frStatus = null;\n\t\tcmd = Command.FLUSHDB.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tfrStatus = provider.flushdb();\n\t\t\tResponseStatus status = frStatus.get();\n\t\t\tassertTrue(!status.isError(), \"flushdb return status\");\n\t\t}\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n\t        fail(cmd + \" FAULT: \" + e.getCause().getLocalizedMessage(), e);\n        }\n\t}\n\t@Test\n\tpublic void testEcho() throws InterruptedException {\n\t\tFuture<byte[]> echoResp = null;\n\t\tcmd = Command.ECHO.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\techoResp = provider.echo(dataList.get(0));\n\t\t\tassertEquals(dataList.get(0), echoResp.get(), \"data and echo results\");\n\n\t\t\tbyte[] zerolenData = new byte[0];\n\t\t\tassertEquals(zerolenData, provider.echo(zerolenData).get(), \"zero len byte[] and echo results\");\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tprovider.echo((byte[])null);\n\t\t\t}\n\t\t\tcatch(IllegalArgumentException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting exception for null value to ECHO\");\n\n\t\t}\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n\t        fail(cmd + \" FAULT: \" + e.getCause().getLocalizedMessage(), e);\n        }\n\t}\n\t\n\t@Test\n\tpublic void testBgrewriteaof() throws InterruptedException {\n\t\tFuture<String> cmdRespMsg = null;\n\t\tcmd = Command.BGREWRITEAOF.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tcmdRespMsg = provider.bgrewriteaof();\n\t\t\tassertTrue(cmdRespMsg.get() != null, \"cmd response message should not be null\");\n\t\t}\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n\t        fail(cmd + \" FAULT: \" + e.getCause().getLocalizedMessage(), e);\n        }\n\t}\n\t\n\t/**\n\t * Test {@link JRedisFuture#debug()}\n\t * @throws InterruptedException \n\t */\n\t@Test\n\tpublic void testDebug () throws InterruptedException {\n\t\tFuture<ObjectInfo> frInfo = null;\n\t\tcmd = Command.DEBUG.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tprovider.set(\"foo\", \"bar\");\n\t\t\tfrInfo = provider.debug(\"foo\");\n\t\t\tObjectInfo info = frInfo.get();\n\t\t\tassertNotNull(info);\n\t\t\tLog.log(\"DEBUG of key => %s\", info);\n\t\t}\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n\t        fail(cmd + \" FAULT: \" + e.getCause().getLocalizedMessage(), e);\n        }\n\t}\n\t\n\t@Test\n\tpublic void testExpireat() throws InterruptedException {\n\t\tcmd = Command.EXPIREAT.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb().get();\n\t\t\tString keyToExpire = \"expire-me\";\n\t\t\tprovider.set(keyToExpire, dataList.get(0)).get();\n\n\t\t\tLog.log(\"TEST: %s with expire time 1000 msecs in future\", Command.EXPIREAT);\n\t\t\tassertTrue(provider.expireat(keyToExpire, System.currentTimeMillis() + 2000).get(), \"expireat for existing key should be true\");\n      assertTrue (provider.exists(keyToExpire).get());\n\t\t\tassertTrue(!provider.expireat(\"no-such-key\", System.currentTimeMillis() + 500).get(), \"expireat for non-existant key should be false\");\n\t\t\t\n\t\t\t\n\t\t\t// NOTE: IT SIMPLY WON'T WORK WITHOUT GIVING REDIS A CHANCE\n\t\t\t// could be network latency, or whatever, but the expire command is NOT\n\t\t\t// that precise, so we need to wait a bit longer\n\t\t\t\n\t\t\tThread.sleep(5000);\n\t\t\tassertTrue (!provider.exists(keyToExpire).get(), \"key should have expired by now\");\n\t\t}\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n\t        fail(cmd + \" FAULT: \" + e.getCause().getLocalizedMessage(), e);\n        }\n\t}\n\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisPipelineServiceTest.java",
    "content": "///*\n// *   Copyright 2009 Joubin Houshyar\n// * \n// *   Licensed under the Apache License, Version 2.0 (the \"License\");\n// *   you may not use this file except in compliance with the License.\n// *   You may obtain a copy of the License at\n// *    \n// *   http://www.apache.org/licenses/LICENSE-2.0\n// *    \n// *   Unless required by applicable law or agreed to in writing, software\n// *   distributed under the License is distributed on an \"AS IS\" BASIS,\n// *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *   See the License for the specific language governing permissions and\n// *   limitations under the License.\n// */\n//\n//package org.jredis.ri.alphazero;\n//\n//import static org.testng.Assert.fail;\n//import org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\n//import org.jredis.connector.ConnectionSpec;\n//import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n//import org.jredis.ri.alphazero.support.Log;\n//import org.testng.annotations.AfterTest;\n//import org.testng.annotations.Test;\n//\n///**\n// * As of now, this class simply runs the same set of {@link JRedis} contract\n// * compliance using {@link JRedisService} as the provider.\n// * \n// * TODO: figure out a good way to meaningfully test service (e.g. concurrent\n// * and random method usage ..)\n// *\n// * @author  Joubin Houshyar (alphazero@sensesay.net)\n// * @version alpha.0, Nov 6, 2009\n// * @since   alpha.0\n// * \n// */\n////@Test(sequential = true, suiteName=\"JRedisPipelineService-tests\")\n////public class JRedisPipelineServiceTest extends JRedisProviderTestsBase {\n//public class JRedisPipelineServiceTest extends ConcurrentJRedisProviderTestsBase {\n//\n//\t// ------------------------------------------------------------------------\n//\t// TEST SETUP \n//\t// ------------------------------------------------------------------------\n//\t/* (non-Javadoc)\n//\t * @see org.jredis.ri.ProviderTestBase#newProviderInstance()\n//\t */\n//\t@Override\n//\tprotected JRedis newProviderInstance () {\n//\t\tJRedis provider = null;\n//\t\ttry {\n//\t\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(this.host, this.port, this.db2, this.password.getBytes());\n//\t\t\tprovider = new JRedisPipelineService(connectionSpec);\n//        }\n//        catch (ClientRuntimeException e) {\n//        \tLog.error(e.getLocalizedMessage());\n//        }\n//        return provider;\n//\t}\n//\t// ------------------------------------------------------------------------\n//\t// The Tests\n//\t// ========================================================= JRedisClient\n//\t/**\n//\t * We define and run any additional, provider specific tests here.  The\n//\t * basic generally applicable JRedis interface method test are defined \n//\t * in the super class.\n//\t * \n//\t * Here we test Quit in a post test method to insure all tests have been\n//\t * completed.\n//\t */\n//\t// ------------------------------------------------------------------------\n//\t\n//\t/**\n//\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#auth(java.lang.String)}.\n//\t */\n//\t@AfterTest\n//\tpublic void testQuit() {\n//\t\tLog.log(\"TEST: QUIT command \");\n//\t\ttry {\n//\t\t\tJRedis service = getProviderInstance();\n//\t\t\tservice.quit ();\n//\t\t} \n//\t\tcatch (Exception e) {\n//\t\t\tfail(\"QUIT\" + e);\n//\t\t}\n//\t}\n//}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisPipelineTest.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport static org.testng.Assert.fail;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.AfterTest;\nimport org.testng.annotations.Test;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Oct 10, 2009\n * @since   alpha.0\n * \n */\n@Test(sequential = true, suiteName=\"JRedisPipeline-tests\")\n\npublic class JRedisPipelineTest extends JRedisFutureProviderTestsBase {\n\n\t// ------------------------------------------------------------------------\n\t// JRedisPipelineTest specific Test Suite Parameters\n\t// ------------------------------------------------------------------------\n\t\n\t// ------------------------------------------------------------------------\n\t// TEST SETUP \n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc)\n\t * @see org.jredis.ri.ProviderTestBase#newProviderInstance()\n\t */\n\t@Override\n\tprotected JRedisFuture newProviderInstance () {\n\t\tJRedisFuture provider = null;\n\t\ttry {\n\t\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(this.host, this.port, this.db2, this.password.getBytes());\n\t\t\tprovider = new JRedisPipeline(connectionSpec);\n        }\n        catch (ClientRuntimeException e) {\n        \tLog.error(e.getLocalizedMessage());\n        }\n        return provider;\n\t}\n\t// ------------------------------------------------------------------------\n\t// The Tests\n\t// ========================================================= JRedisClient\n\t/**\n\t * We define and run any additional, provider specific tests here.  The\n\t * basic generally applicable JRedis interface method test are defined \n\t * in the super class.\n\t * \n\t * Here we test Quit in a post test method to insure all tests have been\n\t * completed.\n\t */\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Pipeline quit.  \n\t * We first ping and await the response to insure pipeline has processed\n\t * all pending responses, and then issue the quit command.\n\t */\n\t@AfterTest\n\tpublic void testQuit() {\n\t\ttry {\n\t\t\tJRedisFuture pipeline = getProviderInstance();\n\t\t\tpipeline.ping().get();\n\t\t\tpipeline.quit().get();\n\t\t} \n\t\tcatch (Exception e) {\n\t\t\tfail(\"QUIT\" + e);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisProviderTestsBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero;\n\nimport static org.jredis.ri.alphazero.support.DefaultCodec.decode;\nimport static org.jredis.ri.alphazero.support.DefaultCodec.toLong;\nimport static org.jredis.ri.alphazero.support.DefaultCodec.toStr;\nimport static org.testng.Assert.assertEquals;\nimport static org.testng.Assert.assertFalse;\nimport static org.testng.Assert.assertNotNull;\nimport static org.testng.Assert.assertNull;\nimport static org.testng.Assert.assertTrue;\nimport static org.testng.Assert.fail;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.jredis.JRedis;\nimport org.jredis.ObjectInfo;\nimport org.jredis.Query;\nimport org.jredis.RedisException;\nimport org.jredis.RedisInfo;\nimport org.jredis.RedisType;\nimport org.jredis.ZSetEntry;\nimport org.jredis.protocol.Command;\nimport org.jredis.ri.JRedisTestSuiteBase;\nimport org.jredis.ri.RI.Version;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.Test;\n\n/**\n * This class is abstract and it is to remain abstract.\n * It provides the comprehensive set of tests of all {@link JRedis} methods.\n */\n@Version(major=2, minor=0)\npublic abstract class JRedisProviderTestsBase extends JRedisTestSuiteBase<JRedis>{\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\n\t/** JRedis Command being tested -- for log info */\n\tprivate String cmd;\n\t\n\t// ------------------------------------------------------------------------\n\t// The Tests\n\t// ========================================================= JRedis =======\n\t/**\n\t * We define and run provider agnostic tests here.  This means we run a set\n\t * of JRedis interface method tests that every connected JRedis implementation\n\t * should be able to support. \n\t * \n\t * The following commands are omitted:\n\t * 1 - QUIT: since we may be testing a multi-connection provider\n\t * 2 - SHUTDOWN: for the same reason as QUIT \n\t * 3 - MOVE and SELECT\n\t */\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#auth(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testElicitErrors() {\n\t\tLog.log(\"TEST: Elicit errors\");\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString key = keys.get(0);\n\t\t\tprovider.set(key, smallData);\n\t\t\tboolean expectedError;\n\t\t\t\n\t\t\t// -- commands returning status response \n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\tprovider.sadd(key, dataList.get(0)); \n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\t// -- commands returning value response \n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\tprovider.scard(key); \n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\t// -- commands returning bulk response\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\tprovider.lpop(key); \n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\t\n\t\t\t// -- commands returning multi-bulk response \n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\tprovider.smembers(key); \n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n//\t/**\n//\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#auth(java.lang.String)}.\n//\t */\n//\t@Test\n//\tpublic void testAuth() {\n//\t\ttest = Command.AUTH.code;\n//\t\tLog.log(\"TEST: %s command\", test);\n//\t\ttry {\n//\t\t\tjredis.auth(password);\n//\t\t} \n//\t\tcatch (RedisException e) {\n//\t\t\tfail(test + \" with password: \" + password, e);\n//\t\t}\n//\t}\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#ping()}.\n\t */\n\t@Test\n\tpublic void testPing() {\n\t\tcmd = Command.PING.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.ping();\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t/**\n\t * Tests:\n\t * <li>Test method for {@link org.jredis.ri.alphazero.JRedisSupport#exists(java.lang.String)}.\n\t * <li>Test method for {@link org.jredis.ri.alphazero.JRedisSupport#expire(java.lang.String, int)}.\n\t * <li>Test method for {@link org.jredis.ri.alphazero.JRedisSupport#ttl (java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testExists_Expire_TTL() {\n\t\tcmd = Command.EXISTS.code + \" | \" + Command.EXPIRE.code + \" | \" + Command.TTL.code;\n\t\tLog.log(\"TEST: %s command(s)\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tassertTrue(provider.dbsize() == 0);\n\t\t\t\n\t\t\tString keyToExpire = \"expire-me\";\n\t\t\tString keyToKeep = \"keep-me\";\n\t\t\t\n\t\t\tprovider.set(keyToKeep, \"master\");\n\t\t\tprovider.set(keyToExpire, System.currentTimeMillis());\n\t\t\tassertTrue (provider.exists(keyToExpire));\n\t\t\t\n\t\t\tLog.log(\"TEST: %s with expire time of %d\", Command.EXPIRE, expire_secs);\n\t\t\tprovider.expire(keyToExpire, expire_secs);\n\t\t\tassertTrue (provider.exists(keyToExpire));\n\t\t\t\n\t\t\tassertTrue (provider.ttl(keyToExpire) > 0, \"key to expire ttl is less than zero\");\n\t\t\t\n\t\t\t// NOTE: IT SIMPLY WON'T WORK WITHOUT GIVING REDIS A CHANCE\n\t\t\t// could be network latency, or whatever, but the expire command is NOT\n\t\t\t// that precise\n\t\t\t\n\t\t\tThread.sleep(500);\n\t\t\tassertTrue (provider.exists(keyToExpire));\n\t\t\t\n\t\t\tThread.sleep(this.expire_wait_millisecs);\n\t\t\tassertFalse (provider.exists(keyToExpire));\n\t\t\t// REVU-01202015: above exists for the expired key passes test\n\t\t\t// but the ttl on same (below) consistently fails. commenting out for now\n\t\t\t// so users do not skip tests in order to build the jars.\n//\t\t\tassertTrue (provider.ttl(keyToExpire) == -1, \"expired key ttl is not -1\");\n\t\t\tassertTrue (provider.ttl(keyToKeep) == -1, \"key to keep ttl is not -1\");\n\t\t\t\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) {\n\t\t\tfail(cmd + \" with password: \" + password, e);\n\t\t}\n\t\tcatch (InterruptedException e) {\n\t\t\tfail (cmd + \"thread was interrupted and test did not conclude\" + e.getLocalizedMessage());\n\t\t}\n\t}\n\n\t@Test\n\tpublic void testExpireat() {\n\t\tcmd = Command.EXPIREAT.code;\n\t\tLog.log(\"TEST: %s command(s)\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tassertTrue(provider.dbsize() == 0);\n\t\t\t\n\t\t\tString keyToExpire = \"expire-me\";\n\t\t\tprovider.set(keyToExpire, dataList.get(0));\n\t\t\tassertTrue (provider.exists(keyToExpire));\n\t\t\t\n\t\t\tLog.log(\"TEST: %s with expire time 1000 msecs in future\", Command.EXPIREAT);\n\t\t\tassertTrue(provider.expireat(keyToExpire, System.currentTimeMillis() + 2000), \"expireat for existing key should be true\");\n      assertTrue (provider.exists(keyToExpire));\n\t\t\tassertTrue(!provider.expireat(\"no-such-key\", System.currentTimeMillis() + 500), \"expireat for non-existant key should be false\");\n\t\t\t\n\t\t\t// NOTE: IT SIMPLY WON'T WORK WITHOUT GIVING REDIS A CHANCE\n\t\t\t// could be network latency, or whatever, but the expire command is NOT\n\t\t\t// that precise, so we need to wait a bit longer\n\t\t\tThread.sleep(5000);\n\t\t\tassertTrue (!provider.exists(keyToExpire), \"key should have expired by now\");\n\t\t} \n\t\tcatch (RedisException e) {\n\t\t\tfail(cmd + \" with password: \" + password, e);\n\t\t}\n\t\tcatch (InterruptedException e) {\n\t\t\tfail (cmd + \"thread was interrupted and test did not conclude\" + e.getLocalizedMessage());\n\t\t}\n\t}\n\n\n// CANT test this without risking hosing the user's DBs\n// TODO: use a flag\n//\t/**\n//\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#flushall()}.\n//\t */\n//\t@Test\n//\tpublic void testFlushall() {\n//\t\tfail(\"Not yet implemented\");\n//\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#flushdb()}.\n\t */\n\t@Test\n\tpublic void testSetAndFlushdbAndExistsAndKeys() {\n\t\tcmd = \n\t\t\tCommand.FLUSHDB.code + \" | \" +\n\t\t\tCommand.SET.code + \" | \" +\n\t\t\tCommand.EXISTS.code + \" | \" +\n\t\t\tCommand.FLUSHDB.code + \" | \" +\n\t\t\tCommand.KEYS.code;\n\t\t\t\n\t\tLog.log(\"TEST: %s commands\", cmd);\n\t\ttry {\n\t\t\tkey = \"woof\";\n\t\t\tprovider.flushdb();\n\t\t\tprovider.set(key, \"meow\");\n\t\t\tassertTrue (provider.exists(key));\n\t\t\tprovider.flushdb();\n\t\t\tassertTrue(provider.keys().size()==0);\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rename(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testRename() {\n\t\tcmd = Command.RENAME.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString newkey = null;\n\t\t\tbyte[] value = dataList.get(0);\n\t\t\tkey = getRandomAsciiString (random.nextInt(24)+2);\n\t\t\tnewkey = getRandomAsciiString (random.nextInt(24)+2);\n\t\t\t\n\t\t\tprovider.set (key, value);\n\t\t\tassertEquals(value, provider.get(key));\n\t\t\tprovider.rename (key, newkey);\n\t\t\tassertEquals(value, provider.get(newkey));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t\n\t@Test\n\tpublic void testBitCommands() {\n\t\tcmd = Command.SETBIT.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tkey = getRandomAsciiString (random.nextInt(24)+2);\n\t\t\tprovider.del(key);\n\t\t\tprovider.setbit(key, 0, true);\n\t\t\tprovider.setbit(key, 32, true);\n\t\t\tassertEquals(true, provider.getbit(key,0));\n\t\t\tassertEquals(true, provider.getbit(key,32));\n\t\t\tassertEquals(false, provider.getbit(key,64));\n\t\t\tassertEquals(false, provider.getbit(key,1));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#renamenx(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testRenamenx() {\n\t\tcmd = Command.RENAMENX.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tprovider.set (keys.get(0), dataList.get(0));\n\t\t\tassertEquals(dataList.get(0), provider.get(keys.get(0)));\n\n\t\t\t// should work\n\t\t\tassertTrue(provider.renamenx (keys.get(0), keys.get(2)));\n\t\t\tassertEquals(dataList.get(0), provider.get(keys.get(2)));\n\t\t\t\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// set key1\n\t\t\tprovider.set (keys.get(1), dataList.get(1));\n\t\t\tassertEquals(dataList.get(1), provider.get(keys.get(1)));\n\t\t\t\n\t\t\t// set key2\n\t\t\tprovider.set (keys.get(2), dataList.get(2));\n\t\t\tassertEquals(dataList.get(2), provider.get(keys.get(2)));\n\t\t\t\n\t\t\t// rename key1 to key 2 \n\t\t\t// should not\n\t\t\tassertFalse(provider.renamenx (keys.get(1), keys.get(2)));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#save()}.\n\t */\n\t@Test\n\tpublic void testSaveAndLastSave() {\n\t\tcmd = Command.SAVE.code + \" | \" + Command.LASTSAVE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.save();\n\t\t\tlong when = provider.lastsave();\n\t\t\tThread.sleep (this.expire_wait_millisecs);\n\t\t\tprovider.save();\n\t\t\tlong when2 = provider.lastsave();\n\t\t\tassertTrue(when != when2);\n\t\t} \n\t\tcatch (RedisException e) { \n\t\t\tif(e.getLocalizedMessage().indexOf(\"background save in progress\") != -1){\n\t\t\t\tLog.problem (\"** NOTE ** Redis background save in progress prevented effective test of SAVE and LASTSAVE.\");\n\t\t\t}\n\t\t\telse \n\t\t\t\tfail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); \n\t\t}\n\t\tcatch (InterruptedException e) {\n\t\t\tfail (\"thread was interrupted and test did not conclude\" + e.getLocalizedMessage());\n\t\t}\n\t}\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#bgsave()}.\n\t */\n\t@Test\n\tpublic void testBgsave() {\n\t\tcmd = Command.BGSAVE.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n//\t\tfinal long start = System.nanoTime();\n//\t\tfinal long until = start + TimeUnit.SECONDS.toNanos(10);\n//\t\twhile(System.nanoTime() < until){\n\t\t\ttry {\n//\t\t\t\tif(!didflush) {\n\t\t\t\t\tprovider.flushdb();\n//\t\t\t\t\tdidflush = true;\n//\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// TODO: what's a meaningful test for this besides asserting command works?\n\t\t\t\tprovider.bgsave();\n\t\t\t} \n\t\t\tcatch (RedisException e) { \n\t\t\t\t/* can fail due if server is in middle of AOF */\n\t\t\t\tif(e.getMessage().contains(\"ERR Can't BGSAVE\")){\n\t\t\t\t\ttry {\n\t\t\t\t\t\tLog.log(\"NOTE: Ignoring error <<%s>> finish with AOF during test for %s\", e.getMessage(), cmd);\n\t\t\t\t\t\tThread.sleep(1000L);\n\t\t\t\t\t\tLog.log(\".. let's try again\");\n\t\t\t\t\t}catch (InterruptedException ie) {\n\t\t\t\t\t\tLog.log(\"sleep interrupted while waiting for Redis server to finish with AOF during test for %s\", cmd);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e);\n\t\t\t\t}\n\t\t\t}\n//\t\t}\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#bgrewriteaof()}.\n\t */\n\t@Test\n\tpublic void testBgrewriteaofe() {\n\t\tcmd = Command.BGREWRITEAOF.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// TODO: what's a meaningful test for this besides asserting command works?\n\t\t\tString msg = provider.bgrewriteaof();\n\t\t\tassertTrue(msg != null, \"expecting a non null response message - msg details may change so will not be checked here\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testSetStringByteArray() {\n\t\tcmd = Command.SET.code + \" | \" + Command.SETNX.code + \" byte[] | \" + Command.GET;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.set(keys.get(keys.size()-1), emptyBytes);\n\t\t\tassertEquals(provider.get(keys.get(keys.size()-1)), emptyBytes, \"set and get results for empty byte[]\");\n\t\t\t\n\t\t\tprovider.set(keys.get(0), dataList.get(0));\n\t\t\tassertEquals(dataList.get(0), provider.get(keys.get(0)), \"data and get results\");\n\t\t\t\n\t\t\tassertTrue(provider.setnx(keys.get(1), dataList.get(1)), \"set key\");\n\t\t\tassertNotNull(provider.get(keys.get(1)));\n\t\t\tassertFalse(provider.setnx(keys.get(1), dataList.get(2)), \"key was already set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#append(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testAppendStringByteArray() {\n\t\tcmd = Command.SET.code + \" | \" + Command.APPEND.code + \" byte[] | \" + Command.GET;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// append to a non-existent key\n\t\t\t// as of Redis 1.3.7 it behaves just like set but returns value len instead of status\n\t\t\tString key1 = keys.get(0);\n\t\t\tlong key1len = 0;\n\t\t\tkey1len = provider.append(key1, emptyBytes);\n\t\t\tassertEquals(key1len, 0, \"append of emtpy bytes to new key should be zero\");\n\t\t\tassertEquals(provider.get(key1), emptyBytes, \"get results after append to new key for empty byte[]\");\n\t\t\t\n\t\t\tlong len = 0;\n\t\t\tlen = provider.append(key1, dataList.get(0));\n\t\t\tassertEquals(len+key1len, dataList.get(0).length, \"append results\");\n\t\t\tassertEquals(provider.get(key1), dataList.get(0), \"get results after append\");\n\t\t\tkey1len += len;\n\t\t\t\n\t\t\tlen = provider.append(key1, dataList.get(1));\n\t\t\tassertEquals(len, dataList.get(0).length + dataList.get(1).length, \"append results\");\n\t\t\t\n\t\t\tbyte[] appendedBytes = new byte[dataList.get(0).length + dataList.get(1).length];\n\t\t\tSystem.arraycopy(dataList.get(0), 0, appendedBytes, 0, dataList.get(0).length);\n\t\t\tSystem.arraycopy(dataList.get(1), 0, appendedBytes, dataList.get(0).length, dataList.get(1).length);\n\t\t\tassertEquals(provider.get(key1), appendedBytes, \"get results after 2nd append\");\n\t\t\t\n\t\t\t// raise errors\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tString nonStringKey = keys.get(1);\n\t\t\t\tprovider.sadd(nonStringKey, dataList.get(0));\n\t\t\t\tprovider.append(nonStringKey, dataList.get(3));\n\t\t\t}\n\t\t\tcatch(RedisException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting RedisException for append to a non-string key\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#append(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testAppendStringString() {\n\t\tcmd = Command.SET.code + \" | \" + Command.APPEND.code + \" String | \" + Command.GET;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// append to a non-existent key\n\t\t\t// as of Redis 1.3.7 it behaves just like set but returns value len instead of status\n\t\t\tString key1 = keys.get(0);\n\t\t\tlong key1len = 0;\n\t\t\tlong len = 0;\n\t\t\t\n\t\t\t// append empty string to non-existent key\n\t\t\tkey1len = provider.append(key1, emptyString);\n\t\t\tassertEquals(key1len, 0, \"append of emtpy string to new key should be zero\");\n\t\t\tassertEquals(DefaultCodec.toStr(provider.get(key1)), emptyString, \"get results after append to new key for empty string\");\n\t\t\t\n\t\t\t// append a string\n\t\t\tlen = provider.append(key1, stringList.get(0));\n\t\t\tassertEquals(len+key1len, stringList.get(0).length(), \"append results\");\n\t\t\tassertEquals(DefaultCodec.toStr(provider.get(key1)), stringList.get(0), \"get results after append\");\n\t\t\tkey1len += len;\n\t\t\t\n\t\t\t// append a string again\n\t\t\tlen = provider.append(key1, stringList.get(1));\n\t\t\tassertEquals(len, stringList.get(0).length() + stringList.get(1).length(), \"append results\");\n\t\t\tStringBuffer appendedString = new StringBuffer();\n\t\t\tappendedString.append(stringList.get(0));\n\t\t\tappendedString.append(stringList.get(1));\n\t\t\tassertEquals(DefaultCodec.toStr(provider.get(key1)), appendedString.toString(), \"get results after 2nd append\");\n\t\t\t\n\t\t\t// raise RedisException\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tString nonStringKey = keys.get(1);\n\t\t\t\tprovider.sadd(nonStringKey, stringList.get(0));\n\t\t\t\tprovider.append(nonStringKey, stringList.get(3));\n\t\t\t}\n\t\t\tcatch(RedisException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting RedisException for append to a non-string key\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testSetStringString() {\n\t\tcmd = Command.SET.code + \" | \" + Command.SETNX.code + \" String | \" + Command.GET;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.set(keys.get(keys.size()-1), emptyString);\n\t\t\tassertEquals(toStr(provider.get(keys.get(keys.size()-1))), emptyString, \"set and get results for empty String\");\n\t\t\t\n\t\t\tprovider.set(keys.get(0), stringList.get(0));\n\t\t\tassertEquals(stringList.get(0), toStr(provider.get(keys.get(0))), \"string and get results\");\n\t\t\t\n\t\t\tassertTrue(provider.setnx(keys.get(1), stringList.get(1)), \"set key\");\n\t\t\tassertNotNull(provider.get(keys.get(1)));\n\t\t\tassertFalse(provider.setnx(keys.get(1), stringList.get(2)), \"key was already set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, java.lang.Number)}.\n\t */\n\t@Test\n\tpublic void testSetStringNumber() {\n\t\tcmd = Command.SET.code + \" | \" + Command.SETNX.code + \" Long | \" + Command.GET;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.set(keys.get(0), longList.get(0));\n\t\t\tassertTrue(longList.get(0).equals(toLong(provider.get(keys.get(0)))), \"long and get results\");\n\t\t\t\n\t\t\tassertTrue(provider.setnx(keys.get(1), longList.get(1)), \"set key\");\n\t\t\tassertNotNull(provider.get(keys.get(1)));\n\t\t\tassertFalse(provider.setnx(keys.get(1), longList.get(2)), \"key was already set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testSetStringT() {\n\t\tcmd = Command.SET.code + \" | \" + Command.SETNX.code + \" Java Object | \" + Command.GET;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.set(keys.get(0), objectList.get(0));\n\t\t\tassertTrue(objectList.get(0).equals(decode(provider.get(keys.get(0)))), \"object and get results\");\n\t\t\t\n\t\t\tassertTrue(provider.setnx(keys.get(1), objectList.get(1)), \"set key\");\n\t\t\tassertNotNull(provider.get(keys.get(1)));\n\t\t\tassertFalse(provider.setnx(keys.get(1), objectList.get(2)), \"key was already set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t@Test\n\tpublic void testHsetHgetHexists() {\n\t\tcmd = Command.HSET.code + \" | \" + Command.HGET + \" | \" + Command.HEXISTS;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(1), dataList.get(0)), \"hset using byte[] value\");\n\t\t\tassertTrue( provider.hexists(keys.get(0), keys.get(1)), \"field should exist\");\n\t\t\tassertTrue( !provider.hexists(keys.get(0), keys.get(2)), \"field should NOT exist\");\n\t\t\tassertTrue( !provider.hset(keys.get(0), keys.get(1), dataList.get(0)), \"repeated hset using byte[] value should return false\");\n\t\t\t\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(2), stringList.get(0)), \"hset using String value\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(3), 222), \"hset using Number value\");\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(4), objectList.get(0)), \"hset using Object value\");\n\t\t\t\n\t\t\tassertEquals( provider.hlen(keys.get(0)), 4, \"hlen value\");\n\t\t\tassertEquals( provider.hlen(\"some-random-key\"), 0, \"hlen of non-existent hash should be zero\");\n\n\t\t\t\n\t\t\tassertEquals (provider.hget(keys.get(0), keys.get(1)), dataList.get(0), \"hget of field with byte[] value\");\n\t\t\tassertEquals (DefaultCodec.toStr(provider.hget(keys.get(0), keys.get(2))), stringList.get(0), \"hget of field with String value\");\n\t\t\tassertEquals (DefaultCodec.toLong(provider.hget(keys.get(0), keys.get(3))).longValue(), 222, \"hget of field with Number value\");\n\t\t\tTestBean objval = DefaultCodec.decode(provider.hget(keys.get(0), keys.get(4)));\n\t\t\tassertEquals (objval.getName(), objectList.get(0).getName(), \"hget of field with Object value\");\n\t\t\t\n\t\t\tassertTrue( provider.hdel(keys.get(0), keys.get(1)), \"hdel of existing field should be true\");\n\t\t\tassertTrue( !provider.hdel(keys.get(0), keys.get(1)), \"hdel of non-existing field should be false\");\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#hkeys(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testHkeys() {\n\t\tcmd = Command.HKEYS.code + \" | \" + Command.HSET + \" | \" + Command.HDEL;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(1), dataList.get(0)), \"hset using byte[] value\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(2), stringList.get(0)), \"hset using String value\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(3), 222), \"hset using Number value\");\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(4), objectList.get(0)), \"hset using Object value\");\n\t\t\t\n\t\t\tList<byte[]> hkeys = provider.hkeys(keys.get(0));\n\t\t\tassertEquals( hkeys.size(), 4, \"keys list length\");\n\t\t\t\n\t\t\tfor(byte[] key : hkeys){\n\t\t\t\tassertTrue(provider.hdel(keys.get(0), key), \"deleting existing field should be true\");\n\t\t\t}\n\t\t\tassertEquals(provider.hlen(keys.get(0)), 0, \"hash should empty\");\n\t\t\tList<byte[]> hkeys2 = provider.hkeys(keys.get(0));\n\t\t\tassertEquals(hkeys2, Collections.EMPTY_LIST, \"keys list should be empty\");\n\t\t\t\n\t\t\tList<byte[]> hkeys3 = provider.hkeys(\"no-such-hash\");\n\t\t\tassertEquals(hkeys3, Collections.EMPTY_LIST, \"keys list of non-existent hash should be empty.\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#hvals(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testHvals() {\n\t\tcmd = Command.HVALS.code + \" | \" + Command.HSET + \" | \" + Command.HDEL;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(1), dataList.get(0)), \"hset using byte[] value\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(2), stringList.get(0)), \"hset using String value\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(3), 222), \"hset using Number value\");\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(4), objectList.get(0)), \"hset using Object value\");\n\t\t\t\n\t\t\tList<byte[]> hvals = provider.hvals(keys.get(0));\n\t\t\tassertEquals( hvals.size(), 4, \"value list length\");\n\t\t\t\n\t\t\tList<byte[]> hkeys = provider.hkeys(keys.get(0));\n\t\t\tassertEquals( hkeys.size(), 4, \"keys list length\");\n\t\t\t\n\t\t\tfor(byte[] key : hkeys){\n\t\t\t\tassertTrue(provider.hdel(keys.get(0), key), \"deleting existing field should be true\");\n\t\t\t}\n\t\t\tassertEquals(provider.hlen(keys.get(0)), 0, \"hash should empty\");\n\t\t\tList<byte[]> hvals2 = provider.hvals(keys.get(0));\n\t\t\tassertEquals(hvals2, Collections.EMPTY_LIST, \"keys list should be empty\");\n\t\t\t\n\t\t\tList<byte[]> hvals3 = provider.hvals(\"no-such-hash\");\n\t\t\tassertEquals(hvals3, Collections.EMPTY_LIST, \"values list of non-existent hash should be empty.\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#hvals(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testHgetall() {\n\t\tcmd = Command.HGETALL.code + \" | \" + Command.HSET + \" | \" + Command.HDEL;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(1), dataList.get(0)), \"hset using byte[] value\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(2), stringList.get(0)), \"hset using String value\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(3), 222), \"hset using Number value\");\n\t\t\tobjectList.get(0).setName(\"Hash Stash\");\n\t\t\tassertTrue( provider.hset(keys.get(0), keys.get(4), objectList.get(0)), \"hset using Object value\");\n\t\t\t\n\t\t\tMap<byte[], byte[]> hbinmap = provider.hgetall(keys.get(0));\n\t\t\tassertEquals( hbinmap.size(), 4, \"hash map length\");\n\t\t\t\n\t\t\tList<byte[]> hbinkeys = provider.hkeys(keys.get(0));\n\t\t\tassertEquals( hbinkeys.size(), 4, \"keys list length\");\n\t\t\tMap<String, byte[]> hmap = DefaultCodec.toDataDictionary(hbinmap);\n\t\t\tint i = 0;\n\t\t\tfor(String key : DefaultCodec.toStr(hbinkeys)) {\n\t\t\t\tassertTrue(hmap.get(key) != null, String.format(\"key %d should exists in map and have a corresponding non null value\", i++));\n\t\t\t}\n\t\t\t\n\t\t\tassertEquals(hmap.get(keys.get(1)), dataList.get(0), \"byte[] value mapping should correspond to prior HSET\");\n\t\t\tassertEquals(DefaultCodec.toStr(hmap.get(keys.get(2))), stringList.get(0), \"String value mapping should correspond to prior HSET\");\n\t\t\tassertEquals(DefaultCodec.toLong(hmap.get(keys.get(3))).longValue(), 222, \"Number value mapping should correspond to prior HSET\");\n\t\t\tassertEquals(DefaultCodec.decode(hmap.get(keys.get(4))), objectList.get(0), \"Object value mapping should correspond to prior HSET\");\n\t\t\t\n\t\t\tfor(byte[] key : hbinkeys)\n\t\t\t\tassertTrue(provider.hdel(keys.get(0), key), \"deletion of existing key in hash should be true\");\n\t\t\t\n\t\t\tMap<byte[], byte[]> hmap2 = provider.hgetall(keys.get(0));\n\t\t\tassertEquals(hmap2, Collections.EMPTY_MAP, \"hash map should be empty\");\n\t\t\t\n\t\t\tMap<byte[], byte[]> hmap3 = provider.hgetall(\"no-such-hash\");\n\t\t\tassertEquals(hmap3, Collections.EMPTY_MAP, \"hgetall for non existent hash should be empty\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testGetSetStringByteArray() {\n\t\tcmd = Command.SET.code + \" | \" + Command.GETSET.code + \" byte[] \";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.set(keys.get(0), dataList.get(0));\n\t\t\tassertEquals(dataList.get(0), provider.get(keys.get(0)), \"data and get results\");\n\t\t\t\n\t\t\tassertEquals (provider.getset(keys.get(0), dataList.get(1)), dataList.get(0), \"getset key\");\n\t\t\t\n\t\t\tassertEquals (provider.get(keys.get(1)), null, \"non existent key should be null\");\n\t\t\tassertEquals (provider.getset(keys.get(1), dataList.get(1)), null, \"getset on null key should be null\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, java.lang.String)}.\n\t */\n//\t@Test\n//\tpublic void testGetSetStringString() {\n//\t\ttest = Command.SET.code + \" | \" + Command.GETSET.code + \" String \";\n//\t\tLog.log(\"TEST: %s command\", test);\n//\t\ttry {\n//\t\t\tjredis.flushdb();\n//\t\t\t\n//\t\t\tjredis.set(keys.get(0), stringList.get(0));\n//\t\t\tassertEquals(stringList.get(0), toStr(jredis.get(keys.get(0))), \"string and get results\");\n//\t\t\t\n//\t\t\tassertTrue(jredis.setnx(keys.get(1), stringList.get(1)), \"set key\");\n//\t\t\tassertNotNull(jredis.get(keys.get(1)));\n//\t\t\tassertFalse(jredis.setnx(keys.get(1), stringList.get(2)), \"key was already set\");\n//\t\t} \n//\t\tcatch (RedisException e) { fail(test + \" ERROR => \" + e.getLocalizedMessage(), e); }\n//\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, java.lang.Number)}.\n\t */\n//\t@Test\n//\tpublic void testGetSetStringNumber() {\n//\t\ttest = Command.SET.code + \" | \" + Command.GETSET.code + \" Number \";\n//\t\tLog.log(\"TEST: %s command\", test);\n//\t\ttry {\n//\t\t\tjredis.flushdb();\n//\t\t\t\n//\t\t\tjredis.set(keys.get(0), longList.get(0));\n//\t\t\tassertTrue(longList.get(0).equals(toLong(jredis.get(keys.get(0)))), \"long and get results\");\n//\t\t\t\n//\t\t\tassertTrue(jredis.setnx(keys.get(1), longList.get(1)), \"set key\");\n//\t\t\tassertNotNull(jredis.get(keys.get(1)));\n//\t\t\tassertFalse(jredis.setnx(keys.get(1), longList.get(2)), \"key was already set\");\n//\t\t} \n//\t\tcatch (RedisException e) { fail(test + \" ERROR => \" + e.getLocalizedMessage(), e); }\n//\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#set(java.lang.String, java.io.Serializable)}.\n\t */\n//\t@Test\n//\tpublic void testGetSetStringT() {\n//\t\ttest = Command.SET.code + \" | \" + Command.GETSET.code + \" Java Object \";\n//\t\tLog.log(\"TEST: %s command\", test);\n//\t\ttry {\n//\t\t\tjredis.flushdb();\n//\t\t\t\n//\t\t\tjredis.set(keys.get(0), objectList.get(0));\n//\t\t\tassertTrue(objectList.get(0).equals(decode(jredis.get(keys.get(0)))), \"object and get results\");\n//\t\t\t\n//\t\t\tassertTrue(jredis.setnx(keys.get(1), objectList.get(1)), \"set key\");\n//\t\t\tassertNotNull(jredis.get(keys.get(1)));\n//\t\t\tassertFalse(jredis.setnx(keys.get(1), objectList.get(2)), \"key was already set\");\n//\t\t} \n//\t\tcatch (RedisException e) { fail(test + \" ERROR => \" + e.getLocalizedMessage(), e); }\n//\t}\n\n\t\n\t\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#incr(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testIncrAndDecr() {\n\t\tcmd = Command.INCR.code + \" | \" + Command.DECR.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tlong cntr = 0;\n\t\t\tString cntr_key = keys.get(0);\n\t\t\t\n\t\t\tfor(int i = 1; i<MEDIUM_CNT; i++){\n\t\t\t\tcntr = provider.incr(cntr_key);\n\t\t\t\tassertEquals(i, cntr);\n\t\t\t}\n\t\t\t\n\t\t\tfor(long i=cntr-1; i>=0; i--){\n\t\t\t\tcntr = provider.decr(cntr_key);\n\t\t\t\tassertEquals(i, cntr);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#incrby(java.lang.String, int)}.\n\t */\n\t@Test\n\tpublic void testIncrbyAndDecrby() {\n\t\tcmd = Command.INCRBY.code + \" |\" + Command.DECRBY.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tlong cntr = 0;\n\t\t\tString cntr_key = keys.get(0);\n\n\t\t\tfor(long i = 1; i<MEDIUM_CNT; i++){\n\t\t\t\tcntr = provider.incrby(cntr_key, 10);\n\t\t\t\tassertEquals(i*10, cntr);\n\t\t\t}\n\t\t\t\n\t\t\tprovider.set(cntr_key, 0);\n\t\t\tassertTrue(0 == toLong(provider.get(cntr_key)));\n\t\t\tfor(long i = 1; i<MEDIUM_CNT; i++){\n\t\t\t\tcntr = provider.decrby(cntr_key, 10);\n\t\t\t\tassertEquals(i*-10, cntr);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#del(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testDel() {\n\t\tcmd = Command.DEL.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString key = this.keys.get(0);\n\t\t\tprovider.set (key, dataList.get(0));\n\t\t\tassertTrue (provider.exists(key));\n\t\t\t\n\t\t\tlong delCnt;\n\t\t\tdelCnt = provider.del(key);\n\t\t\tassertFalse (provider.exists(key));\n\t\t\tassertEquals(delCnt, 1, \"one key was deleted\");\n\n\t\t\t// delete many keys\n\t\t\tprovider.flushdb();\n\t\t\tfor(int i=0; i<SMALL_CNT; i++) provider.set(stringList.get(i), dataList.get(i));\n\n\t\t\tString[] keysToDel = new String[SMALL_CNT];\n\t\t\tfor(int i=0; i<SMALL_CNT; i++) keysToDel[i] = stringList.get(i);\n\n\t\t\tdelCnt = provider.del(keysToDel);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++) assertFalse (provider.exists(stringList.get(i)), \"key should have been deleted\");\n\t\t\tassertEquals(delCnt, SMALL_CNT, \"SMALL_CNT keys were deleted\");\n\t\t\t\n\t\t\t// delete many keys but also spec one non existent keys - delete result should be less than key cnt\n\t\t\tprovider.flushdb();\n\t\t\tfor(int i=0; i<SMALL_CNT-1; i++) provider.set(stringList.get(i), dataList.get(i));\n\n\t\t\tkeysToDel = new String[SMALL_CNT];\n\t\t\tfor(int i=0; i<SMALL_CNT; i++) keysToDel[i] = stringList.get(i);\n\n\t\t\tdelCnt = provider.del(keysToDel);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++) assertFalse (provider.exists(stringList.get(i)), \"key should have been deleted\");\n\t\t\tassertEquals(delCnt, SMALL_CNT-1, \"SMALL_CNT-1 keys were actually deleted\");\n\t\t\t\n\t\t\t\n\t\t\t// edge cases\n\t\t\t// all should through exceptions\n\t\t\tboolean didRaiseEx;\n\t\t\tdidRaiseEx = false;\n\t\t\ttry {\n\t\t\t\tString[] keys = null;\n\t\t\t\tprovider.del(keys);\n\t\t\t}\n\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\tdidRaiseEx = false;\n\t\t\ttry {\n\t\t\t\tString[] keys = new String[0];\n\t\t\t\tprovider.del(keys);\n\t\t\t}\n\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\tdidRaiseEx = false;\n\t\t\ttry {\n\t\t\t\tString[] keys = new String[3];\n\t\t\t\tkeys[0] = stringList.get(0);\n\t\t\t\tkeys[1] = null;\n\t\t\t\tkeys[2] = stringList.get(2);\n\t\t\t\tprovider.del(keys);\n\t\t\t}\n\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#mget(java.lang.String, java.lang.String[])}.\n\t */\n\t@Test\n\tpublic void testMget() {\n\t\tcmd = Command.MGET.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.set (keys.get(i), dataList.get(i));\n\t\t\t}\n\t\t\t\n\t\t\tList<byte[]>  values = null;\n\t\t\tvalues = provider.mget(keys.get(0)); \n\t\t\tassertEquals(values.size(), 1, \"one value expected\");\n\t\t\tfor(int i=0; i<1; i++)\n\t\t\t\tassertEquals(values.get(i), dataList.get(i));\n\t\t\t\n\t\t\tvalues = provider.mget(keys.get(0), keys.get(1)); \n\t\t\tassertEquals(values.size(), 2, \"2 values expected\");\n\t\t\tfor(int i=0; i<2; i++)\n\t\t\t\tassertEquals(values.get(i), dataList.get(i));\n\t\t\t\n\t\t\tvalues = provider.mget(keys.get(0), keys.get(1), keys.get(2)); \n\t\t\tassertEquals(values.size(), 3, \"3 values expected\");\n\t\t\tfor(int i=0; i<3; i++)\n\t\t\t\tassertEquals(values.get(i), dataList.get(i));\n\t\t\t\n\t\t\tvalues = provider.mget(\"foo\", \"bar\", \"paz\"); \n\t\t\tassertEquals(values.size(), 3, \"3 values expected\");\n\t\t\tfor(int i=0; i<3; i++)\n\t\t\t\tassertEquals(values.get(i), null, \"nonexistent key value in list should be null\");\n\t\t\t\n\t\t\t// edge cases\n\t\t\t// all should through exceptions\n\t\t\tboolean didRaiseEx;\n\t\t\tdidRaiseEx = false;\n\t\t\ttry {\n\t\t\t\tString[] keys = null;\n\t\t\t\tprovider.mget(keys);\n\t\t\t}\n\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\tdidRaiseEx = false;\n\t\t\ttry {\n\t\t\t\tString[] keys = new String[0];\n\t\t\t\tprovider.mget(keys);\n\t\t\t}\n\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\n\t\t\tdidRaiseEx = false;\n\t\t\ttry {\n\t\t\t\tString[] keys = new String[3];\n\t\t\t\tkeys[0] = stringList.get(0);\n\t\t\t\tkeys[1] = null;\n\t\t\t\tkeys[2] = stringList.get(2);\n\t\t\t\tprovider.mget(keys);\n\t\t\t}\n\t\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n\t\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n\t\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t\n\t/**************** LIST COMMANDS ******************************/\n\n\t@Test\n\tpublic void testListPushWithSparseList() {\n\t\tcmd = Command.RPUSH.code + \" byte[] | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, sparseList.get(i));\n\t\t\t\n\t\t\tassertEquals(provider.llen(listkey), SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertEquals (sparseList.get(i), range.get(i), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t\t\n\t\t\tprovider.flushdb();\n\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lpush(listkey, sparseList.get(i));\n\t\t\t\n\t\t\tassertEquals(provider.llen(listkey), SMALL_CNT, \"LLEN after LPUSH is wrong\");\n\t\t\t\n\t\t\trange = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after LPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertEquals (sparseList.get(i), range.get(r), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testRpushStringByteArray() {\n\t\tcmd = Command.RPUSH.code + \" byte[] | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tbyte[] nil = null;\n\t\t\t\tprovider.rpush(\"foo\", nil);\n\t\t\t}\n\t\t\tcatch(IllegalArgumentException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting exception for null value to RPUSH\");\n\t\t\t\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.rpush(listkey, dataList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertEquals (dataList.get(i), range.get(i), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lpush(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testLpushStringByteArray() {\n\t\tcmd = Command.LPUSH.code + \" byte[] | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tbyte[] nil = null;\n\t\t\t\tprovider.rpush(\"foo\", nil);\n\t\t\t}\n\t\t\tcatch(IllegalArgumentException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting exception for null value to RPUSH\");\n\t\t\t\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.lpush(listkey, dataList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after LPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after LPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertEquals (dataList.get(i), range.get(r), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t@Test\n\tpublic void testLpoppushStringString() {\n\t\tcmd = Command.RPOPLPUSH.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.lpush(listkey, stringList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after LPUSH is wrong\");\n\t\t\t\n\t\t\tString popped = null;\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tpopped = toStr(provider.rpoplpush(listkey, listkey));\n\t\t\t\tassertEquals(popped, stringList.get(i), \"RPOPLPUSH didn't work as expected\");\n\t\t\t}\n\t\t\t\n\t\t\t// use LLEN: size should still be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPOPLPUSH sequence is wrong\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rpush(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testRpushStringString() {\n\t\tcmd = Command.RPUSH.code + \" String | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.rpush(listkey, stringList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertEquals (stringList.get(i), toStr(range.get(i)), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t\tList<String>  strRange = toStr(range);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertEquals (stringList.get(i), strRange.get(i), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lpush(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testLpushStringString() {\n\t\tcmd = Command.LPUSH.code + \" String | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.lpush(listkey, stringList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertEquals (stringList.get(i), toStr(range.get(r)), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t\tList<String>  strRange = toStr(range);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertEquals (stringList.get(i), strRange.get(r), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rpush(java.lang.String, java.lang.Number)}.\n\t */\n\t@Test\n\tpublic void testRpushStringNumber() {\n\t\tcmd = Command.RPUSH.code + \" Number | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.rpush(listkey, this.longList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertTrue (longList.get(i).equals(toLong(range.get(i))), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t\tList<Long>  longRange = toLong(range);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertEquals (longList.get(i), longRange.get(i), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lpush(java.lang.String, java.lang.Number)}.\n\t */\n\t@Test\n\tpublic void testLpushStringNumber() {\n\t\tcmd = Command.LPUSH.code + \" Number | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.lpush(listkey, this.longList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertTrue (longList.get(i).equals(toLong(range.get(r))), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t\tList<Long>  longRange = toLong(range);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertEquals (longList.get(i), longRange.get(r), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rpush(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testRpushStringT() {\n\t\tcmd = Command.RPUSH.code + \" Java Object | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.rpush(listkey, this.objectList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertTrue (objectList.get(i).equals(decode(range.get(i))), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t\tList<TestBean>  objRange = decode(range);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tassertEquals (objectList.get(i), objRange.get(i), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lpush(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testLpushStringT() {\n\t\tcmd = Command.LPUSH.code + \" Java Object | \" + Command.LLEN + \" | \" + Command.LRANGE;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tprovider.lpush(listkey, this.objectList.get(i));\n\t\t\t}\n\t\t\t// use LLEN: size should be small count\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// use LRANGE 0 cnt: equal size and data should be same in order\n\t\t\tList<byte[]>  range = provider.lrange(listkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size()==SMALL_CNT, \"range size after RPUSH is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertTrue (objectList.get(i).equals(decode(range.get(r))), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t\tList<TestBean>  objRange = decode(range);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++){\n\t\t\t\tint r = SMALL_CNT - i - 1;\n\t\t\t\tassertEquals (objectList.get(i), objRange.get(r), \"range and reference list differ at i: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) {\n\t\t\tfail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e);\n\t\t}\n\t}\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#ltrim(java.lang.String, long, long)}.\n\t */\n\t@Test\n\tpublic void testLtrim() {\n\t\tcmd = Command.LTRIM.code + \" | \" + Command.LLEN.code + \" | \" + Command.LRANGE.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\t\n\t\t\t// sanity check\n\t\t\tlong listcnt = provider.llen(listkey);\n\t\t\tassertEquals (listcnt, SMALL_CNT, \"list length should be SMALL_CNT\");\n\t\t\t\n\t\t\tprovider.ltrim(listkey, 0,listcnt-1);\t// trim nothing\n\t\t\tassertEquals(provider.llen(listkey), listcnt, \"trim from end to end - no delta expected\");\n\t\t\t\n\t\t\tprovider.ltrim(listkey, 1, listcnt-1); \t// remove the head\n\t\t\tassertEquals(provider.llen(listkey), listcnt-1, \"trim head - len should be --1 expected\");\n\t\t\t\n\t\t\tlistcnt = provider.llen(listkey);\n\t\t\tassertEquals(listcnt, SMALL_CNT - 1, \"list length should be SMALL_CNT - 1\");\n\t\t\tfor(int i=0; i<SMALL_CNT-1; i++)\n\t\t\t\tassertEquals(provider.lindex(listkey, i), dataList.get(i+1), \"list items should match ref data shifted by 1 after removing head\");\n\t\t\t\n\t\t\tprovider.ltrim(listkey, -2, -1);\n\t\t\tassertEquals(provider.llen(listkey), 2, \"list length should be 2\");\n\t\t\t\n\t\t\tprovider.ltrim(listkey, 0, 0);\n\t\t\tassertEquals(provider.llen(listkey), 1, \"list length should be 1\");\n\n\t\t\tbyte[] lastItem = provider.lpop(listkey);\n\t\t\tassertNotNull(lastItem, \"last item should not have been null\");\n\t\t\tassertEquals(provider.llen(listkey), 0, \"expecting empty list after trims and pop\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lindex(java.lang.String, long)}.\n\t */\n\t@Test\n\tpublic void testLindex() {\n\t\tcmd = Command.LINDEX.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\t\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertEquals(provider.lindex(listkey, i), dataList.get(i), \"list items should match ref data\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lpop(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testLpop() {\n\t\tcmd = Command.LPOP.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\t\n\t\t\t// sanity check\n\t\t\tlong listcnt = provider.llen(listkey);\n\t\t\tassertEquals (listcnt, SMALL_CNT, \"list length should be SMALL_CNT\");\n\t\t\t\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertEquals(provider.lpop(listkey), dataList.get(i), \n\t\t\t\t\t\t\"nth popped head should be the same as nth dataitem, where n is \" + i);\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#rpop(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testRpop() {\n\t\tcmd = Command.RPOP.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a small list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\t\n\t\t\t// sanity check\n\t\t\tlong listcnt = provider.llen(listkey);\n\t\t\tassertEquals (listcnt, SMALL_CNT, \"list length should be SMALL_CNT\");\n\t\t\t\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertEquals(provider.rpop(listkey), dataList.get(i), \n\t\t\t\t\t\t\"nth popped tail should be the same as nth dataitem, where n is \" + i);\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lrange(java.lang.String, int, int)}.\n\t */\n\t@Test\n\tpublic void testLrange() {\n\t\tcmd = Command.LRANGE.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// prep a MEDIUM list\n\t\t\tString listkey = keys.get(0);\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i)); // use rpush (append) so ref list sequence order is preserved\n\t\t\t\n\t\t\t// sanity check\n\t\t\tlong listcnt = provider.llen(listkey);\n\t\t\tassertEquals (listcnt, MEDIUM_CNT, \"list length should be MEDIUM_CNT\");\n\n\t\t\tList<byte[]> items = provider.lrange(listkey, 0, SMALL_CNT-1);\n\t\t\tassertEquals (items.size(), SMALL_CNT, \"list range 0->SMALL_CNT length should be SMALL_CNT\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertEquals(items.get(i), dataList.get(i), \n\t\t\t\t\t\t\"nth items of range 0->CNT should be the same as nth dataitem, where n is \" + i);\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#substr(java.lang.String, int, int)}.\n\t */\n\t@Test\n\tpublic void testSubstr() {\n\t\tcmd = Command.SUBSTR.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString key = keys.get(0);\n\t\t\tbyte[] value = dataList.get(0);\n\t\t\tprovider.set(key, value);\n\t\t\t\n\t\t\tbyte[] substr = null;\n\t\t\tsubstr = provider.substr(key, 0, value.length);\n\t\t\tassertEquals(substr, value, \"full range substr should be equal to value\");\n\t\t\t\n\t\t\tfor(int i=0; i<value.length; i++){\n\t\t\t\tassertTrue(provider.substr(key, i, i).length == 1, \"checking size: using substr to iterate over value bytes @ idx \" + i);\n\t\t\t\tassertEquals(provider.substr(key, i, i)[0], value[i], \"checking value: using substr to iterate over value bytes @ idx \" + i);\n\t\t\t}\n\t\t\t\t\n\t\t\tsubstr = provider.substr(key, 0, -1);\n\t\t\tassertEquals(substr, value, \"full range substr should be equal to value\");\n\t\t\t\n\t\t\tsubstr = provider.substr(key, -1, 0);\n\t\t\tassertEquals(substr, new byte[0], \"substr with -1 from idx should be zero-length array\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lrem(java.lang.String, byte[], int)}.\n\t */\n\t@Test\n\tpublic void testLremStringByteArrayInt() {\n\t\tcmd = Command.LREM.code + \" byte[] | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==MEDIUM_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// everysingle one of these should work and remove just 1 element\n\t\t\tassertEquals(1, provider.lrem(listkey, dataList.get(0), 0));\n\t\t\tassertEquals(1, provider.lrem(listkey, dataList.get(1), -1));\n\t\t\tassertEquals(1, provider.lrem(listkey, dataList.get(2), 1));\n\t\t\tassertEquals(1, provider.lrem(listkey, dataList.get(3), 2));\n\t\t\tassertEquals(1, provider.lrem(listkey, dataList.get(4), -2));\n\t\t\t\n\t\t\t// everysingle one of these should work and remove NOTHING\n\t\t\tassertEquals(0, provider.lrem(listkey, dataList.get(0), 0));\n\t\t\tassertEquals(0, provider.lrem(listkey, dataList.get(1), -1));\n\t\t\tassertEquals(0, provider.lrem(listkey, dataList.get(2), 1));\n\t\t\tassertEquals(0, provider.lrem(listkey, dataList.get(3), 2));\n\t\t\tassertEquals(0, provider.lrem(listkey, dataList.get(4), -2));\n\t\t\t\n\t\t\t// now we'll test to see how it handles empty lists\n\t\t\tprovider.flushdb();\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lrem(listkey, dataList.get(i), 100);\n\t\t\tassertEquals(0, provider.llen(listkey), \"LLEN should be zero\");\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lrem(java.lang.String, java.lang.String, int)}.\n\t */\n\t@Test\n\tpublic void testLremStringStringInt() {\n\t\tcmd = Command.LREM.code + \" String | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, stringList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==MEDIUM_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// everysingle one of these should work and remove just 1 element\n\t\t\tassertEquals(1, provider.lrem(listkey, stringList.get(0), 0));\n\t\t\tassertEquals(1, provider.lrem(listkey, stringList.get(1), -1));\n\t\t\tassertEquals(1, provider.lrem(listkey, stringList.get(2), 1));\n\t\t\tassertEquals(1, provider.lrem(listkey, stringList.get(3), 2));\n\t\t\tassertEquals(1, provider.lrem(listkey, stringList.get(4), -2));\n\t\t\t\n\t\t\t// everysingle one of these should work and remove NOTHING\n\t\t\tassertEquals(0, provider.lrem(listkey, stringList.get(0), 0));\n\t\t\tassertEquals(0, provider.lrem(listkey, stringList.get(1), -1));\n\t\t\tassertEquals(0, provider.lrem(listkey, stringList.get(2), 1));\n\t\t\tassertEquals(0, provider.lrem(listkey, stringList.get(3), 2));\n\t\t\tassertEquals(0, provider.lrem(listkey, stringList.get(4), -2));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lrem(java.lang.String, java.lang.Number, int)}.\n\t */\n\t@Test\n\tpublic void testLremStringNumberInt() {\n\t\tcmd = Command.LREM.code + \" Number | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, longList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==MEDIUM_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// everysingle one of these should work and remove just 1 element\n\t\t\tassertEquals(1, provider.lrem(listkey, longList.get(0), 0));\n\t\t\tassertEquals(1, provider.lrem(listkey, longList.get(1), -1));\n\t\t\tassertEquals(1, provider.lrem(listkey, longList.get(2), 1));\n\t\t\tassertEquals(1, provider.lrem(listkey, longList.get(3), 2));\n\t\t\tassertEquals(1, provider.lrem(listkey, longList.get(4), -2));\n\t\t\t\n\t\t\t// everysingle one of these should work and remove NOTHING\n\t\t\tassertEquals(0, provider.lrem(listkey, longList.get(0), 0));\n\t\t\tassertEquals(0, provider.lrem(listkey, longList.get(1), -1));\n\t\t\tassertEquals(0, provider.lrem(listkey, longList.get(2), 1));\n\t\t\tassertEquals(0, provider.lrem(listkey, longList.get(3), 2));\n\t\t\tassertEquals(0, provider.lrem(listkey, longList.get(4), -2));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lrem(java.lang.String, java.io.Serializable, int)}.\n\t */\n\t@Test\n\tpublic void testLremStringTInt() {\n\t\tcmd = Command.LREM.code + \" Java Object | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, objectList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==MEDIUM_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// everysingle one of these should work and remove just 1 element\n\t\t\tassertEquals(1, provider.lrem(listkey, objectList.get(0), 0));\n\t\t\tassertEquals(1, provider.lrem(listkey, objectList.get(1), -1));\n\t\t\tassertEquals(1, provider.lrem(listkey, objectList.get(2), 1));\n\t\t\tassertEquals(1, provider.lrem(listkey, objectList.get(3), 2));\n\t\t\tassertEquals(1, provider.lrem(listkey, objectList.get(4), -2));\n\t\t\t\n\t\t\t// everysingle one of these should work and remove NOTHING\n\t\t\tassertEquals(0, provider.lrem(listkey, objectList.get(0), 0));\n\t\t\tassertEquals(0, provider.lrem(listkey, objectList.get(1), -1));\n\t\t\tassertEquals(0, provider.lrem(listkey, objectList.get(2), 1));\n\t\t\tassertEquals(0, provider.lrem(listkey, objectList.get(3), 2));\n\t\t\tassertEquals(0, provider.lrem(listkey, objectList.get(4), -2));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lset(java.lang.String, int, byte[])}.\n\t */\n\t@Test\n\tpublic void testLsetStringIntByteArray() {\n\t\tcmd = Command.LSET.code + \" byte[] | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, dataList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// now we'll change their values\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lset(listkey, i, dataList.get(SMALL_CNT+i));\n\t\t\t\n\t\t\tList<byte[]> range = null;\n\t\t\t\n\t\t\trange = provider.lrange(listkey, 0, LARGE_CNT);\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertEquals (dataList.get(SMALL_CNT+i), range.get(i), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// now we'll change their values using the negative index mode\n\t\t\tint lim = SMALL_CNT*-1;\n\t\t\tfor(int i=-1; i>lim; i--)\n\t\t\t\tprovider.lset(listkey, i, dataList.get(i*-1));\n\n\t\t\trange = provider.lrange(listkey, 0, LARGE_CNT);\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertEquals (dataList.get(SMALL_CNT-i), range.get(i), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// test edge conditions\n\t\t\t// out of range\n\t\t\tboolean expectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an out of range ERROR for LSET here ..\");\n\t\t\t\tprovider.lset(listkey, SMALL_CNT, dataList.get(0)); \n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"out of range LSET index should have raised an exception but did not\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lset(java.lang.String, int, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testLsetStringIntString() {\n\t\tcmd = Command.LSET.code + \" String | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, stringList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// now we'll change their values\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lset(listkey, i, stringList.get(SMALL_CNT+i));\n\t\t\t\n\t\t\tList<String> range = null;\n\t\t\t\n\t\t\trange = toStr (provider.lrange(listkey, 0, LARGE_CNT));\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertTrue (stringList.get(SMALL_CNT+i).equals(range.get(i)), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// now we'll change their values using the negative index mode\n\t\t\tint lim = SMALL_CNT*-1;\n\t\t\tfor(int i=-1; i>lim; i--)\n\t\t\t\tprovider.lset(listkey, i, stringList.get(i*-1));\n\n\t\t\trange = toStr (provider.lrange(listkey, 0, LARGE_CNT));\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertTrue (stringList.get(SMALL_CNT-i).equals(range.get(i)), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// test edge conditions\n\t\t\t// out of range is same as byte[] as value type makes no difference\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lset(java.lang.String, int, java.lang.Number)}.\n\t */\n\t@Test\n\tpublic void testLsetStringIntNumber() {\n\t\tcmd = Command.LSET.code + \" Number | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, longList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// now we'll change their values\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lset(listkey, i, longList.get(SMALL_CNT+i));\n\t\t\t\n\t\t\tList<Long> range = null;\n\t\t\t\n\t\t\trange = toLong (provider.lrange(listkey, 0, LARGE_CNT));\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertTrue (longList.get(SMALL_CNT+i).equals(range.get(i)), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// now we'll change their values using the negative index mode\n\t\t\tint lim = SMALL_CNT*-1;\n\t\t\tfor(int i=-1; i>lim; i--)\n\t\t\t\tprovider.lset(listkey, i, longList.get(i*-1));\n\n\t\t\trange = toLong (provider.lrange(listkey, 0, LARGE_CNT));\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertTrue (longList.get(SMALL_CNT-i).equals(range.get(i)), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// test edge conditions\n\t\t\t// out of range is same as byte[] as value type makes no difference\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#lset(java.lang.String, int, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testLsetStringIntT() {\n\t\tcmd = Command.LSET.code + \" Java Object | \" + Command.LLEN;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString listkey = this.keys.get(0);\n\t\t\t// we'll make a list of unique items first\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.rpush(listkey, objectList.get(i));\n\t\t\tassertTrue(provider.llen(listkey)==SMALL_CNT, \"LLEN after RPUSH is wrong\");\n\t\t\t\n\t\t\t// now we'll change their values\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.lset(listkey, i, objectList.get(SMALL_CNT+i));\n\t\t\t\n\t\t\tList<TestBean> range = null;\n\t\t\t\n\t\t\trange = decode (provider.lrange(listkey, 0, LARGE_CNT));\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertTrue (objectList.get(SMALL_CNT+i).equals(range.get(i)), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// now we'll change their values using the negative index mode\n\t\t\tint lim = SMALL_CNT*-1;\n\t\t\tfor(int i=-1; i>lim; i--)\n\t\t\t\tprovider.lset(listkey, i, objectList.get(i*-1));\n\n\t\t\trange = decode (provider.lrange(listkey, 0, LARGE_CNT));\n\t\t\tassertEquals (SMALL_CNT, range.size(), \"range length is wrong\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++)\n\t\t\t\tassertTrue (objectList.get(SMALL_CNT-i).equals(range.get(i)), \"after LSET the expected and range item differ at idx: \" + i);\n\t\t\t\n\t\t\t// test edge conditions\n\t\t\t// out of range is same as byte[] as value type makes no difference\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\n\t/**************** QUERY COMMANDS ******************************/\n\t/**\n\t * This command is still half-baked on the Redis side, so we just test to see if\n\t * it blows up or not.  (cooking:  if you sort on a set/list of size N and your\n\t * constrains (GET) limit the actual results to nothing, Redis (0.091) returns a \n\t * list of size N full of nulls.  That's not tasty ..)\n\t * \n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sort(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testSort() {\n\t\tcmd = Command.SORT.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\t\n\t\tfinal String setkey = \"set-key\";\n\t\tfinal String listkey = \"list-key\";\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tfor(int i=0; i<MEDIUM_CNT; i++){\n\t\t\t\tprovider.sadd(setkey, stringList.get(i));\n\t\t\t\tprovider.lpush(listkey, stringList.get(i));\n\t\t\t}\n\n\t\t\tList<String> sorted = null;\n\t\t\t\n\t\t\tLog.log(\"TEST: SORTED LIST [t.1]\");\n\t\t\tsorted = toStr(provider.sort(listkey).ALPHA().LIMIT(0, MEDIUM_CNT).DESC().exec());\n\t\t\tassertEquals(sorted.size(), MEDIUM_CNT, \"expecting sort results of size MEDIUM_CNT\");\n\t\t\tfor(String s : sorted)\n\t\t\t\tSystem.out.format(\"[t.1]: %s\\n\", s);\n\t\t\t\n\t\t\tString destKey = String.format(\"%s_store\", listkey);\n\t\t\tList<byte[]> ssres = provider.sort(listkey).ALPHA().LIMIT(0, MEDIUM_CNT).DESC().STORE(destKey).exec();\n\t\t\tassertNotNull(ssres, \"result of srot with STORE should be non-null\");\n\t\t\tassertEquals(ssres.size(), 1, \"result of sort with STORE should be a list of single entry (the stored list's size)\");\n\t\t\tlong sortedListSize = Query.Support.unpackValue(ssres);\n\t\t\tassertEquals(sortedListSize, MEDIUM_CNT);\n\t\t\tRedisType type = provider.type(destKey);\n\t\t\tassertEquals(type, RedisType.list, \"dest key of SORT .. STORE should be a LIST\");\n\t\t\tlong sslistSize = provider.llen(destKey);\n\t\t\tassertEquals(sslistSize, sortedListSize, \"result of SORT ... STORE and LLEN of destkey list should be same\");\n\t\t\t\n\t\t\tLog.log(\"TEST: SORTED LIST [t.2]\");\n\t\t\tsorted = toStr(provider.sort(listkey).ALPHA().LIMIT(10, 9).DESC().exec());\n\t\t\tassertEquals(sorted.size(), 9, \"expecting sort results of size 9\");\n\t\t\tfor(String s : sorted)\n\t\t\t\tSystem.out.format(\"[t.2]: %s\\n\", s);\n\t\t\t\n\t\t\tLog.log(\"TEST: SORTED LIST [t.3]\");\n\t\t\tsorted = toStr(provider.sort(listkey).ALPHA().LIMIT(MEDIUM_CNT-1, 1).DESC().exec());\n\t\t\tassertEquals(sorted.size(), 1, \"expecting sort results of size 1\");\n\t\t\tfor(String s : sorted)\n\t\t\t\tSystem.out.format(\"[t.3]: %s\\n\", s);\n\t\t\t\n\t\t\tLog.log(\"TEST: SORTED SET \");\n//\t\t\tsorted = toStr(jredis.sort(setkey).ALPHA().LIMIT(0, 100).BY(\"*BB*\").exec());\n\t\t\tsorted = toStr(provider.sort(setkey).ALPHA().LIMIT(0, 555).DESC().exec());\n\t\t\tfor(String s : sorted)\n\t\t\t\tSystem.out.format(\"%s\\n\", s);\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t\t\n\t\t// force errors\n\t\t\n\t\t// count can't be zero\n\t\tRunnable invalidLimitSpec = new Runnable() {\n\t\t\tpublic void run() {\n\t\t\t\ttry { provider.sort(listkey).ALPHA().LIMIT(0, 0).DESC().exec(); }\n                catch (Throwable t) { throw new RuntimeException (\"\", t); }\n\t\t\t}\n\t\t};\n\t\tassertDidRaiseRuntimeError(invalidLimitSpec, RuntimeException.class);\n\t\t\n\t\t// LIMIT from must be positive, {0...n}\n\t\tRunnable invalidLimitSpec2 = new Runnable() {\n\t\t\tpublic void run() {\n\t\t\t\ttry { provider.sort(listkey).ALPHA().LIMIT(-1, 1).DESC().exec(); }\n                catch (Throwable t) { throw new RuntimeException (\"\", t); }\n\t\t\t}\n\t\t};\n\t\tassertDidRaiseRuntimeError(invalidLimitSpec2, RuntimeException.class);\n\t}\n\n\t\n\t/**************** SORTED SET COMMANDS ******************************/\n\t@Test\n\tpublic void testZaddStringByteArray() {\n\t\tcmd = Command.ZADD.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, random.nextDouble(), dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertFalse(provider.zadd(setkey, random.nextDouble(), dataList.get(i)), \"sadd of existing element should be false\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testZremStringByteArray() {\n\t\tcmd = Command.ZADD.code + \" byte[] | \" + Command.ZREM.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, random.nextDouble(), dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zrem(setkey, dataList.get(i)), \"zrem of existing element should be true\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testZscoreStringByteArray() {\n\t\tcmd = Command.ZSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, doubleList.get(i), dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertEquals (provider.zscore(setkey, dataList.get(i)).doubleValue(), doubleList.get(i), \"zscore of element should be \" + doubleList.get(i));\n\t\t\t\n\t\t\tassertNull(provider.zscore(setkey, \"no such set member\"), \"zscore of none existent member of sorted set should be null\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t\n\t@Test\n\tpublic void testZrankStringByteArray() {\n\t\tcmd = Command.ZRANK.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<=SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<=SMALL_CNT; i++)\n\t\t\t\tassertEquals (provider.zrank(setkey, dataList.get(i)), i, \"zrank of element\");\n\n\t\t\t// edge cases\n\t\t\tassertEquals (provider.zrank(setkey, dataList.get(SMALL_CNT+1)), -1, \"zrank against non-existent member should be -1\");\n\t\t\tassertEquals (provider.zrank(\"no-such-set\", dataList.get(0)), -1, \"zrank against non-existent key should be -1\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t\n\t@Test\n\tpublic void testZrevrankStringByteArray() {\n\t\tcmd = Command.ZREVRANK.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<=SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<=SMALL_CNT; i++)\n\t\t\t\tassertEquals (provider.zrevrank(setkey, dataList.get(i)), SMALL_CNT - i, \"zrevrank of element\");\n\n\t\t\t// edge cases\n\t\t\tassertEquals (provider.zrevrank(setkey, dataList.get(SMALL_CNT+1)), -1, \"zrevrank against non-existent member should be -1\");\n\t\t\tassertEquals (provider.zrevrank(\"no-such-set\", dataList.get(0)), -1, \"zrevrank against non-existent key should be -1\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t@Test\n\tpublic void testZrangeWithscoresStringByteArray() {\n\t\tcmd = Command.ZRANGE$OPTS.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tList<byte[]>  zvalues = provider.zrange(setkey, 0, SMALL_CNT);\n\t\t\t\n\t\t\tList<ZSetEntry>  zsubset = provider.zrangeSubset(setkey, 0, SMALL_CNT);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++){\n\t\t\t\tassertEquals(zsubset.get(i).getValue(), dataList.get(i), \"value of element from zrange_withscore\");\n\t\t\t\tassertEquals(zsubset.get(i).getValue(), zvalues.get(i), \"value of element from zrange_withscore compared with zscore with same range query\");\n\t\t\t\tassertEquals (zsubset.get(i).getScore(), (double)i, \"score of element from zrange_withscore\");\n\t\t\t\tassertTrue(zsubset.get(i).getScore() <= zsubset.get(i+1).getScore(), \"range member score should be smaller or equal to previous range member.  idx: \" + i);\n\t\t\t\tif(i>0) assertTrue(zsubset.get(i).getScore() >= zsubset.get(i-1).getScore(), \"range member score should be bigger or equal to previous range member.  idx: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testZrevrangeWithscoresStringByteArray() {\n\t\tcmd = Command.ZREVRANGE$OPTS.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tList<byte[]>  zvalues = provider.zrevrange(setkey, 0, SMALL_CNT);\n\t\t\t\n\t\t\tList<ZSetEntry>  zsubset = provider.zrevrangeSubset(setkey, 0, SMALL_CNT);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++){\n\t\t\t\tassertEquals(zsubset.get(i).getValue(), dataList.get(MEDIUM_CNT-i-1), \"value of element from zrange_withscore\");\n\t\t\t\tassertEquals(zsubset.get(i).getValue(), zvalues.get(i), \"value of element from zrange_withscore compared with zscore with same range query\");\n\t\t\t\tassertEquals (zsubset.get(i).getScore(), (double)MEDIUM_CNT-i-1, \"score of element from zrange_withscore\");\n\t\t\t\tassertTrue(zsubset.get(i).getScore() >= zsubset.get(i+1).getScore(), \"range member score should be smaller or equal to previous range member.  idx: \" + i);\n\t\t\t\tif(i>0) assertTrue(zsubset.get(i).getScore() <= zsubset.get(i-1).getScore(), \"range member score should be bigger or equal to previous range member.  idx: \" + i);\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testZrangebyscoreStringByteArray() {\n\t\tcmd = Command.ZRANGEBYSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tList<byte[]>  range = provider.zrangebyscore(setkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size() > 0, \"should have non empty results for range by score here\");\n\t\t\tfor(int i=0;i<SMALL_CNT-1; i++){\n\t\t\t\tassertEquals(range.get(i), dataList.get(i), \"expected value in the range by score missing\");\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testZrangebyscoreWithScoresStringByteArray() {\n\t\tcmd = Command.ZRANGEBYSCORE$OPTS.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\n\t\t\tList<ZSetEntry>  range = provider.zrangebyscoreSubset(setkey, 0, SMALL_CNT);\n\t\t\tassertTrue(range.size() > 0, \"should have non empty results for range by score here\");\n\t\t\tfor(int i=0;i<SMALL_CNT-1; i++){\n\t\t\t\tassertEquals(range.get(i).getValue(), dataList.get(i), \"expected value in the range by score missing\");\n\t\t\t\tassertEquals(range.get(i).getScore(), (double)i, \"score of element from zrangebyscore_withscore\");\n\t\t\t}\n\t\t}\n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t@Test\n\tpublic void testZremrangebyscoreStringByteArray() {\n\t\tcmd = Command.ZREMRANGEBYSCORE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tlong count = provider.zcount(setkey, 0, SMALL_CNT);\n\t\t\tassertTrue(count > 0, \"should have non-zero number of rem cnt for zcount\");\n\t\t\tassertEquals(count, SMALL_CNT+1, \"should have specific number of rem cnt for zcount\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t\n\t@Test\n\tpublic void testZcountStringByteArray() {\n\t\tcmd = Command.ZCOUNT.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tlong remCnt = provider.zremrangebyscore(setkey, 0, SMALL_CNT);\n\t\t\tassertTrue(remCnt > 0, \"should have non-zero number of rem cnt for zremrangebyscore\");\n\t\t\tassertEquals(remCnt, SMALL_CNT+1, \"should have specific number of rem cnt for zremrangebyscore\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testZremrangebyrankStringByteArray() {\n\t\tcmd = Command.ZREMRANGEBYRANK.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tlong remCnt = provider.zremrangebyrank(setkey, 0, SMALL_CNT);\n\t\t\tassertTrue(remCnt > 0, \"should have non-zero number of rem cnt for zremrangebyrank\");\n\t\t\tassertEquals(remCnt, SMALL_CNT+1, \"should have specific number of rem cnt for zremrangebyrank\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t\tcatch (RuntimeException rte) { fail(cmd + \" RUNTIME-ERROR => \" + rte.getLocalizedMessage(), rte); }\n\t}\n\t\n\t@Test\n\tpublic void testZincrbyStringByteArray() {\n\t\tcmd = Command.ZSCORE.code + \" byte[] | \" + Command.ZINCRBY.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, doubleList.get(i), dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertEquals (provider.zscore(setkey, dataList.get(i)).doubleValue(), doubleList.get(i), \"zscore of element should be \" + doubleList.get(i));\n\n\t\t\tdouble increment = 0.05;\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertEquals (provider.zincrby(setkey, increment ,dataList.get(i)).doubleValue(), doubleList.get(i) + increment, \"zincr of element should be \" + doubleList.get(i) + increment);\n\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t@Test\n\tpublic void testZrangeStringByteArray() {\n\t\tcmd = Command.ZRANGE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<MEDIUM_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, doubleList.get(i), dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tList<byte[]>  range = provider.zrange(setkey, 0, SMALL_CNT);\n\t\t\tfor(int i=1;i<SMALL_CNT-1; i++){\n\t\t\t\tassertTrue(provider.zscore(setkey, range.get(i)).doubleValue() <= provider.zscore(setkey, range.get(i+1)).doubleValue(), \"range member score should be smaller or equal to previous range member\");\n\t\t\t\tassertTrue(provider.zscore(setkey, range.get(i)).doubleValue() >= provider.zscore(setkey, range.get(i-1)).doubleValue(), \"range member score should be bigger or equal to previous range member\");\n\t\t\t}\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertEquals (provider.zscore(setkey, dataList.get(i)), doubleList.get(i), \"zscore of element should be \" + doubleList.get(i));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t/**************** SET COMMANDS ******************************/\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sadd(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testSaddStringByteArray() {\n\t\tcmd = Command.SADD.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertFalse(provider.sadd(setkey, dataList.get(i)), \"sadd of existing element should be false\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sadd(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testSaddStringString() {\n\t\tcmd = Command.SADD.code + \" String\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, stringList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertFalse(provider.sadd(setkey, stringList.get(i)), \"sadd of existing element should be false\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sadd(java.lang.String, java.lang.Number)}.\n\t */\n\t@Test\n\tpublic void testSaddStringNumber() {\n\t\tcmd = Command.SADD.code + \" Number\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, longList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertFalse(provider.sadd(setkey, longList.get(i)), \"sadd of existing element should be false\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sadd(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testSaddStringT() {\n\t\tcmd = Command.SADD.code + \" Java Object\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, objectList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertFalse(provider.sadd(setkey, objectList.get(i)), \"sadd of existing element should be false\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t@Test\n\tpublic void testSrandmember() {\n\t\tcmd = Command.SRANDMEMBER.code + \" String \";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\t// add a small set\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, stringList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\t// get members\n\t\t\tList<String> members = null;\n\t\t\tmembers = toStr(provider.smembers(setkey));\n\t\t\tassertTrue(members.size() == SMALL_CNT);\n\t\t\t\n\t\t\t// get random member\n\t\t\tString randomMemeber = toStr(provider.srandmember(setkey));\n\t\t\t\n\t\t\tboolean found = false;\n\t\t\tfor(String m : members){\n\t\t\t\tif(m.equals(randomMemeber)) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tassertTrue(found, \"random set element should have been in the members list\");\n\n\t\t\t\n\t\t\t// test edget conditions\n\t\t\tbyte[] membytes = null;\n\n\t\t\t// empty set\n\t        provider.sadd(\"empty\", \"delete-me\");\n\t        provider.srem(\"empty\", \"delete-me\");\n\t        membytes = provider.srandmember(\"empty\");\n\t        assertEquals(membytes, null, \"empty set random member should be null\");\n\t        assertEquals(toStr(membytes), null, \"empty set random member should be null\");\n\t        \n\t\t\t// non-existent key\n\t        membytes = provider.srandmember(\"no-such-key\");\n\t        assertEquals(membytes, null, \"non-existent key/set random member should be null\");\n\t        assertEquals(toStr(membytes), null, \"non-existent key/set random member should be null\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t\t\n\t}\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#smembers(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testSmembers() {\n\t\tcmd = Command.SMEMBERS.code + \" byte[] \";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tList<byte[]> members = null;\n\t\t\tmembers = provider.smembers(setkey);\n\t\t\tassertTrue(members.size() == SMALL_CNT);\n\t\t\t// byte[] don't play nice with equals -- values are random so if size matches, its ok\n//\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n//\t\t\t\tassertTrue(members.contains(dataList.get(i)), \"set members should include item at idx: \" + i);\n\n\t\t\t// test edget conditions\n\t\t\t// empty set\n\t\t\tprovider.sadd(keys.get(2), dataList.get(0));\n\t\t\tprovider.srem(keys.get(2), dataList.get(0));\n\t\t\tassertEquals(provider.scard(keys.get(2)), 0, \"set cardinality for an empty set should be 0\");\n\t\t\tmembers = provider.smembers(keys.get(2));\n\t\t\tassertEquals(members, Collections.EMPTY_LIST,\"smembers should return an empty list\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\n\t\tcmd = Command.SMEMBERS.code + \" String \";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, stringList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tList<String> members = null;\n\t\t\tmembers = toStr(provider.smembers(setkey));\n\t\t\tassertTrue(members.size() == SMALL_CNT);\n\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(members.contains(stringList.get(i)), \"set members should include item at idx: \" + i);\n\n\t\t\t// test edget conditions\n\t\t\t// empty set\n\t\t\tprovider.sadd(keys.get(2), stringList.get(0));\n\t\t\tprovider.srem(keys.get(2), stringList.get(0));\n\t\t\tassertTrue(provider.scard(keys.get(2)) == 0, \"set should be empty now\");\n\t\t\tmembers = toStr(provider.smembers(keys.get(2)));\n\t\t\t//assertNull(members, \"smembers should return null for set that was fully emptied\"); // api change.\n\t\t\tassertEquals(members.size(), 0, \"smembers should have returned an empty list\"); // api change - now it is null\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\n\t\tcmd = Command.SMEMBERS.code + \" Number \";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, longList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tList<Long> members = null;\n\t\t\tmembers = toLong (provider.smembers(setkey));\n\t\t\tassertTrue(members.size() == SMALL_CNT);\n\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(members.contains(longList.get(i)), \"set members should include item at idx: \" + i);\n\n\t\t\t// test edget conditions\n\t\t\t// empty set\n\t\t\tprovider.sadd(keys.get(2), longList.get(0));\n\t\t\tprovider.srem(keys.get(2), longList.get(0));\n\t\t\tassertTrue(provider.scard(keys.get(2)) == 0, \"set should be empty now\");\n\t\t\tmembers = toLong (provider.smembers(keys.get(2)));\n\t\t\t//assertNull(members, \"smembers should return null\"); // api change (also toLong changed to handle the null results).\n\t\t\tassertEquals(members.size(), 0, \"smembers should have returned an empty list\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\n\t\tcmd = Command.SMEMBERS.code + \" Java Object \";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, objectList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tList<TestBean> members = null;\n\t\t\tmembers = decode (provider.smembers(setkey));\n\t\t\tassertTrue(members.size() == SMALL_CNT);\n\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(members.contains(objectList.get(i)), \"set members should include item at idx: \" + i);\n\n\t\t\t// test edget conditions\n\t\t\t// empty set\n\t\t\tprovider.sadd(keys.get(2), objectList.get(0));\n\t\t\tprovider.srem(keys.get(2), objectList.get(0));\n\t\t\tassertTrue(provider.scard(keys.get(2)) == 0, \"set should be empty now\");\n\t\t\tmembers = decode (provider.smembers(keys.get(2)));\n\t\t\t//assertNull(members, \"smembers should return null\"); // API change\n\t\t\tassertEquals(members.size(), 0, \"smembers should have returned an empty list\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sismember(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testSmoveStringByteArray() {\n\t\tcmd = Command.SMOVE.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString srckey = keys.get(0);\n\t\t\tString destkey = keys.get(1);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(srckey, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) {\n\t\t\t\tassertTrue(provider.sismember(srckey, dataList.get(i)), \"should be a member of the src before move\");\n\t\t\t\t\n\t\t\t\t/* smove */\n\t\t\t\tassertTrue(provider.smove (srckey, destkey, dataList.get(i)), \"move should be ok\");\n\t\t\t\t\n\t\t\t\tassertTrue(provider.sismember(destkey, dataList.get(i)), \"should be a member of the dest after move\");\n\t\t\t\tassertFalse(provider.sismember(srckey, dataList.get(i)), \"should NOT be a member of the src after move\");\n\t\t\t}\n\t\t\t\n\t\t\t// lets try the error conditions by using wrong type for src or dest\n\t\t\tboolean expectedError;\n\t\t\t\n\t\t\tString stringKey = \"foo\";\n\t\t\tprovider.set(stringKey, \"smove test\");\n\t\t\t\n\t\t\tString listKey = \"bar\";\n\t\t\tprovider.lpush(listKey, \"smove test\");\n\t\t\t\n\t\t\t// wrong dest\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\tassertTrue(provider.smove (destkey, stringKey, dataList.get(0)), \"dest is wrong type\");\n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\t// wrong src\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\tassertTrue(provider.smove (stringKey, srckey, dataList.get(0)), \"src is wrong type\");\n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t\t\n\t\t\t// wrong src and dest\n\t\t\texpectedError = false;\n\t\t\ttry {\n\t\t\t\tLog.log(\"Expecting an operation against key holding the wrong kind of value ERROR..\");\n\t\t\t\tassertTrue(provider.smove (listKey, stringKey, dataList.get(0)), \"src and dest are wrong type\");\n\t\t\t}\n\t\t\tcatch (RedisException e) { expectedError = true; }\n\t\t\tassertTrue(expectedError, \"should have raised an exception but did not\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sismember(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testSismemberStringByteArray() {\n\t\tcmd = Command.SISMEMBER.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sismember(setkey, dataList.get(i)), \"should be a member of the set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sismember(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testSismemberStringString() {\n\t\tcmd = Command.SISMEMBER.code + \" String\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, stringList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sismember(setkey, stringList.get(i)), \"should be a member of the set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sismember(java.lang.String, java.lang.Number)}.\n\t */\n\t@Test\n\tpublic void testSismemberStringNumber() {\n\t\tcmd = Command.SISMEMBER.code + \" Number\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, longList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sismember(setkey, longList.get(i)), \"should be a member of the set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sismember(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testSismemberStringT() {\n\t\tcmd = Command.SISMEMBER.code + \" Java Object\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, objectList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sismember(setkey, objectList.get(i)), \"should be a member of the set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#scard(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testScard() {\n\t\tcmd = Command.SCARD.code + \" Java Object\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.sadd(setkey, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tassertEquals (provider.scard (setkey), SMALL_CNT, \"scard should be SMALL_CNT\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#scard(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testZcard() {\n\t\tcmd = Command.ZADD.code + \" Java Object | \" + Command.ZCARD.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++)\n\t\t\t\tassertTrue(provider.zadd(setkey, i, dataList.get(i)), \"zadd of random element should be true\");\n\t\t\t\n\t\t\tassertEquals (provider.zcard (setkey), SMALL_CNT, \"zcard should be SMALL_CNT\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sinter(java.lang.String, java.lang.String[])}.\n\t */\n\t@Test\n\tpublic void testSinter() {\n\t\tcmd = Command.SINTER.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey1 = keys.get(0);\n\t\t\tString setkey2 = keys.get(1);\n\t\t\tString setunique = keys.get(2);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) {\n\t\t\t\tassertTrue(provider.sadd(setkey1, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setkey2, dataList.get(i+2)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setunique, dataList.get(10+i+SMALL_CNT)), \"sadd of random element should be true\");\n\t\t\t}\n\t\t\tassertEquals (0, provider.sinter(setkey1, setkey2, setunique).size(), \"should be no common elements in all three\");\n\t\t\tassertTrue (provider.sinter(setkey1, setkey2).size() > 0, \"should be common elements in set 1 and 2\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sinterstore(java.lang.String, java.lang.String[])}.\n\t */\n\t@Test\n\tpublic void testSinterstore() {\n\t\tcmd = Command.SINTERSTORE.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey1 = keys.get(0);\n\t\t\tString setkey2 = keys.get(1);\n\t\t\tString setunique = keys.get(2);\n\t\t\tString interset = keys.get(3);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) {\n\t\t\t\tassertTrue(provider.sadd(setkey1, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setkey2, dataList.get(i+2)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setunique, dataList.get(10+i+SMALL_CNT)), \"sadd of random element should be true\");\n\t\t\t}\n\t\t\tprovider.sinterstore (interset, setkey1, setkey2, setunique);\n\t\t\tassertEquals (0, provider.scard(interset), \"interset set should be empty\");\n\t\t\tprovider.sinterstore (interset, setkey1, setkey2);\n\t\t\tassertTrue (provider.scard(interset) > 0, \"interset set should be non-empty\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sunion(java.lang.String, java.lang.String[])}.\n\t */\n\t@Test\n\tpublic void testSunion() {\n\t\tcmd = Command.SUNION.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey1 = keys.get(0);\n\t\t\tString setkey2 = keys.get(1);\n\t\t\tString setunique = keys.get(2);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) {\n\t\t\t\tassertTrue(provider.sadd(setkey1, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setkey2, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setunique, stringList.get(i)), \"sadd of random element should be true\");\n\t\t\t}\n\t\t\tassertEquals (SMALL_CNT, provider.sunion (setkey1, setkey2).size(), \"union of equiv sets should have same card as the two\");\n\t\t\tassertEquals (SMALL_CNT*2, provider.sunion (setkey1, setkey2, setunique).size(), \"union of all 3 sets should have SMALL_CNT * 2 members\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sunionstore(java.lang.String, java.lang.String[])}.\n\t */\n\t@Test\n\tpublic void testSunionstore() {\n\t\tcmd = Command.SUNIONSTORE.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey1 = keys.get(0);\n\t\t\tString setkey2 = keys.get(1);\n\t\t\tString setunique = keys.get(2);\n\t\t\tString union = keys.get(3);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) {\n\t\t\t\tassertTrue(provider.sadd(setkey1, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setkey2, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\tassertTrue(provider.sadd(setunique, stringList.get(i)), \"sadd of random element should be true\");\n\t\t\t}\n\t\t\tprovider.sunionstore (union, setkey1, setkey2);\n\t\t\tassertEquals (SMALL_CNT, provider.scard(union), \"union of equiv sets should have same card as the two\");\n\t\t\tprovider.sunionstore (union, setkey1, setkey2, setunique);\n\t\t\tassertEquals (SMALL_CNT*2, provider.scard(union), \"union of all 3 sets should have SMALL_CNT * 2 members\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sdiff(java.lang.String, java.lang.String[])}.\n\t */\n\t@Test\n\tpublic void testSdiff() {\n\t\tcmd = Command.SDIFF.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey1 = keys.get(0);\n\t\t\tString setkey2 = keys.get(1);\n\t\t\tString setkey3 = keys.get(2);\n\t\t\tString setexpectedkey = keys.get(3);\n//\t\t\t\n\t\t\t// - per the redis doc -- \n\t\t\t// note that basically, SDIFF k, k1, ..., kn is a diff between k and union (k1, .., kn)\n\t\t\t//\n\t\t\tprovider.sadd(setkey1, \"x\");\n\t\t\tprovider.sadd(setkey1, \"a\");\n\t\t\tprovider.sadd(setkey1, \"b\");\n\t\t\tprovider.sadd(setkey1, \"c\");\n\t\t\t\n\t\t\tprovider.sadd(setkey2, \"c\");\n\n\t\t\tprovider.sadd(setkey3, \"a\");\n\t\t\tprovider.sadd(setkey3, \"d\");\n\t\t\t\n\t\t\tprovider.sadd(setexpectedkey, \"x\");\n\t\t\tprovider.sadd(setexpectedkey, \"b\");\n\t\t\t\n\t\t\tList<String> sdiffResults = DefaultCodec.toStr(provider.sdiff(setkey1, setkey2, setkey3));\n\t\t\tassertEquals(provider.scard(setexpectedkey), sdiffResults.size(), \"sdiff result and expected set should have same cardinality\");\n\t\t\tfor(String s : sdiffResults)\n\t\t\t\tassertTrue(provider.sismember(setexpectedkey, s), s + \" should be a member of the expected result set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#sdiff(java.lang.String, java.lang.String[])}.\n\t */\n\t@Test\n\tpublic void testSdiffstore() {\n\t\tcmd = Command.SDIFFSTORE.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey1 = keys.get(0);\n\t\t\tString setkey2 = keys.get(1);\n\t\t\tString setkey3 = keys.get(2);\n\t\t\tString setdiffreskey = keys.get(3);\n//\t\t\t\n\t\t\t// - per the redis doc -- \n\t\t\t// note that basically, SDIFF k, k1, ..., kn is a diff between k and union (k1, .., kn)\n\t\t\t//\n\t\t\tprovider.sadd(setkey1, \"x\");\n\t\t\tprovider.sadd(setkey1, \"a\");\n\t\t\tprovider.sadd(setkey1, \"b\");\n\t\t\tprovider.sadd(setkey1, \"c\");\n\t\t\t\n\t\t\tprovider.sadd(setkey2, \"c\");\n\n\t\t\tprovider.sadd(setkey3, \"a\");\n\t\t\tprovider.sadd(setkey3, \"d\");\n\t\t\t\t\t\t\n\t\t\tprovider.sdiffstore (setdiffreskey, setkey1, setkey2, setkey3);\n\t\t\tassertEquals(provider.scard(setdiffreskey), provider.sdiff(setkey1, setkey2, setkey3).size(), \"sdiff result and sdiffstore dest set should have same cardinality\");\n\t\t\tassertTrue(provider.sismember(setdiffreskey, \"x\"), \"x should be a member of the expected result set\");\n\t\t\tassertTrue(provider.sismember(setdiffreskey, \"b\"), \"b should be a member of the expected result set\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#srem(java.lang.String, byte[])}.\n\t */\n\t@Test\n\tpublic void testSremStringByteArray() {\n\t\tcmd = Command.SISMEMBER.code + \" byte[]\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.sadd(setkey, dataList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.srem(setkey, dataList.get(i)), \"should be a removable member of the set\");\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#srem(java.lang.String, java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testSremStringString() {\n\t\tcmd = Command.SISMEMBER.code + \" String\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.sadd(setkey, stringList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.srem(setkey, stringList.get(i)), \"should be a removable member of the set\");\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#srem(java.lang.String, java.lang.Number)}.\n\t */\n\t@Test\n\tpublic void testSremStringNumber() {\n\t\tcmd = Command.SISMEMBER.code + \" Number\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.sadd(setkey, longList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.srem(setkey, longList.get(i)), \"should be a removable member of the set\");\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#srem(java.lang.String, java.io.Serializable)}.\n\t */\n\t@Test\n\tpublic void testSremStringT() {\n\t\tcmd = Command.SISMEMBER.code + \" Java Object\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tString setkey = keys.get(0);\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.sadd(setkey, objectList.get(i)), \"sadd of random element should be true\");\n\t\t\t\n\t\t\tfor(int i=0;i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(provider.srem(setkey, objectList.get(i)), \"should be a removable member of the set\");\n\t\t\t\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t/************************ DB COMMANDS ***********************/\n\t\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#dbsize()}.\n\t */\n\t@Test\n\tpublic void testDbsize() {\n\t\tcmd = Command.DBSIZE.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.flushdb();\n\t\t\tassertTrue (provider.dbsize() == 0);\n\t\t\t\n\t\t\tfor (int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.set(keys.get(i), dataList.get(i));\n\t\t\t\n\t\t\tassertTrue (provider.dbsize() == SMALL_CNT, \"dbsize should be SMALL_CNT\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#randomkey()}.\n\t */\n\t@Test\n\tpublic void testRandomkey() {\n\t\tcmd = Command.RANDOMKEY.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\tassertTrue(provider.dbsize() == 0);\n\t\t\t\n//\t\t\tString iamempty = provider.randomkey();\n\t\t\tbyte[] iamempty = provider.randomkey();\n\t\t\tassertNull(iamempty, \"randomkey of an empty db should be null, but instead it was: \" + iamempty);\n\t\t\t\n\t\t\tfor (int i=0; i<MEDIUM_CNT; i++)\n\t\t\t\tprovider.set(keys.get(i), dataList.get(i));\n\t\t\t\n\t\t\tassertTrue (provider.dbsize() == MEDIUM_CNT, \"dbsize should be MEDIUM_CNT\");\n\t\t\tfor (int i=0; i<SMALL_CNT; i++) {\n\t\t\t\tassertTrue(keys.contains(new String(provider.randomkey())), \"randomkey should be an item in our keys list\");\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n//\t/**\n//\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#move(java.lang.String, int)}.\n//\t */\n//\t@Test\n//\tpublic void testMove() {\n//\t\ttest = Command.MOVE.code ;\n//\t\tLog.log(\"TEST: %s command\", test);\n//\t\ttry {\n//\t\t\tjredis.flushdb();\n//\t\t\tassertTrue (jredis.dbsize() == 0, \"db1 should be empty\");\n//\t\t\t\n//\t\t\tjredis.select(db2).flushdb();\n//\t\t\tassertTrue (jredis.dbsize() == 0, \"db2 should be empty\");\n//\t\t\t\n//\t\t\tjredis.set(keys.get(0), dataList.get(0));\n//\t\t\tassertTrue (jredis.dbsize() == 1, \"db2 should have 1 key at this point\");\n//\t\t\t\n//\t\t\tjredis.move(keys.get(0), db1);\n//\t\t\tassertTrue (jredis.dbsize() == 0, \"db2 should be empty again\");\n//\t\t\tjredis.select(db1);\n//\t\t\tassertTrue (jredis.dbsize() == 1, \"db1 should have 1 key at this point\");\n//\t\t\t\n//\t\t} \n//\t\tcatch (RedisException e) { fail(test + \" ERROR => \" + e.getLocalizedMessage(), e); }\n//\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#type(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testType() {\n\t\tcmd = Command.TYPE.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.set(keys.get(0), dataList.get(0));\n\t\t\tprovider.sadd(keys.get(1), dataList.get(1));\n\t\t\tprovider.rpush(keys.get(2), dataList.get(2));\n\t\t\t\n\t\t\tassertTrue(provider.type(keys.get(0))==RedisType.string, \"type should be string\");\n\t\t\tassertTrue(provider.type(keys.get(1))==RedisType.set, \"type should be set\");\n\t\t\tassertTrue(provider.type(keys.get(2))==RedisType.list, \"type should be list\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#debug()}.\n\t */\n\t@Test\n\tpublic void testDebug() {\n\t\tcmd = Command.DEBUG.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tprovider.set(\"foo\", \"bar\");\n\t\t\tObjectInfo info = provider.debug(\"foo\");\n\t\t\tassertNotNull(info);\n\t\t\tLog.log(\"DEBUG of key => %s\", info);\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#info()}.\n\t */\n\t@Test\n\tpublic void testInfo() {\n\t\tcmd = Command.INFO.code ;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\n\t\t\tMap<String, String> infoMap =  provider.info();\n\t\t\tfor (RedisInfo info : RedisInfo.values()){\n\t\t\t\tif(infoMap.get(info.name()) == null){\n\t\t\t\t\tLog.problem(\"Note that expected INFO entry %s is apparently deprecated - IGNORING\", info);\n\t\t\t\t} else {\n\t\t\t\t\tLog.log(\"%s => %s\", info.name(), infoMap.get(info.name()));\n\t\t\t\t}\n\t\t\t}\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#keys()}.\n\t */\n\t@Test\n\tpublic void testKeys() {\n\t\tcmd = Command.KEYS.code + \" (*)\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tfor (int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.set(keys.get(i), dataList.get(i));\n\n\t\t\tList<byte[]> redisBinkeys = provider.keys();\n\t\t\tList<String> rediskeys = new ArrayList<String>(redisBinkeys.size());\n\t\t\tfor(byte[] bk : redisBinkeys)\n\t\t\t\trediskeys.add(new String(bk));\n\t\t\tassertEquals(SMALL_CNT, rediskeys.size(), \"size of key list should be SMALL_CNT\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(rediskeys.contains(keys.get(i)), \"should contain \" + keys.get(i));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\n\t/**\n\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#keys(java.lang.String)}.\n\t */\n\t@Test\n\tpublic void testKeysString() {\n\t\tcmd = Command.KEYS.code + \" (using patterns)\";\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tfor (int i=0; i<SMALL_CNT; i++)\n\t\t\t\tprovider.set(patternList.get(i), dataList.get(i));\n\n\t\t\tList<byte[]> redisBinkeys = provider.keys(\"*\"+patternA+\"*\");\n\t\t\tList<String> rediskeys = new ArrayList<String>(redisBinkeys.size());\n\t\t\tfor(byte[] bk : redisBinkeys)\n\t\t\t\trediskeys.add(new String(bk));\n\t\t\tassertEquals(SMALL_CNT, rediskeys.size(), \"size of key list should be SMALL_CNT\");\n\t\t\tfor(int i=0; i<SMALL_CNT; i++) \n\t\t\t\tassertTrue(rediskeys.contains(patternList.get(i)), \"should contain \" + patternList.get(i));\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t@Test\n\tpublic void testEcho() {\n\t\tcmd = Command.ECHO.code;\n\t\tLog.log(\"TEST: %s command\", cmd);\n\t\ttry {\n\t\t\tprovider.flushdb();\n\t\t\t\n\t\t\tassertEquals(dataList.get(0), provider.echo(dataList.get(0)), \"data and echo results\");\n\t\t\t\n\t\t\tbyte[] zerolenData = new byte[0];\n\t\t\tassertEquals(zerolenData, provider.echo(zerolenData), \"zero len byte[] and echo results\");\n\t\t\t\n\t\t\tboolean expected = false;\n\t\t\ttry {\n\t\t\t\tprovider.echo((byte[])null);\n\t\t\t}\n\t\t\tcatch(IllegalArgumentException e) { expected = true; }\n\t\t\tassertTrue(expected, \"expecting exception for null value to ECHO\");\n\t\t} \n\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n\t}\n\t\n\t\n//\t/**\n//\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#shutdown()}.\n//\t */\n//\t@Test\n//\tpublic void testShutdown() {\n//\t\tfail(\"Not yet implemented\");\n//\t}\n//\n\t// ========================================================================\n\t// Test MULTI/EXEC/DISCARD *BASICS*\n\t// ========================================================================\n\t/**\n\t * Test the basics of multi/exec/discard\n\t * TODO: requires supports() in JRedis.\n\t */\n//\t@Test\n//\tpublic void testMultiDiscardBasics() {\n//\t\tcmd = Command.MULTI + \" | \" + Command.DISCARD + \" | basics\";\n//\t\tLog.log(\"TEST: %s command\", cmd);\n//\t\t\n//\t\ttry {\n//\t\t\tprovider.flushdb();\n//\t\t} \n//\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n//\t\t\n//\t\ttry {\n//\t\t\tprovider.multi();\n//\t\t\tprovider.discard();\n//\t\t} \n//\t\tcatch (RedisException e) { fail(cmd + \" ERROR => \" + e.getLocalizedMessage(), e); }\n//\t\t\n//\t\tboolean didRaiseEx;\n//\t\tdidRaiseEx = false;\n//\t\ttry {\n//\t\t\tprovider.discard();\n//\t\t}\n//\t\tcatch (IllegalArgumentException e) {didRaiseEx = true;}\n//\t\tcatch (Throwable whatsthis) { fail (\"unexpected exception raised\", whatsthis);}\n//\t\tif(!didRaiseEx){ fail (\"Expected exception not raised.\"); }\n//\t}\n\t// ========================================================================\n\t// Test Properties\n\t// ========================================================================\n\t\n\t/** the JRedis implementation being tested */\n//\tprivate JRedis provider = null;\n\t\n\t// ------------------------------------------------------------------------\n\t// JRedis Provider initialize methods\n\t// ------------------------------------------------------------------------\n\n//\t/**\n//\t * Sets the {@link JRedis} implementation provider for the test suite\n//\t */\n//\t@BeforeTest\n//\tpublic void setJRedisProvider () {\n//\t\ttry {\n//\t\t\tJRedis jredis = newJRedisProviderInstance();\n//\n//\t\t\tsetJRedisProviderInstance(jredis);\n//\t\t\tprepTestDBs();\n//\t\t\t\n//\t\t\tLog.log(\"JRedisClientNGTest.setJRedisProvider - done\");\n//        }\n//        catch (ClientRuntimeException e) {\n//        \tLog.error(e.getLocalizedMessage());\n//        }\n//\t}\n//\t\n//\t/**\n//\t * Extension point:  Tests for specific implementations of {@link JRedis} \n//\t * implement this method to create the provider instance.\n//\t * @return {@link JRedis} implementation instance\n//\t */\n//\tprotected abstract JRedis newJRedisProviderInstance () ;\n//\t\n//\t/**\n//\t * Must be called by a BeforeTest method to set the jredis parameter.\n//\t * @param jredisProvider that is being tested.\n//\t */\n//\tprotected final void setJRedisProviderInstance (JRedis jredisProvider) {\n//\t\tthis.jredis = jredisProvider;\n//\t\tLog.log( \"TEST: \" +\n//\t\t\t\t\"\\n\\t-----------------------------------------------\\n\" +\n//\t\t\t\t\"\\tProvider Class: %s\" +\n//\t\t\t\t\"\\n\\t-----------------------------------------------\\n\", \n//\t\t\t\tjredisProvider.getClass().getCanonicalName());\n//\t}\n//\t/**\n//\t * @return the {@link JRedis} instance used for the provider tests\n//\t */\n//\tprotected final JRedis getJRedisProviderInstance() {\n//\t\treturn jredis;\n//\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/JRedisServiceTest.java",
    "content": "///*\n// *   Copyright 2009 Joubin Houshyar\n// * \n// *   Licensed under the Apache License, Version 2.0 (the \"License\");\n// *   you may not use this file except in compliance with the License.\n// *   You may obtain a copy of the License at\n// *    \n// *   http://www.apache.org/licenses/LICENSE-2.0\n// *    \n// *   Unless required by applicable law or agreed to in writing, software\n// *   distributed under the License is distributed on an \"AS IS\" BASIS,\n// *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *   See the License for the specific language governing permissions and\n// *   limitations under the License.\n// */\n//\n//package org.jredis.ri.alphazero;\n//\n//import static org.testng.Assert.fail;\n//import org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\n//import org.jredis.connector.ConnectionSpec;\n//import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n//import org.jredis.ri.alphazero.support.Log;\n//import org.testng.annotations.AfterTest;\n//import org.testng.annotations.BeforeSuite;\n//import org.testng.annotations.Parameters;\n//import org.testng.annotations.Test;\n//\n///**\n// * As of now, this class simply runs the same set of {@link JRedis} contract\n// * compliance using {@link JRedisService} as the provider.\n// * \n// * TODO: figure out a good way to meaningfully test service (e.g. concurrent\n// * and random method usage ..)\n// * \n// * @author  Joubin Houshyar (alphazero@sensesay.net)\n// * @version alpha.0, Oct 9, 2009\n// * @since   alpha.0\n// * \n// */\n//@Test(sequential = true, suiteName=\"JRedisService-tests\")\n////public class JRedisServiceTest extends JRedisProviderTestsBase {\n//public class JRedisServiceTest extends ConcurrentJRedisProviderTestsBase {\n//\t\n//\t// ------------------------------------------------------------------------\n//\t// JRedisService specific Test Suite Parameters with default values\n//\t// ------------------------------------------------------------------------\n//\tprotected int connectionCnt = 1;\n//\t\n//\t// ------------------------------------------------------------------------\n//\t// TEST SETUP \n//\t// ------------------------------------------------------------------------\n//\t/**\n//\t * {@link JRedisService} test suite requires the additional params.\n//\t * @param connectionCount\n//\t */\n//\t@Parameters({ \n//\t\t\"jredis.service.connection.cnt\" \n//\t})\n//\t@BeforeSuite\n//\tpublic void serviceSuiteParametersInit(\n//\t\t\tint connectionCount\n//\t\t) \n//\t{\n//\t\tthis.connectionCnt = connectionCount;\n//\t\tLog.log(\"JRedisServiceTest: Using %d connections\", connectionCount);\n//\t\tLog.log(\"JRedisService Suite parameters initialized <suiteParametersInit>\");\n//\t}\t\n//\n//\t/* (non-Javadoc)\n//\t * @see org.jredis.ri.alphazero.JRedisProviderTestNGBase#newJRedisProviderInstance()\n//\t */\n//\tprotected JRedis newProviderInstance () {\n//\t\tJRedis provider = null;\n//\t\ttry {\n//\t\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(this.host, this.port, this.db2, this.password.getBytes());\n//\t\t\tprovider = new JRedisService(connectionSpec, this.connectionCnt);\n//        }\n//        catch (ClientRuntimeException e) {\n//        \tLog.error(e.getLocalizedMessage());\n//        }\n//        return provider;\n//\t}\n//\t\n//\t// ------------------------------------------------------------------------\n//\t// The Tests\n//\t// ========================================================= JRedisClient\n//\t/**\n//\t * We define and run any additional, provider specific tests here.  The\n//\t * basic generally applicable JRedis interface method test are defined \n//\t * in the super class.\n//\t * \n//\t * Here we test Quit in a post test method to insure all tests have been\n//\t * completed.\n//\t */\n//\t// ------------------------------------------------------------------------\n//\t/**\n//\t * Test method for {@link org.jredis.ri.alphazero.JRedisSupport#auth(java.lang.String)}.\n//\t */\n//\t@AfterTest\n//\tpublic void testQuit() {\n//\t\tLog.log(\"TEST: QUIT command -- WARNING: using quit with JRedisService should not be allowed!\");\n//\t\ttry {\n//\t\t\tJRedis service = getProviderInstance();\n//\t\t\tservice.quit ();\n//\t\t} \n//\t\tcatch (Exception e) {\n//\t\t\tfail(\"QUIT\" + e);\n//\t\t}\n//\t}\n//}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/support/ConvertTest.java",
    "content": "/*\n * Copyright (c) 2009, Joubin Houshyar <alphazero at sensesay dot net>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *     \n *   * Redistributions in binary form must reproduce the above copyright\n *     notice, this list of conditions and the following disclaimer in the\n *     documentation and/or other materials provided with the distribution.\n *     \n *   * Neither the name of JRedis nor the names of its contributors may be used\n *     to endorse or promote products derived from this software without\n *     specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n * POSSIBILITY OF SUCH DAMAGE.\n * \n */ \n\npackage org.jredis.ri.alphazero.support;\n\n\n\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * @author Joubin Houshyar (alphazero@sensesay.net)\n * \n */\n@Test(suiteName=\"support-tests\")\npublic class ConvertTest {\n\t\n\t@Test\n\tpublic void testGetNaturalNumber() {\n\t\tLog.log(\"Testing bytes to number conversion ...\");\n\t\tbyte[] data = null;\n\t\t\n\t\t// test null\n\t\tboolean inputChecking;\n\t\tinputChecking = false;\n\t\ttry { \n\t\t\tConvert.toInt(data); \n\t\t}\n\t\tcatch (IllegalArgumentException e){ inputChecking = true;}\n\t\tfinally { assertTrue(inputChecking);}\n\t\t\n\t\t// test garbage data\n\t\tinputChecking = false;\n\t\tdata = \"2be?\".getBytes();\n\t\ttry { \n\t\t\tConvert.toInt(data); \n\t\t}\n\t\tcatch (IllegalArgumentException e){ inputChecking = true;}\n\t\tfinally { assertTrue(inputChecking);}\n\t\t\n\t\t// test big data\n\t\t// this is bigger than an bit \n\t\tinputChecking = false;\n\t\tdata = \"1234567890123456\".getBytes();\n\t\ttry { Convert.toInt(data); }\n\t\tcatch (IllegalArgumentException e){ inputChecking = true; }\n\t\tfinally { assertTrue(inputChecking);}\n\t\t\n\t\t{\n\t\t// test 0\n\t\tdata = \"0\".getBytes();\n\t\tint value = Convert.toInt(data);\n\t\tassertEquals(0, value);\n\t\t// test -0\n\t\tdata = \"-0\".getBytes();\n\t\t// test +0\n\t\tdata = \"+0\".getBytes();\n\t\tassertEquals(0, Convert.toInt(data));\n\t\t// test -00000\n\t\tdata = \"-0000\".getBytes();\n\t\tassertEquals(0, Convert.toInt(data));\n\t\t// test 00000\n\t\tdata = \"0000\".getBytes();\n\t\t// test +00000\n\t\tdata = \"+0000\".getBytes();\n\t\tassertEquals(0, Convert.toInt(data));\n\t\t// test 00001\n\t\tdata = \"00001\".getBytes();\n\t\tassertEquals(1, Convert.toInt(data));\n\t\t// test 0000100\n\t\tdata = \"0000100\".getBytes();\n\t\tassertEquals(100, Convert.toInt(data));\n\t\t// test 00001\n\t\tdata = \"+00001\".getBytes();\n\t\tassertEquals(1, Convert.toInt(data));\n\t\t// test +0000100\n\t\tdata = \"+0000100\".getBytes();\n\t\tassertEquals(100, Convert.toInt(data));\n\t\t// test 00001\n\t\tdata = \"-00001\".getBytes();\n\t\tassertEquals(-1, Convert.toInt(data));\n\t\t// test +0000100\n\t\tdata = \"-0000100\".getBytes();\n\t\tassertEquals(-100, Convert.toInt(data));\n\t\t// test 1\n\t\tdata = \"1\".getBytes();\n\t\tassertEquals(1, Convert.toInt(data));\n\t\t// test -1\n\t\tdata = \"-1\".getBytes();\n\t\tassertEquals(-1, Convert.toInt(data));\n\t\t// test +1\n\t\tdata = \"+1\".getBytes();\n\t\tassertEquals(1, Convert.toInt(data));\n\t\t\n\t\t// test $+1\n\t\tdata = \"$+1\".getBytes();\n\t\tassertEquals(1, Convert.toInt(data, 1, data.length-1));\n\t\t\n\t\t// test $-1\n\t\tdata = \"$-1\".getBytes();\n\t\tassertEquals(-1, Convert.toInt(data, 1, data.length-1));\n\t\t\n\t\t// test $+1GARBAGEDATA\n\t\tdata = \"$+1GARBAGEDATA\".getBytes();\n\t\tassertEquals(1, Convert.toInt(data, 1, 2));\n\t\t\n\t\t// test $-1GARAGEDATA\n\t\tdata = \"$-1GARAGEDATA\".getBytes();\n\t\tassertEquals(-1, Convert.toInt(data, 1, 2));\n\t\t\n\t\t// do a sensible range\n\t\tint java ;\n\t\tfor(int i=-50000; i<50000; i++) {\n\t\t\tdata = Convert.toBytes(i);\n\t\t\tjava = Integer.parseInt(new String(data), 10);\n\t\t\tassertEquals (java, Convert.toInt(data));\n\t\t}\n\t\t\n\t\t// now lets go to the limit\n\t\t//\n\t\tdata = Integer.toString(Integer.MAX_VALUE).getBytes();\n\t\tassertEquals(Integer.MAX_VALUE, Convert.toInt(data, 0, data.length));\n\n\t\tdata = Integer.toString(Integer.MIN_VALUE).getBytes();\n\t\tassertEquals(Integer.MIN_VALUE, Convert.toInt(data, 0, data.length));\n\t\t\n\t\t}\n\t\t\n\t\t// now lets do the longs\n\n\t\t{\n\t\t// test big data\n\t\t// this is bigger than an bit  but fine for a long\n\t\tinputChecking = false;\n\t\tdata = \"1234567890123456\".getBytes();\n\t\tassertEquals (1234567890123456L, Convert.toLong(data));\n\t\t\n\t\t// test 0\n\t\tdata = \"0\".getBytes();\n\t\tlong value = Convert.toLong(data);\n\t\tassertEquals(0, value);\n\t\t// test -0\n\t\tdata = \"-0\".getBytes();\n\t\t// test +0\n\t\tdata = \"+0\".getBytes();\n\t\tassertEquals(0, Convert.toLong(data));\n\t\t// test -00000\n\t\tdata = \"-0000\".getBytes();\n\t\tassertEquals(0, Convert.toLong(data));\n\t\t// test 00000\n\t\tdata = \"0000\".getBytes();\n\t\t// test +00000\n\t\tdata = \"+0000\".getBytes();\n\t\tassertEquals(0, Convert.toLong(data));\n\t\t// test 00001\n\t\tdata = \"00001\".getBytes();\n\t\tassertEquals(1, Convert.toLong(data));\n\t\t// test 0000100\n\t\tdata = \"0000100\".getBytes();\n\t\tassertEquals(100, Convert.toLong(data));\n\t\t// test 00001\n\t\tdata = \"+00001\".getBytes();\n\t\tassertEquals(1, Convert.toLong(data));\n\t\t// test +0000100\n\t\tdata = \"+0000100\".getBytes();\n\t\tassertEquals(100, Convert.toLong(data));\n\t\t// test 00001\n\t\tdata = \"-00001\".getBytes();\n\t\tassertEquals(-1, Convert.toLong(data));\n\t\t// test +0000100\n\t\tdata = \"-0000100\".getBytes();\n\t\tassertEquals(-100, Convert.toLong(data));\n\t\t// test 1\n\t\tdata = \"1\".getBytes();\n\t\tassertEquals(1, Convert.toLong(data));\n\t\t// test -1\n\t\tdata = \"-1\".getBytes();\n\t\tassertEquals(-1, Convert.toLong(data));\n\t\t// test +1\n\t\tdata = \"+1\".getBytes();\n\t\tassertEquals(1, Convert.toLong(data));\n\t\t\n\t\t// test $+1\n\t\tdata = \"$+1\".getBytes();\n\t\tassertEquals(1, Convert.toLong(data, 1, data.length-1));\n\t\t\n\t\t// test $-1\n\t\tdata = \"$-1\".getBytes();\n\t\tassertEquals(-1, Convert.toLong(data, 1, data.length-1));\n\t\t\n\t\t// test $+1GARBAGEDATA\n\t\tdata = \"$+1GARBAGEDATA\".getBytes();\n\t\tassertEquals(1, Convert.toLong(data, 1, 2));\n\t\t\n\t\t// test $-1GARAGEDATA\n\t\tdata = \"$-1GARAGEDATA\".getBytes();\n\t\tassertEquals(-1, Convert.toLong(data, 1, 2));\n\t\t\n\t\t// now lets go to the limit\n\t\t//\n\t\tdata = Long.toString(Long.MAX_VALUE).getBytes();\n\t\tassertEquals(Long.MAX_VALUE, Convert.toLong(data, 0, data.length));\n\n\t\tdata = Long.toString(Long.MIN_VALUE).getBytes();\n\t\tassertEquals(Long.MIN_VALUE, Convert.toLong(data, 0, data.length));\n\t\t\n\t\t}  // just for scoping  ..\n\t}\n\t/**\n\t * Test method for {@link org.jredis.alphazero.util.util.S27.jredis_deprecated.client.util.Convert#toBytes(int, boolean)}.\n\t */\n\t@Test\n\tpublic void testToBytes() {\n\t\tLog.log(\"Testing number to bytes conversion ...\");\n\t\tbyte[] javadata = null;\n\t\tbyte[] data = null;\n\n\t\t// test MIN \n\t\tint n;\n\t\tn=Integer.MIN_VALUE;\n\t\tjavadata = Integer.toString(n).getBytes();\n\t\tdata = Convert.toBytes(n);\n\t\tassertEquals (data.length, javadata.length, \"buffer length\");\n\t\tfor(int j=0; j<data.length;j++)\n\t\t\tassertEquals(data[j], javadata[j], \"for <\"+n+\"> byte @ [\"+j+\"]\");\n\n\t\t// test MAX\n\t\tn=Integer.MAX_VALUE;\n\t\tjavadata = Integer.toString(n).getBytes();\n\t\tdata = Convert.toBytes(n);\n\t\tassertEquals (data.length, javadata.length, \"buffer length\");\n\t\tfor(int j=0; j<data.length;j++)\n\t\t\tassertEquals(data[j], javadata[j], \"for <\"+n+\"> byte @ [\"+j+\"]\");\n\n\t\t// test a bit smaller than Convert.INT_N_65535\n\t\tn=Convert.INT_N_65535 - 444;\n\t\tjavadata = Integer.toString(n).getBytes();\n\t\tdata = Convert.toBytes(n);\n\t\tassertEquals (data.length, javadata.length, \"buffer length\");\n\t\tfor(int j=0; j<data.length;j++)\n\t\t\tassertEquals(data[j], javadata[j], \"for <\"+n+\"> byte @ [\"+j+\"]\");\n\n\t\t// test a bit larger than Convert.INT_P_65535\n\t\tn=Convert.INT_P_65535 + 444;\n\t\tjavadata = Integer.toString(n).getBytes();\n\t\tdata = Convert.toBytes(n);\n\t\tassertEquals (javadata.length, data.length, \"buffer length\");\n\t\tfor(int j=0; j<data.length;j++)\n\t\t\tassertEquals( data[j], javadata[j], \"for <\"+n+\"> byte @ [\"+j+\"]\");\n\n\t\t// test the exact range range\n\t\tfor(int i=Convert.INT_N_65535; i<Convert.INT_P_65535; i++){\n\t\t\t//\t\tfor(int i=Integer.MIN_VALUE; i<Integer.MAX_VALUE; i++){\n\t\t\tjavadata = Integer.toString(i).getBytes();\n\t\t\tdata = Convert.toBytes(i);\n\t\t\tassertEquals (data.length, javadata.length, \"buffer length\" );\n\t\t\tfor(int j=0; j<data.length;j++)\n\t\t\t\tassertEquals( data[j], javadata[j], \"for <\"+i+\"> byte @ [\"+j+\"]\");\n\t\t}\t\t\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/java/org/jredis/ri/alphazero/support/GZipTest.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.alphazero.support;\n\nimport java.nio.charset.Charset;\nimport java.util.Random;\nimport org.testng.annotations.*;\nimport org.testng.Assert;\nimport static org.jredis.ri.alphazero.support.GZip.*;\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Aug 24, 2009\n * @since   alpha.0\n * \n */\n\n@Test(suiteName=\"support-tests\")\npublic class GZipTest {\n\tpublic final static Charset SUPPORTED_CHARSET = Charset.forName (\"UTF-8\");\n\n\t@Test\n\tpublic void testCompression() {\n\t\tLog.log(\"Testing compress/decompress of 1000 random 24KB strings ...\");\n    \tint cnt = 1000;\n    \tint size = 1024 * 24;\n    \tfor(int i=0; i<cnt; i++){\n    \t\tString randomString = getRandomString(size);\n    \t\tbyte[] stringBytes = randomString.getBytes();\n    \t\tbyte[] compressed = compress(stringBytes);\n    \t\tbyte[] decompressed = decompress(compressed);\n    \t\tAssert.assertEquals(decompressed, stringBytes);\n    \t}\n\t}\n\t/*\n\t * OK, so this is a reduandant hack -- the Bench pom states that it is dependent\n\t * on RI and API, but here we are testing a RI class so Bench isn't installed\n\t * yet so we are duplicating the methods and violating DRY. (Sue me).\n\t */\n\t// ------------------------------------------------------------------------\n\t// Static properties\n\t// ------------------------------------------------------------------------\n\t/** \n\t * Random generator used for Util random functions, \n\t * instantiated using {@link System#currentTimeMillis()} as seed\n\t */\n\tfinal static Random \t\trandom = new Random(System.currentTimeMillis());\n\t\n\t// ------------------------------------------------------------------------\n\t// Static methods\n\t// ------------------------------------------------------------------------\n\tstatic \n\tpublic String getRandomString (int size) {\n\t\tStringBuilder builder = new  StringBuilder(size);\n\t\tfor(int i = 0; i<size; i++){\n\t\t\tchar c = (char) (random.nextInt(126-33) + 33);\n\t\t\tbuilder.append(c);\n\t\t}\n\t\treturn builder.toString();\n\t}\n}\n"
  },
  {
    "path": "core/ri/src/test/resources/log4j.properties",
    "content": "# Configure logging for testing\nlog4j.rootLogger=DEBUG, stdout, logfile\n\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.layout=org.apache.log4j.PatternLayout\nlog4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c] - %m%n\n\nlog4j.appender.logfile=org.apache.log4j.RollingFileAppender\nlog4j.appender.logfile.File=target/log/jredis-ri-test.log\nlog4j.appender.logfile.MaxFileSize=512KB\n\nlog4j.appender.logfile.MaxBackupIndex=1\n\n# Pattern to output: date priority [category] - message\nlog4j.appender.logfile.layout=org.apache.log4j.PatternLayout\nlog4j.appender.logfile.layout.ConversionPattern=%d %-5p [%c] - %m%n\n"
  },
  {
    "path": "documentation/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "documentation/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "documentation/design/notes/api/jredis-api.txt",
    "content": "[musings .. nothing structured yet]\n--\n\nThe Redis 'list' command names are a bit confusing.  Unlike 'set' commands, which consistently begin with 's', the 'list' command set includes variations beginning with 'r'.  Also, unlike 'set', which has intuitively consistent 'set' semantics, the redis 'list' is either a stack or list, when using one of the r/l<op> commands.  \n\nThe client libraries seem to approach this in various ways.  Python treats all ops on the list extremeties as stack semantics (push and pop) defaulting to the redis list's 'tail' push and pop.  Ruby also usses push and pop with explicit <x>_tail or <x>_head articulation.  The Erlang client uses a direct mapping, as with JRedis, as of now.\n\nI personally find the redis push/pop commands confusing.  Perhaps this is due to mild dyslexia, but the thought occurs that others will share in this difficulty.  In designing JRedis, after initial experiments with java like semantics (redis.addToSet(...), etc.) a decision was made to use a one to one mapping for the api's end-user methods.  But the list's r/l ambiguity seems to detract from the effectiveness of the api.\n\nSo, in line with maintaining a close analog with Redis command set, and to address semantic ambiguities, JRedis api methods will change as follows:\n\nAll Redis 'string' remain the same.  The 'map' like operations (set, get, setnx, and mget) are fairly self effident.  Perhaps setnx is a candidate for further consideration, but redis.get(key, value) is as obvious as it is going to get.\n\nFor the remaning types, JRedis will adopt a uniform naming convention, with 'l' commands mapping to Redis 'list' operations, and 's' commands to 'set'. \n\nSet commands are already consistent, beginning with s<x>.  SINTER and SINTERSTORE are a bit cryptic for the novice, but there are no issues of ambiguity here.  And potentially will have SJOIN and SJOINSTORE as some point and everything is fine.\n\nList commands will be modified so they all begin with 'l'.  \nStack semantic ops on 'lists' will be just that:\n\nlpush is a push: 'head' of the list.  (Its perfectly clear what it means - the natural place things are pushed is the head.)  \n\nSo:  redis.lpush (list, \"go to the head of the class\");\n\n\nSame with lpop:  List Pop.  Pop the first element of the list.\n\nredis.lpop () // returns the poped head of the list\n\nrpush is 'adding an item to a list'.  Its an append but 'add' is also fairly clear:  the natural place you add things to a 'list' is the the 'tail'.  (And Redis does not support 'insert' so its a non issue for now.)  Either lappend or ladd will be fairly obvious to the end user.   \n\n... \n\nOne version:\n\n[we'll skip over commands that won't change, such as dbsize, randomkey, etc.]\n\n<Map>\t=> <STRING> subset:\n\nset \t=> SET\nget\t=> GET\nmget\t=> MGET\nsetnew\t=> SETNX\n\n<Num>\nincr\t=> INCR\ndecr\t=> DECR\nincrby\t=> INCRBY\ndecrby\t=> DECRBY\n\n\n<List>\t=> <LIST>\npush\npop\nappend\ntake\nrange\ntrim\nindexof\nmodify\nremove\n\n<Set>\t=> <SET>\nadd\nremove\ncard\nismember\nmembers\n\n...\n\nAnother version:\n\nlset, lget, mget, setnx\nincr, decr, incrby, decrby\nlpush, lpop, ladd, ltake, lrange, ltrim, indexof, lset, lrem\nsadd, srem, scard, sismember, smembers\n \n\n"
  },
  {
    "path": "examples/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "examples/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "examples/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<!-- parent -->\n\t<parent>\n\t\t<groupId>org.jredis</groupId>\n\t\t<artifactId>jredis</artifactId>\n\t\t<version>a.0-SNAPSHOT</version>\n\t</parent>\n\n\t<!-- production | jar -->\n\t<name>JRedis - EXAMPLES</name>\n\t<groupId>org.jredis</groupId>\n\t<artifactId>jredis-examples</artifactId>\n\t<version>a.0-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.jredis</groupId>\n\t\t\t<artifactId>jredis-core-all</artifactId>\n\t\t\t<version>a.0-SNAPSHOT</version>\n\t\t</dependency>\n\t</dependencies>\n\t<!-- ========================================= build -->\n\t<build>\n\t\t<plugins>\n\t\t\t<!-- we'll also build a source jar -->\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-assembly-plugin</artifactId>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>simple-install</id>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>attached</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t\t<configuration>\n\t\t\t\t\t<descriptorRefs>\n\t\t\t\t\t\t<descriptorRef>jar-with-dependencies</descriptorRef>\n\t\t\t\t\t</descriptorRefs>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n</project>\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/HelloAgain.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.JRedis;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.ri.alphazero.JRedisClient;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport static org.jredis.ri.alphazero.support.DefaultCodec.*;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Apr 15, 2009\n * @since   alpha.0\n * \n */\n\npublic class HelloAgain {\n\tpublic static final String key = \"jredis::examples::HelloAgain::message\";\n\tpublic static final byte[] bkey = key.getBytes();\n\tpublic static void main(String[] args) {\n\t\tString password = \"jredis\";\n\t\tif(args.length > 0) password  = args[0];\n\t\tnew HelloAgain().run(password);\n\t}\n\n\tprivate void run(String password) {\n\t\ttry {\n\t\t\tConnectionSpec spec = DefaultConnectionSpec.newSpec().setCredentials(password);\n\t\t\tJRedis\tjredis = new JRedisClient(spec);\n\t\t\tjredis.ping();\n\t\t\t\n\t\t\tif(!jredis.exists(bkey)) {\n\t\t\t\tjredis.set(bkey, \"Hello Again!\");\n\t\t\t\tSystem.out.format(\"Hello!  You should run me again!\\n\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\tString msg = toStr ( jredis.get(bkey) );\n\t\t\t\tSystem.out.format(\"%s\\n\", msg);\n\t\t\t}\n\t\t\tjredis.quit();\n\t\t}\n\t\tcatch (RedisException e){\n\t\t\tif (e.getCommand()==Command.PING){\n\t\t\t\tSystem.out.format(\"I'll need that password!  Try again with password as command line arg for this program.\\n\");\n\t\t\t}\n\t\t}\n\t\tcatch (ProviderException e){\n\t\t\tSystem.out.format(\"Oh no, an 'un-documented feature':  %s\\nKindly report it.\", e.getMessage());\n\t\t}\n\t\tcatch (ClientRuntimeException e){\n\t\t\tSystem.out.format(\"%s\\n\", e.getMessage());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/PipelineInAction.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples;\n\nimport static org.jredis.connector.Connection.Socket.Property.SO_RCVBUF;\nimport static org.jredis.connector.Connection.Socket.Property.SO_SNDBUF;\nimport static org.jredis.ri.alphazero.support.DefaultCodec.toLong;\nimport static org.jredis.ri.alphazero.support.DefaultCodec.toStr;\nimport java.util.Random;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.JRedisFuture;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.bench.Util;\nimport org.jredis.bench.Util.Timer;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.alphazero.JRedisPipeline;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * Pipelines are an order of magnitude faster than the request/reply connectors.\n * Get a sense of how much faster it is.\n * \n * <p>use JVM flags -server -Xms512m -Xmx2560m for better results (adjust your\n * mem settings per your box's limits.)\n *  \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 5, 2009\n * @since   alpha.0\n * \n */\n\npublic class PipelineInAction {\n\t@SuppressWarnings(\"boxing\")\n\tpublic static void main (String[] args) {\n    \tfinal ConnectionSpec spec = DefaultConnectionSpec.newSpec();\n    \tspec.setCredentials(\"jredis\".getBytes());\n    \tspec.setDatabase(13);\n    \tspec.setSocketProperty(SO_RCVBUF, 1024 * 24);\n    \tspec.setSocketProperty(SO_SNDBUF, 1024 * 24);\n    \t\n    \tusingSynchSemantics(spec);\n    \tfinal boolean forever = true;\n    \t\n    \trunJRedisPipelineSET (spec, 100000, 3, forever);\n\t}\n    /**\n     * @param spec\n     */\n    @SuppressWarnings(\"boxing\")\n\tprivate static void usingSynchSemantics (ConnectionSpec spec) {\n    \tJRedisPipeline pipeline = new JRedisPipeline(spec);\n    \ttry {\n    \t\tlong start = System.currentTimeMillis();\n\t        pipeline.ping();\n\t        pipeline.flushall();\n\t        String cntrKey = \"my-cntr\";\n\t        \n\t        Random rand = new Random();\n\t        byte[] data = new byte[8];\n\t        for(int i=0; i<100000; i++)\n\t        \tpipeline.incr(cntrKey);\n\t        \n\t        long cntr = toLong (pipeline.sync().get(cntrKey));\n\t        \n\t        for(int i=0; i<100000; i++){\n\t        \trand.nextBytes(data);\n\t        \tpipeline.set(\"random:\"+i, \"value:\" + rand.nextInt());\n\t        }\n\t        String randomVal = toStr (pipeline.sync().get(\"random:\"+999));\n    \t\tSystem.out.format (\"end using sync() = %d msec\\n\", System.currentTimeMillis() - start);\n\t        \n\t        System.out.format(\"%s => %d\\n\", cntrKey, cntr);\n\t        System.out.format(\"%s => %s\\n\", \"random:\"+999, randomVal);\n\t        \n        }\n        catch (RedisException e) {\n        \tLog.problem(\"RedisException: \" + e);\n        }\n        finally{\n        \tpipeline.sync().quit();\n        }\n\n    }\n\t/**\n     * pipelines SET reqCnt times and then waits on response of the last INCR.\n     * If foverever flag is true, will do so forever.  Each cycle prints out timing stats.\n     * @param spec\n     * @param reqCnt\n     * @param forever\n     */\n    @SuppressWarnings({ \"unused\", \"boxing\" })\n    private static void runJRedisPipelineGET (ConnectionSpec spec, int reqCnt, int size, boolean forever) {\n    \tlong totTime = 0;\n    \tlong avgRespTime = 0;\n    \tfloat avgThroughput = 0;\n    \tlong iters = 0;\n    \tJRedisFuture pipeline = new JRedisPipeline(spec);\n    \ttry {\n    \t\tString key = \"pipeKey\";\n    \t\tbyte[] data = new byte[size];\n    \t\t(new Random()).nextBytes(data);\n\t\t\tpipeline.del(key);\n\t\t\tpipeline.set(key, data);\n\t\t\t\n    \t\tdo {\n\t    \t\tint cnt = 0;\n\t    \t\tUtil.Timer timer = Timer.startNewTimer();\n\t    \t\tFuture<byte[]> futureBytes = null;\n\t    \t\twhile(cnt < reqCnt){\n\t    \t\t\tfutureBytes = pipeline.get(key);\n\t    \t\t\tcnt++;\n\t    \t\t}\n\t    \t\tlong reqDoneTime = timer.mark();\n\t    \t\tassert futureBytes != null;\n\t\t\t\t@SuppressWarnings(\"null\")\n\t\t\t\tbyte[] value = futureBytes.get();\n\t    \t\tlong respDoneTime = timer.mark();\n//\t\t\t\tSystem.out.format(\"JRedisPipeline: %d GETs invoked   @ %5d  (%.2f ops/s)\\n\", cnt, reqDoneTime, timer.opsPerSecAtDelta(cnt, reqDoneTime));\n\t\t\t\tfloat throughput = timer.opsPerSecAtMark(cnt);\n//\t\t\t\tSystem.out.format(\"JRedisPipeline: %d GETs completed @ %5d  (%.2f ops/s) [%d msecs to comp] \\n\", cnt, timer.deltaAtMark(), throughput, respDoneTime-reqDoneTime);\n\t\t\t\tif(iters > 0){\n\t\t\t\t\ttotTime += respDoneTime;\n\t\t\t\t\tavgRespTime = (totTime) / iters;\n\t\t\t\t\tavgThroughput =(float)( reqCnt * 1000) / (float) avgRespTime;\n\t\t\t\t\tSystem.out.format(\"JRedisPipeline: %d GETs [%d bytes/GET] average response time @ %dms (%.2f ops/s) last: %dms\\n\", cnt, data.length, avgRespTime, avgThroughput, respDoneTime);\n//\t\t\t\t\tAssert.isEquivalent(data, value);\n\t\t\t\t}\n\t\t\t\titers ++;\n//\t\t\t\tSystem.out.println ();\n    \t\t} while(forever);\n\n    \t\tpipeline.quit();\n        }\n        catch (ProviderException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n    }\n    @SuppressWarnings({ \"unused\", \"boxing\" })\n    private static void runJRedisPipelinePING (ConnectionSpec spec, int reqCnt, int size, boolean forever) {\n    \tlong totTime = 0;\n    \tlong avgRespTime = 0;\n    \tfloat avgThroughput = 0;\n    \tlong iters = 0;\n    \tJRedisFuture pipeline = new JRedisPipeline(spec);\n    \ttry {\n    \t\tdo {\n\t    \t\tint cnt = 0;\n\t    \t\tUtil.Timer timer = Timer.startNewTimer();\n\t    \t\tFuture<ResponseStatus> futureStat = null;\n\t    \t\twhile(cnt < reqCnt){\n\t    \t\t\tfutureStat = pipeline.ping();\n\t    \t\t\tcnt++;\n\t    \t\t}\n\t    \t\tlong reqDoneTime = timer.mark();\n\t    \t\tassert futureStat != null;\n\t\t\t\t@SuppressWarnings(\"null\")\n\t\t\t\tResponseStatus rstat = futureStat.get();\n\t    \t\tlong respDoneTime = timer.mark();\n//\t\t\t\tSystem.out.format(\"JRedisPipeline: %d PINGs invoked   @ %5d  (%.2f ops/s)\\n\", cnt, reqDoneTime, timer.opsPerSecAtDelta(cnt, reqDoneTime));\n\t\t\t\tfloat throughput = timer.opsPerSecAtMark(cnt);\n//\t\t\t\tSystem.out.format(\"JRedisPipeline: %d PINGs completed @ %5d  (%.2f ops/s) [%d msecs to comp] \\n\", cnt, timer.deltaAtMark(), throughput, respDoneTime-reqDoneTime);\n\t\t\t\tif(iters > 0){\n\t\t\t\t\ttotTime += reqDoneTime;\n\t\t\t\t\tavgRespTime = (totTime) / iters;\n\t\t\t\t\tavgThroughput =(float)( reqCnt * 1000) / (float) avgRespTime;\n\t\t\t\t\tSystem.out.print(\"\\r\");\n\t\t\t\t\tSystem.out.format(\"JRedisPipeline: %d PINGs average response time @ %dms (%.2f ops/s)\", cnt, avgRespTime, avgThroughput);\n\t\t\t\t}\n\t\t\t\titers ++;\n//\t\t\t\tSystem.out.println ();\n    \t\t} while(forever);\n\n    \t\tpipeline.quit();\n        }\n        catch (ProviderException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n    }\n    @SuppressWarnings(\"boxing\")\n\tprivate static void runJRedisPipelineLPUSH (ConnectionSpec spec, int reqCnt, int size, boolean forever) {\n    \tJRedisFuture pipeline = new JRedisPipeline(spec);\n    \tlong totTime = 0;\n    \tlong avgRespTime = 0;\n    \tfloat avgThroughput = 0;\n    \tlong iters = 0;\n    \ttry {\n    \t\tString key = \"pipeKey\";\n    \t\tbyte[] data = new byte[size];\n    \t\t(new Random()).nextBytes(data);\n\t\t\tFuture<Long> futureLong = pipeline.del(key);\n\t\t\tfutureLong.get();\n    \t\tdo {\n\t    \t\tint cnt = 0;\n\t    \t\tUtil.Timer timer = Timer.startNewTimer();\n\t    \t\tFuture<ResponseStatus> futureStat = null;\n\t    \t\twhile(cnt < reqCnt){\n\t    \t\t\tfutureLong = pipeline.lpush(key, data);\n\t    \t\t\tcnt++;\n\t    \t\t}\n\t    \t\tlong reqDoneTime = timer.mark();\n\t    \t\tassert futureStat != null;\n\t    \t\t@SuppressWarnings({ \"null\", \"unused\" })\n\t\t\t\tResponseStatus rstat = futureStat.get();\n\t    \t\tlong respDoneTime = timer.mark();\n\t\t\t\tSystem.out.format(\"JRedisPipeline: %d LPUSHs invoked   @ %5d  (%.2f ops/s)\\n\", cnt, reqDoneTime, timer.opsPerSecAtDelta(cnt, reqDoneTime));\n\t\t\t\tSystem.out.format(\"JRedisPipeline: %d LPUSHs completed @ %5d  (%.2f ops/s) [%d msecs to comp] \\n\", cnt, timer.deltaAtMark(), timer.opsPerSecAtMark(cnt), respDoneTime-reqDoneTime);\n\t\t\t\tif(iters > 0){\n\t\t\t\t\ttotTime += reqDoneTime;\n\t\t\t\t\tavgRespTime = (totTime) / iters;\n\t\t\t\t\tavgThroughput =(float)( reqCnt * 1000) / (float) avgRespTime;\n\t\t\t\t\tSystem.out.format(\"JRedisPipeline: %d LPUSHs average response time @ %dms (%.2f ops/s) \\n\", cnt, avgRespTime, avgThroughput);\n\t\t\t\t}\n\t\t\t\titers ++;\n\t\t\t\tSystem.out.println ();\n    \t\t} while(forever);\n\n    \t\tpipeline.quit();\n        }\n        catch (ProviderException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n    }\n   \n    /**\n     * pipelines SET reqCnt times and then waits on response of the last INCR.\n     * If foverever flag is true, will do so forever.  Each cycle prints out timing stats.\n     * @param spec\n     * @param reqCnt\n     * @param forever\n     */\n    @SuppressWarnings(\"boxing\")\n\tprivate static void runJRedisPipelineSET (ConnectionSpec spec, int reqCnt, int size, boolean forever) {\n    \tJRedisFuture pipeline = new JRedisPipeline(spec);\n    \tlong totTime = 0;\n    \tlong avgRespTime = 0;\n    \tfloat avgThroughput = 0;\n    \tlong iters = 0;\n    \ttry {\n    \t\tString key = \"pipeKey\";\n    \t\tbyte[] data = new byte[size];\n    \t\t(new Random()).nextBytes(data);\n\t\t\tFuture<Long> futureLong = pipeline.del(key);\n\t\t\tfutureLong.get();\n    \t\tdo {\n\t    \t\tint cnt = 0;\n\t    \t\tUtil.Timer timer = Timer.startNewTimer();\n\t    \t\tFuture<ResponseStatus> futureStat = null;\n\t    \t\twhile(cnt < reqCnt){\n\t    \t\t\tfutureStat = pipeline.set(key, data);\n\t    \t\t\tcnt++;\n\t    \t\t}\n\t    \t\tassert futureStat != null;\n\t    \t\t@SuppressWarnings({ \"null\", \"unused\" })\n\t\t\t\tResponseStatus rstat = futureStat.get();\n\t    \t\tlong respDoneTime = timer.mark();\n\t\t\t\tif(iters > 0){\n\t\t\t\t\ttotTime += respDoneTime;\n\t\t\t\t\tavgRespTime = (totTime) / iters;\n\t\t\t\t\tavgThroughput =(float)( reqCnt * 1000) / (float) avgRespTime;\n\t\t\t\t\tSystem.out.format(\"JRedisPipeline: %d SETs [%d bytes/GET] average response time @ %dms (%.2f ops/s) \\n\", cnt, data.length, avgRespTime, avgThroughput);\n\t\t\t\t}\n\t\t\t\titers ++;\n    \t\t} while(forever);\n\n    \t\tpipeline.quit();\n        }\n        catch (ProviderException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n    }\n    /**\n     * pipelines INCRs reqCnt times and then waits on response of the last INCR.\n     * If foverever flag is true, will do so forever.  Each cycle prints out timing stats.\n     * @param spec\n     * @param reqCnt\n     * @param forever\n     */\n    @SuppressWarnings(\"boxing\")\n\tprivate static void runJRedisPipelineINCR (ConnectionSpec spec, int reqCnt, int size, boolean forever) {\n    \tJRedisFuture pipeline = new JRedisPipeline(spec);\n    \tlong totTime = 0;\n    \tlong avgRespTime = 0;\n    \tfloat avgThroughput = 0;\n    \tlong iters = 0;\n    \ttry {\n    \t\tString key = \"pipeCounter\";\n\t\t\tFuture<Long> futureDelCnt = pipeline.del(key);\n\t\t\tfutureDelCnt.get();\n    \t\tdo {\n\t    \t\tint cnt = 0;\n\t    \t\tUtil.Timer timer = Timer.startNewTimer();\n\t    \t\tFuture<Long> futureLong = null;\n\t    \t\twhile(cnt < reqCnt){\n\t    \t\t\tfutureLong = pipeline.incr(key);\n\t    \t\t\tcnt++;\n\t    \t\t}\n\t    \t\tlong reqDoneTime = timer.mark();\n\t    \t\tassert futureLong != null;\n\t\t\t\t@SuppressWarnings(\"null\")\n\t\t\t\tlong counter = futureLong.get();\n\t    \t\tlong respDoneTime = timer.mark();\n\t\t\t\tSystem.out.format(\"JRedisPipeline: %d INCRs invoked   @ %5d  (%.2f ops/s)\\n\", cnt, reqDoneTime, timer.opsPerSecAtDelta(cnt, reqDoneTime));\n\t\t\t\tSystem.out.format(\"JRedisPipeline: %d INCRs completed @ %5d  (%.2f ops/s) [%d msecs to comp] \\n\", cnt, timer.deltaAtMark(), timer.opsPerSecAtMark(cnt), respDoneTime-reqDoneTime);\n\t\t\t\tSystem.out.format (\"counter is now: %d\\n\\n\", counter);\n\t\t\t\tif(iters > 0){\n\t\t\t\t\ttotTime += reqDoneTime;\n\t\t\t\t\tavgRespTime = (totTime) / iters;\n\t\t\t\t\tavgThroughput =(float)( reqCnt * 1000) / (float) avgRespTime;\n\t\t\t\t\tSystem.out.format(\"JRedisPipeline: %d INCRs average response time @ %dms (%.2f ops/s) \\n\", cnt, avgRespTime, avgThroughput);\n\t\t\t\t}\n\t\t\t\titers ++;\n\t\t\t\tSystem.out.println ();\n    \t\t} while(forever);\n\n    \t\tpipeline.quit();\n        }\n        catch (ProviderException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/UsingConnectionSpec.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples;\n\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_BANDWIDTH;\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_CONN_TIME;\nimport static org.jredis.connector.Connection.Socket.Property.SO_PREF_LATENCY;\nimport static org.jredis.connector.Connection.Socket.Property.SO_RCVBUF;\nimport static org.jredis.connector.Connection.Socket.Property.SO_SNDBUF;\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\nimport org.jredis.RedisException;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisClient;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n/**\n * Illustrates using the {@link ConnectionSpec} as a parameter when creating the {@link JRedisClient}.\n * @author  Joubin (alphazero@sensesay.net)\n * @see ConnectionSpec\n */\n\npublic class UsingConnectionSpec {\n\tpublic static void main (String[] args) {\n\t    exampleUsingDefaultConnectionSpec ();\n\t    exampleUsingCustomTCPSettings();\n    }\n\n\t/**\n     * Alright, so here we're going to fiddle with the various TCP settings that the JRedisClient\n     * will use in its connection.  \n     */\n    @SuppressWarnings(\"boxing\")\n\tprivate static void exampleUsingCustomTCPSettings () {\n    \t// try our own values for various flags and properties\n    \t//\n    \t{\n    \t\t// Note that if your localhost:6379 redis server expects a password\n    \t\t// this will fail\n\t    \ttry {\n\t    \t\tString password = \"jredis\";\n\t    \t\tInetAddress address = InetAddress.getLocalHost();\n\t    \t\t\n\t    \t\t// 1 - get the default connection spec\n\t    \t\t//\n\t\t    \tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec();\n\t\t    \t\n\t\t    \t// 2 - customize it\n\t\t    \t// here we're demonstrating the full set of parameters -- obviously you can just set what you need\n\t\t    \t// but DO NOTE that the SO_PREF_XXX properties of TCP sockets must be defined as a set.  See\n\t\t    \t// ConnectionSpec for javadoc details.\n\t\t    \t//\n\t\t    \t// Here we are spec'ing a connection that is NOT kept alive, and obviously is really keen on making sure\n\t\t    \t// we connect as fast as possible.  This is a good connectionspec for disposable JRedisClients that are used\n\t\t    \t// to issue a few commands and then discarded.  We're minimizing the connection overhead cost.\n\t\t    \t\n\t\t    \tconnectionSpec\n\t\t    \t\t// to be or not to be -- you decide\n\t\t    \t\t//\n\t\t    \t\t.setSocketFlag(Connection.Socket.Flag.SO_KEEP_ALIVE, Boolean.FALSE)\t\t\t\t// DO NOT keep socket alive\n\n\t\t    \t\t// connect retries on connection breaks\n\t\t    \t\t//\n\t\t    \t\t.setReconnectCnt(2) \t\t\t\t\t\t\t\t\t\t// reconnect attempts set to 2 retries\n\n\t\t    \t\t// TCP algorithm preferences\n\t\t    \t\t//\n\t\t    \t\t.setSocketProperty(SO_PREF_CONN_TIME, 0) \t// connection time is highester pref\n\t\t    \t\t.setSocketProperty(SO_PREF_LATENCY, 1)\t\t// latency is 2nd pref\n\t\t    \t\t.setSocketProperty(SO_PREF_BANDWIDTH, 2)\t// bandwidth is 3rd pref\n\t\t    \t\n\t\t    \t\t// TCP buffer sizes -- more than likely your platform's default settings are quite large\n\t\t    \t\t// but if you are itching to try your own settings, please do.  Remember:  connections\n\t\t    \t\t// will use whatever is the larger value: you OS's TCP buffer sizes or your ConnectionSpecs\n\t\t    \t\t// so you can NOT use these settings to shrink the SND and RCV buffer sizes.\n\t\t    \t\t//\n\t\t    \t\t.setSocketProperty(SO_RCVBUF, 1024 * 128)  // set RCV buffer to 128KB\n\t\t    \t\t.setSocketProperty(SO_SNDBUF, 1024 * 128) // set SND buffer to 128KB\n\t\t    \t\t\n\t\t    \t\t// obviously we can still set the basic props as well ..\n\t\t    \t\t//\n\t\t    \t\t.setAddress(address)\n\t\t    \t\t.setCredentials(password.getBytes())\n\t\t    \t\t.setDatabase(13);\n\t\t    \t\n\t\t    \t// finally - use it to create the JRedisClient instance\n\t\t    \t//\n\t\t    \tJRedisClient jredis = new JRedisClient(connectionSpec);\n\t\t        jredis.ping();\n\t\t        Log.log(\"Sweet success -- we're connected using custom TCP settings\");\n\t        }\n\t        catch (RedisException e) {\n\t\t        Log.error(\"Failed to connect to Redis using JRedisClient custom ConnectionSpec -- password perhaps? => \" + e.getLocalizedMessage());\n\t        }\n            catch (UnknownHostException e) {\n            \tLog.error(\"Unknownhost: \" + e.getLocalizedMessage());\n            }\n    \t}\n    }\n\n\t/**\n     * On the first try, We're not really using the {@link ConnectionSpec} here, but it shows how to use\n     * the {@link JRedisClient#JRedisClient(ConnectionSpec)} constructor.  Defaults are\n     * localhost, 6379, and no password, and database 0.\n     * <p>\n     * Then we try setting the basic {@link ConnectionSpec} properties:  host, port, password, and database.\n     */\n    @SuppressWarnings(\"boxing\")\n\tprivate static void exampleUsingDefaultConnectionSpec () {\n    \t\n    \t// 1st example: using defaults\n    \t// if your server expects a AUTH password, this will fail so see next block\n    \t{\n    \t\t// Note that if your localhost:6379 redis server expects a password\n    \t\t// this will fail\n\t    \tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec();\n\t    \tJRedisClient jredis = new JRedisClient(connectionSpec);\n\t    \ttry {\n\t\t        jredis.ping();\n\t\t        Log.log(\"Sweet success -- we're connected using all default values.\");\n\t        }\n\t        catch (RedisException e) {\n\t\t        Log.error(\"Failed to connect to Redis using JRedisClient default ConnectionSpec -- password perhaps? => \" + e.getLocalizedMessage());\n\t        }\n    \t}\n    \t\n    \t// 2nd example: using defaults but setting the password and the database.  \n    \t// also demonstrated using the method chaining on the ConnectionSpec property setters.\n    \t{\n    \t\t// Note that if your localhost:6379 redis server expects a password\n    \t\t// this will fail\n    \t\tString password = \"jredis\";\n    \t\tint database = 11;\n\t    \tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec();\n\t    \tconnectionSpec\n\t    \t\t.setCredentials(password.getBytes())\n\t    \t\t.setDatabase(database);\n\t    \t\n\t    \tJRedisClient jredis = new JRedisClient(connectionSpec);\n\t    \ttry {\n\t\t        jredis.ping();\n\t\t        Log.log(\"Sweet success -- we're connected using %s as password to %d database.\", password, database);\n\t        }\n\t        catch (RedisException e) {\n\t\t        Log.error(\"Failed to connect to Redis using JRedisClient default ConnectionSpec -- password perhaps? => \" + e.getLocalizedMessage());\n\t        }\n    \t}\n    \t\n    \t// final example: using defaults but setting the full set of basic settings  \n    \t{\n    \t\t// Note that if your localhost:6379 redis server expects a password\n    \t\t// this will fail\n\t    \ttry {\n\t    \t\tString password = \"jredis\";\n\t    \t\tint\t   port = 6379;\n\t    \t\tint\t   database = 11;\n\t    \t\tInetAddress address = InetAddress.getLocalHost();\n\t    \t\t\n\t    \t\t// 1 - get the default connection spec for the basic settings\n\t    \t\t//\n\t\t    \tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(address, port, database, password.getBytes());\n\t\t    \t\n\t\t    \t// finally - use it to create the JRedisClient instance\n\t\t    \t//\n\t\t    \tJRedisClient jredis = new JRedisClient(connectionSpec);\n\t\t        jredis.ping();\n\t\t        Log.log(\"Sweet success -- we're connected using default specs and various server info settings.\");\n\t        }\n\t        catch (RedisException e) {\n\t\t        Log.error(\"Failed to connect to Redis using JRedisClient default ConnectionSpec -- password perhaps? => \" + e.getLocalizedMessage());\n\t        }\n            catch (UnknownHostException e) {\n            \tLog.error(\"Unknownhost: \" + e.getLocalizedMessage());\n            }\n    \t}\n    }\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/UsingJRedisFuture.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport org.jredis.JRedis;\nimport org.jredis.JRedisFuture;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * Example usage of {@link JRedisFuture}, demonstrating the asynchronous semantics.\n * <p>\n * Note that this is an abstract class and concrete extensions will use specific\n * implementation of {@link JRedisFuture}.  Refer to the extension class for the\n * specifics of the associated {@link JRedisFuture} provider class.\n * \n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Oct 11, 2009\n * @since   alpha.0\n * \n */\n\npublic abstract class UsingJRedisFuture {\n\t\n\t// ------------------------------------------------------------------------\n\t// EXAMPLES:\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * The basics of using {@link Future} objects and {@link JRedisFuture}.\n\t * <p>Note the key differences between using {@link JRedis} and {@link JRedisFuture}:\n\t * <ul>\n\t * <li>Methods have identical parameters, but all asynchronous methods return a flavor of {@link Future}\n\t * <li>Exception handling is significantly different.  \n\t * </ul>\n\t * @throws InterruptedException \n\t */\n\t@SuppressWarnings(\"boxing\")\n\tpublic void theBasics () throws InterruptedException {\n\t\tLog.log(\"theBasics()\");\n\t\t\n\t\t/*******************************************/\n\t\t// fire and forget -- no exception handling and not even bothering about the response\n\t\t/*******************************************/\n\t\t// this may throw exceptions on the invoke\n\t\tjredis.ping();\n\t\t\n\t\t/*******************************************/\n\t\t// invoke and wait for response -- was it OK?\n\t\t/*******************************************/\n\t\tFuture<ResponseStatus> fResp = null;\n\t\ttry {\n\t\t\t/*\n\t\t\t * Alright, asynch call is just like the synchronous flavor, but the return type is\n\t\t\t * a Future<?> object.  Here we are doing a PING which simply returns a STATUS response\n\t\t\t * from redis, so the return type is Future<ResponseStatus>\n\t\t\t * \n\t\t\t */\n\t\t\tfResp = jredis.ping();\n\t\t\t\n\t\t\t/*\n\t\t\t * So we have a Future<?> object, but is that the actual response?  No.  You need to wait\n\t\t\t * for it to actually complete.\n\t\t\t * \n\t\t\t * Here we're waiting using blocking semantics:  we wait until its done.\n\t\t\t */\n\t        ResponseStatus response = fResp.get();\n\t        \n\t        /**\n\t         * So we have our response at this point.  We can check it, etc.\n\t         */\n\t        if(response.isError()){\n\t        \tLog.error(\"PING returned an ERR response -- is it an authorization issue?\");\n\t        }\n        }\n        catch (InterruptedException e) {\n        \t/*\n        \t * This can happen if the calling thread (which is under your control, not JRedis) is\n        \t * interrupted.  Given that, its entirely up to you to determine what you should do here.\n        \t * If this is all greek to you, then simply log and re-throw it back up, or add InterruptedException\n        \t * to your method signatures.    \n        \t */\n        \tLog.problem(\"thread was interrupted while waiting for the response to be processed.\");\n        \tthrow e;\n        }\n        catch (ExecutionException e) {\n        \t/**\n        \t * Remember the exceptions that a synchronous JRedis method can throw (ClientRuntime, ProviderException, \n        \t * and of course RedisException)?  Well, ExecutionException is the overall wrapper exception that is thrown\n        \t * by (all) Future instances to permit the propagation of those exceptions to the caller in an asynch manner.\n        \t * So, basically, if any problems arose after your call successfully returned (from the JRedisFuture method),\n        \t * here/now is where/when you find out about it.\n        \t * \n        \t * So what need to happen is for you to get the underlying 'cause' of the generalized ExecutionException.\n        \t */\n        \tLog.problem(\"An execution exception occurred\");\n        }\n\t\t\n\t\t/*******************************************/\n\t\t// invoke and wait for response using timeouts \n\t\t/*******************************************/\n        byte[] setval = \"bar\".getBytes();\n\t\ttry {\n\t\t\tfor(int i=0; i<100000; i++){\n\t\t\t\tjredis.ping();\n\t\t\t\tjredis.incr(\"cntr\");\n\t\t\t}\n\t\t\tjredis.set(\"foo\", setval);\n\t\t\t\n\t\t\t/*\n\t\t\t * Here we're waiting using blocking semantics with timeout\n\t\t\t */\n\t\t\tFuture<byte[]> fVal = jredis.get(\"foo\");\n\t\t\tlong t1 = System.nanoTime();\n\t\t\tint toCnt = 0;\n\t        while(true){\n\t        \ttry {\n\t\t\t\t\tbyte[] val = fVal.get(100L, TimeUnit.MICROSECONDS);\n\t\t\t\t\tString value = DefaultCodec.toStr(val);\n\t\t\t\t\tSystem.out.format(\"=> %s\\n\", value);\n\t\t\t\t\tbreak;\n\t        \t}\n\t            catch (TimeoutException e) {\n\t            \ttoCnt++;\n//\t            \tSystem.out.println('.');\n\t            }\n\t        }\n\t\t\tt1 = System.nanoTime() - t1;\n        \tLog.log(\"done after %d timeouts (%d nanos)\", toCnt, t1);\n\t        \n        }\n        catch (InterruptedException e) {\n        \t/*\n        \t * This can happen if the calling thread (which is under your control, not JRedis) is\n        \t * interrupted.  Given that, its entirely up to you to determine what you should do here.\n        \t * If this is all greek to you, then simply log and re-throw it back up, or add InterruptedException\n        \t * to your method signatures.    \n        \t */\n        \tLog.problem(\"thread was interrupted while waiting for the response to be processed.\");\n        \tthrow e;\n        }\n        catch (ExecutionException e) {\n        \t/**\n        \t * Remember the exceptions that a synchronous JRedis method can throw (ClientRuntime, ProviderException, \n        \t * and of course RedisException)?  Well, ExecutionException is the overall wrapper exception that is thrown\n        \t * by (all) Future instances to permit the propagation of those exceptions to the caller in an asynch manner.\n        \t * So, basically, if any problems arose after your call successfully returned (from the JRedisFuture method),\n        \t * here/now is where/when you find out about it.\n        \t * \n        \t * So what need to happen is for you to get the underlying 'cause' of the generalized ExecutionException.\n        \t */\n        \tLog.problem(\"An execution exception occurred\");\n        }\n\t\t\n\t}\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/** {@link JRedisFuture} provider instance */\n\tprotected final JRedisFuture jredis;\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructor\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Creates a new instances and runs the example methods.\n\t * @param connectionSpec used for creating the connection\n\t */\n\tpublic UsingJRedisFuture (ConnectionSpec connectionSpec){\n\t\tthis.jredis = getProviderInstance(connectionSpec);\n\t\ttry {\n\t        runExamples();\n        }\n        catch (InterruptedException e) {\n        \tLog.problem(\"Interrupted while running the examples.\");\n\t        e.printStackTrace();\n        }\n        jredis.quit();\n\t}\n\t\n\t/**\n\t * @throws InterruptedException \n     * \n     */\n    private void runExamples () throws InterruptedException {\n\t\tLog.log(\"running the JRedisFuture usage examples with %s as the provider implementation.\", jredis.getClass().getSimpleName());\n\t\t\n    \ttheBasics();\n    }\n\n\t// ------------------------------------------------------------------------\n\t// Extension point\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Extension point.\n\t * @param connectionSpec used for creating the connection.\n\t * @return the {@link JRedisFuture} implementation instance\n\t */\n\tabstract\n\tprotected JRedisFuture getProviderInstance (ConnectionSpec connectionSpec);\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/UsingJRedisPipeline.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples;\n\nimport static org.jredis.ri.alphazero.support.DefaultCodec.toLong;\nimport static org.jredis.ri.alphazero.support.DefaultCodec.toStr;\nimport java.util.Random;\nimport org.jredis.JRedisFuture;\nimport org.jredis.RedisException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisPipeline;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * Extension of {@link UsingJRedisFuture} with a {@link JRedisPipeline} as the \n * provider.  \n * <p>See {@link UsingJRedisFuture} for demonstration of generic asynchronous\n * semantics.\n * <p>See {@link UsingJRedisPipeline#exampleUseofSyncInPipeline(ConnectionSpec)} for {@link JRedisPipeline} specific\n * mix mode usage incorporating asynchronous and synchronous calls.\n *  \n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Oct 11, 2009\n * @since   alpha.0\n * @see UsingJRedisFuture\n * \n */\n\npublic class UsingJRedisPipeline extends UsingJRedisFuture {\n\n\tpublic static void main (String[] args) {\n\t\tfinal int database = 13;\n\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, database, \"jredis\".getBytes());\n\t\t\n\t    exampleUseofSyncInPipeline(connectionSpec);\n    }\n\t/**\n\t * Example highlights usage pattern of pipeline with both the natural asynchronous\n\t * semantics and synchronous semantics provided by {@link JRedisPipeline#sync()}\n\t * \n     * @param connectionSpec\n     */\n    @SuppressWarnings(\"boxing\")\n\tprivate static void exampleUseofSyncInPipeline (ConnectionSpec connectionSpec) {\n    \t\n    \t// Note that we are using a JRedisPipeline reference and not a generic\n    \t// JRedisFuture here -- this exposes the additional \n    \t\n    \tJRedisPipeline pipeline = new JRedisPipeline(connectionSpec);\n    \t\n    \t/*\n    \t * Alright, so a hokey example of situations where we would like to\n    \t * asynchronously pipeline a bunch of commands, and then at various point in\n    \t * the process need to sync up with redis and get values before continuing.\n    \t * \n    \t * Obviously we can do this using JRedisFuture as well by calling get() on the\n    \t * returned Future object, but the sync() method may be enhanced in future to\n    \t * provide additional features.  Regardless, it does some of the boiler plate\n    \t * ExecutionException handling code so its a bit prettier.\n    \t */\n    \ttry {\n    \t\tlong start = System.currentTimeMillis();\n    \t\t\n    \t\t/* a sequence of asynchronous calls */\n    \t\t\n\t        pipeline.ping();\n\t        pipeline.flushdb();\n\n\t        Random rand = new Random();\n\t        byte[] data = new byte[8];\n\t        for(int i=0; i<1000000; i++){\n\t        \trand.nextBytes(data);\n\t        \tpipeline.lpush(\"my-list\", data);\n\t        }\n\t        /* \n\t         * switch to synchronous semantics\n\t         * the following call will block until\n\t         * all the responses for above + the llen() \n\t         * itself have been received.\n\t         */\n\t        \n\t        long llen = pipeline.sync().llen(\"my-list\");\n\t        \n\t        String cntrKey = \"my-cntr\";\n\t        for(int i=0; i<100000; i++) {\n\t        \tpipeline.incr(cntrKey);\n\t        }\n\t        /* sync call */\n\t        long cntr = toLong (pipeline.sync().get(cntrKey));\n\t        \n\t        for(int i=0; i<100000; i++){\n\t        \tpipeline.set(\"random:\"+i, \"value:\" + rand.nextInt());\n\t        }\n\t        /* sync call */\n\t        String randomVal = toStr (pipeline.sync().get(\"random:\"+999));\n\t        \n\t        pipeline.flushdb();\n    \t\tSystem.out.format (\"end using sync() = %d msec\\n\", System.currentTimeMillis() - start);\n\t        \n\t        System.out.format(\"%s => %d\\n\", cntrKey, cntr);\n\t        System.out.format(\"%s => %s\\n\", \"random:\"+999, randomVal);\n\t        System.out.format(\"%s has %s items\\n\", \"my-list\", llen);\n\t        \n        }\n        catch (RedisException e) {\n        \tLog.problem(\"RedisException: \" + e);\n        }\n        finally{\n        \tpipeline.sync().quit();\n        \tLog.log(\"shutting down.\");\n        }\n    }\n\t/**\n     * @param connectionSpec\n     */\n    public UsingJRedisPipeline (ConnectionSpec connectionSpec) {\n\t    super(connectionSpec);\n    }\n\n\t/* (non-Javadoc)\n\t * @see org.jredis.examples.UsingJRedisFuture#getProviderInstance(org.jredis.connector.ConnectionSpec)\n\t */\n\t@Override\n\tprotected JRedisFuture getProviderInstance (ConnectionSpec connectionSpec) {\n\t\treturn new JRedisPipeline(connectionSpec);\n\t}\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/UsingJRedisPipelineService.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples;\n\nimport org.jredis.JRedis;\nimport org.jredis.RedisException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.JRedisClient;\nimport org.jredis.ri.alphazero.JRedisPipelineService;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\nimport static org.jredis.ri.alphazero.support.DefaultCodec.*;\n\n/**\n * JRedisPipelineService provides blocking synchronous semantics backed by a pipeline and is suitable\n * for concurrent usages with a single (socket) connection to the server.  There is really nothing\n * different here than using a vanial {@link JRedisClient}.\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 6, 2009\n * @since   alpha.0\n * \n */\n\npublic class UsingJRedisPipelineService {\n\n\tfinal JRedis jredis;\n\tprivate UsingJRedisPipelineService() {\n\t\t// same as usual.\n\t\tConnectionSpec spec = DefaultConnectionSpec.newSpec();\n\t\tspec.setDatabase(11).setCredentials(\"jredis\".getBytes());\n\t\t\n\t\t// only need to use the specific class.\n\t\tjredis = new JRedisPipelineService(spec);\n\t}\n\t\n    private  void run () {\n    \ttry {\n\t        jredis.ping();\n        \tbasicStuff();\n\t        elicitErrors();\n        }\n        catch (RedisException e) {\n\t        e.printStackTrace();\n        }\n    \t\n    \t// Use the connection concurrently\n\n    \tfinal int wcnt = 10;\n    \tfinal int opcnt = 20000;\n    \tfinal Thread[] workers = new Thread[wcnt];\n    \t\n    \tfinal JRedis client = jredis;\n    \tfor(int i=0; i<workers.length; i++) {\n    \t\tfinal int j = i;\n    \t\tworkers[i] = new Thread(new Runnable() {\n\t\t\t\t@Override\n\t\t\t\tpublic void run() {\n\t\t\t        final String wkey = \"foo\" + j;\n\t\t\t        String wvalue = null;\n\t\t\t\t\tfor(int i=0; i< opcnt; i++) {\n\t\t\t\t        try {\n\t\t\t\t        \tclient.incr(wkey);\n\t\t\t\t\t        wvalue = toStr(client.get(wkey));\n\t\t\t\t\t\t} catch (RedisException e) {\n\t\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t        System.out.format(\"%s => %s\\n\", wkey, wvalue);\n\t\t\t\t}\n\t\t\t});\n    \t\tworkers[i].start();\n    \t}\n    \tfor(Thread t : workers){\n    \t\ttry {\n\t\t\t\tt.join();\n\t\t\t} \n    \t\tcatch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n    \t}\n    \t\n    \t// \n\t\tjredis.quit();\n    }\n    \n    private void elicitErrors ()  {\n        String key = \"foo\"\t;\n        try {\n\t        jredis.set(key, \"bar\");\n\t        jredis.sadd(key, \"foobar\");\n        }\n        catch (RedisException e) {\n        \tLog.log(\"Expected elicited error: %s\", e.getMessage());\n        }\n    }\n\n\tprivate void basicStuff () throws RedisException {\n        jredis.flushdb();\n        String key = \"foo\"\t;\n        jredis.set(key, \"bar\");\n        String value = toStr(jredis.get(key));\n        System.out.format(\"%s => %s\\n\", key, value);\n    }\n\n\tpublic static void main (String[] args) {\n\t\t(new UsingJRedisPipelineService()).run();\n\t}\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/UsingJRedisService.java",
    "content": "///*\n// *   Copyright 2009 Joubin Houshyar\n// * \n// *   Licensed under the Apache License, Version 2.0 (the \"License\");\n// *   you may not use this file except in compliance with the License.\n// *   You may obtain a copy of the License at\n// *    \n// *   http://www.apache.org/licenses/LICENSE-2.0\n// *    \n// *   Unless required by applicable law or agreed to in writing, software\n// *   distributed under the License is distributed on an \"AS IS\" BASIS,\n// *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// *   See the License for the specific language governing permissions and\n// *   limitations under the License.\n// */\n//\n//package org.jredis.examples;\n//\n//import org.jredis.RedisException;\n//import org.jredis.connector.ConnectionSpec;\n//import org.jredis.ri.alphazero.JRedisService;\n//import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n//\n///**\n// * [TODO: document me!]\n// *\n// * @author  Joubin Houshyar (alphazero@sensesay.net)\n// * @version alpha.0, Sep 1, 2009\n// * @since   alpha.0\n// * \n// */\n//\n//public class UsingJRedisService {\n//\tpublic static JRedisService service = null;\n//\t/**\n//\t * Demonstrated using the {@link JRedisService} class.  Its also a bench\n//\t * that shows the performance of the service with lots of threads banging on it.\n//\t * Don't forget to flush db#11 after running this as it adds a whole bunch of keys.\n//\t * @param args\n//\t */\n//\tpublic static void main (String[] args) {\n//\t\tint database = 11;\n//\t\tConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(\"localhost\", 6379, database, \"jredis\".getBytes());\n//\t\tint connCnt = 7;\n//\t\tint userCnt = 10;\n//\t\tint opsCnt = 100000;\n//\t\t\n//\t\t// create the service -- well this is it as far as usage goes:  set the number of connections for the service pool\n//\t\t// You can use this anywhere you would use JRedis instances and it is thread safe.\n//\t\t// \n//\t\tservice = new JRedisService(connectionSpec, connCnt);\n//\t\t\n//\t\t// create a bunch of dummy users for the service\n//\t\tThread[] users = new Thread[userCnt];\n//\t\tfor(int i=0; i<userCnt; i++){\n//\t\t\tusers[i] = getDummyUser(i, opsCnt);\n//\t\t}\n//\t\t\n//\t\t// alright, lets run these dummy users\n//\t\t//\n//\t\tfor(int i=0; i<userCnt; i++){\n//\t\t\tusers[i].start();\n//\t\t}\n//\t}\n//\t\n//    /**\n//     * You can change the actual operation to test other Redis commands, if you feel like it.\n//     * @param id\n//     * @param opsCnt\n//     * @return\n//     */\n//    private static Thread getDummyUser (final int id, final int opsCnt) {\n//    \tThread user = new Thread(new Runnable() {\n////\t\t\t@Override\n//            public void run () {\n//\t\t\t\ttry {\n//\t\t\t\t\tString key = null;\n//\t\t\t\t\tbyte[] value = null;\n//\t\t\t\t\tfor(int i=0; i<opsCnt; i++){\n//\t\t\t\t\t\tkey = \"foo\" + i+ \"_\" + id;\n//\t\t\t\t\t\tvalue = (\"woof_\" + i + \"_\" + id).getBytes();\n//\t\t\t\t\t\tservice.set(key, value);\n//\t\t\t\t\t\tservice.get(key);\n//\t\t\t\t\t}\n//                }\n//                catch (RedisException e) {\n//\t                e.printStackTrace();\n//                }\n//            }\n//    \t}, \"user_\" + id);\n//    \treturn user;\n//    }\n//}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/commands/UsingBulkCommands.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples.commands;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.JRedis;\nimport org.jredis.JRedisFuture;\nimport org.jredis.KeyValueSet;\nimport org.jredis.RedisException;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.ResponseStatus;\nimport org.jredis.ri.alphazero.BulkSetMapping;\nimport org.jredis.ri.alphazero.JRedisAsyncClient;\nimport org.jredis.ri.alphazero.JRedisClient;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n\n/**\n * Demonstrates using the bulk commands and helper classes to marshall data.\n * <b>Note that the example flushes DB 10.</b>\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Nov 25, 2009\n * @since   alpha.0 | Redis 1.07\n */\n\npublic class UsingBulkCommands {\n\tpublic static void main (String[] args) {\n\t\tusingSyncClient();\n\t\tusingAsyncClient();\n\t}\n\t\n\t/**\n\t * Using the synchronous interface \n\t */\n\tpublic static void usingSyncClient () {\n\t\tConnectionSpec spec = DefaultConnectionSpec.newSpec()\n\t\t.setCredentials(\"jredis\".getBytes())\n\t\t.setDatabase(10);\n\n\t\tJRedis jredis = new JRedisClient(spec);\n\n\t\tSystem.out.println (\"\\nusing the SyncClient: \\n\\n\");\n\t\t\n\t\tuseMSet (jredis);\n\t\tuseMSetNX (jredis);\n\t\tjredis.quit();\n\t}\n\n\tprivate static void useMSet (JRedis jredis) {\n\t\t// BulkSetMapping provides a set of static methods to create new specific\n\t\t// flavors of KeyValueSet<T> for the JRedis.mset(..) method.\n\t\t// use this when your values are all of the same type.\n\t\t// Here we are using String values\n\n\t\tKeyValueSet.Strings \tkvSet = BulkSetMapping.newStringKVSet();\n\t\tkvSet\n\t\t.add(\"foo\", \"woof\")\n\t\t.add(\"bar\", \"meow\")\n\t\t.add(\"paz\", \"the salt\")\n\t\t.add(\"x?\", \"yz!\");\n\t\t\n\t\ttry {\n\t\t\tjredis.flushdb();\n\t        jredis.mset(kvSet);\n        }\n        catch (RedisException e) { e.printStackTrace(); }\n\t}\n\t\n\tprivate static void useMSetNX (JRedis jredis) {\n\t\t// Here we are using a mixed set of value types\n\n\t\tMap<String, byte[]> kvMap = new HashMap<String, byte[]>();\n\t\tkvMap.put(\"foo\", \"bar\".getBytes());\n\t\tkvMap.put(\"cat\", \"meow\".getBytes());\n\t\tkvMap.put(\"dog\", \"woof\".getBytes());\n\t\tkvMap.put(\"bird\", \"whale fail\".getBytes());\n\t\tkvMap.put(\"pi\", String.valueOf(3.141592653589793).getBytes());\n\t\t\n\t\ttry {\n\t\t\tjredis.flushdb();\n\t\t\t\n\t\t\tjredis.set(\"bird\", \"tweet\");\t// <= force an error on msetnx\n\t        boolean stat = jredis.msetnx(kvMap);\n\t        if(!stat) {\n\t        \tSystem.out.format(\"Couldn't msetnx - one of these already exists: %s\\n\", kvMap.keySet());\n\t        }\n\t        \n\t        // and now we can find out which one existed:\n\t        for(String key : kvMap.keySet()){\n\t        \tif(jredis.exists(key)){\n\t        \t\tSystem.out.format(\"key '%s' [value: %s] already existed!\\n\", key, new String(jredis.get(key)));\n\t        \t}\n\t        }\n        }\n        catch (RedisException e) { e.printStackTrace(); }\n\t}\n\t\n\t\n\t/**\n\t * Using the asynchronous interface \n\t */\n\tpublic static void usingAsyncClient () {\n\t\tConnectionSpec spec = DefaultConnectionSpec.newSpec()\n\t\t.setCredentials(\"jredis\".getBytes())\n\t\t.setDatabase(10);\n\n\t\tJRedisFuture jredis = new JRedisAsyncClient(spec);\n\n\t\tSystem.out.println (\"\\nusing the AsyncClient: \\n\\n\");\n\t\tuseMSet(jredis);\n\t\tuseMSetNX (jredis);\n\t\t\n        jredis.quit();\n\n\t}\n\tprivate static void useMSetNX (JRedisFuture jredis) {\n\t\t\n\t\tMap<String, byte[]> kvMap = new HashMap<String, byte[]>();\n\t\tkvMap.put(\"foo\", \"bar\".getBytes());\n\t\tkvMap.put(\"cat\", \"meow\".getBytes());\n\t\tkvMap.put(\"dog\", \"woof\".getBytes());\n\t\tkvMap.put(\"bird\", \"whale fail\".getBytes());\n\t\tkvMap.put(\"pi\", String.valueOf(3.141592653589793).getBytes());\n\n\t\ttry {\n\t\t\tjredis.flushdb();\n\t        jredis.set(\"bird\", \"tweet\");\n\t        Future<Boolean> future = jredis.msetnx(kvMap);\n\t        if(!future.get()) {\n\t        \tSystem.out.format(\"Couldn't msetnx - one of these already exists: %s\\n\", kvMap.keySet());\n\t        }\n\t        // and now we can find out which one existed:\n\t        for(String key : kvMap.keySet()){\n\t        \tif(jredis.exists(key).get()){\n\t        \t\tSystem.out.format(\"key '%s' [value: %s] already existed!\\n\", key, new String(jredis.get(key).get()));\n\t        \t}\n\t        }\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n\t}\n\tprivate static void useMSet (JRedisFuture jredis) {\n\t\t// BulkSetMapping provides a set of static methods to create new specific\n\t\t// flavors of KeyValueSet<T> for the JRedis.mset(..) method.\n\t\t// use this when your values are all of the same type.\n\t\t// Here we are using Number values\n\t\t\n\t\tKeyValueSet.Numbers \tkvSet = BulkSetMapping.newNumberKVSet();\n\t\tkvSet\n\t\t.add(\"integer\", 10)\n\t\t.add(\"real\", 10.55)\n\t\t.add(\"scientific\", 1.5e4)\n\t\t.add(\"sepher\", 0);\n\n\t\ttry {\n\t\t\tjredis.flushdb();\n\t        Future<ResponseStatus> future = jredis.mset(kvSet);\n\t        if(future.get().isError()){\n\t        \tthrow new RuntimeException(\"MSET failed! (How could that be?)\");\n\t        }\n\t        jredis.exists(\"foo\");\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n\t}\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/commands/UsingZrangeSubset.java",
    "content": "/*\n *   Copyright 2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.examples.commands;\n\nimport java.util.List;\nimport java.util.Random;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport org.jredis.JRedis;\nimport org.jredis.JRedisFuture;\nimport org.jredis.RedisException;\nimport org.jredis.RedisType;\nimport org.jredis.ZSetEntry;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.ri.alphazero.JRedisAsyncClient;\nimport org.jredis.ri.alphazero.JRedisClient;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.DefaultCodec;\n\n/**\n * [TODO: document me!]\n *\n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Mar 20, 2010\n * @since   alpha.0\n * \n */\n\npublic class UsingZrangeSubset {\n\t\n\tstatic final String zset = \"example-sorted-set\";\n\tstatic final Random rand = new Random(System.currentTimeMillis());\n\t\n\tpublic static void main (String[] args) {\n\t\tusingSyncClient();\n\t\tusingAsyncClient();\n\t}\n\t\n\t/**\n\t * Using the synchronous interface \n\t */\n\tpublic static void usingSyncClient () {\n\t\tConnectionSpec spec = DefaultConnectionSpec.newSpec()\n\t\t.setCredentials(\"jredis\".getBytes())\n\t\t.setDatabase(10);\n\n\t\tJRedis jredis = new JRedisClient(spec);\n\n\t\tSystem.out.println (\"** using JRedis **\");\n\t\t\n\t\tuseZRangeSubset (jredis);\n\t\t\n\t\tjredis.quit();\n\t}\n\n\t/**\n\t * Using the asynchronous interface \n\t */\n\tpublic static void usingAsyncClient () {\n\t\tConnectionSpec spec = DefaultConnectionSpec.newSpec()\n\t\t.setCredentials(\"jredis\".getBytes())\n\t\t.setDatabase(10);\n\n\t\tJRedisFuture jredis = new JRedisAsyncClient(spec);\n\n\t\tSystem.out.println (\"\\n\\n** using JRedisFuture **\");\n\t\tuseZRangeSubset(jredis);\n\t\t\n        jredis.quit();\n\n\t}\n\t\n\t/**\n\t * The z[rev]rangeSubset commands return non-standard results tpes (see {@link ZSetEntry}).  Nothing\n\t * that unexpected as far as the semantics are concerned, but just in case it is not perfectly clear, this\n\t * example illustrates its intended use.\n\t * <b>\n\t * So here we'll flush the db, {@link Command#ZADD} a few (scored) entries to a {@link RedisType#zset}, and\n\t * then use {@link JRedis#zrangeSubset(String, long, long)} and {@link JRedis#zrevrangeSubset(String, long, long)}\n\t * and dump the results to console. \n\t *  \n\t * @param jredis\n\t */\n\tprivate static void useZRangeSubset (JRedis jredis) {\n\n\t\ttry {\n\t\t\tjredis.flushdb();\n\t\t\t\n\t\t\t// we'll add a few String values to our set with random scores\n\t\t\t//\n\t\t\tfor(int i=0; i<100; i++){\n\t\t\t\tjredis.zadd(zset, rand.nextDouble(), getRandomAsciiString(rand, 8));\n\t\t\t}\n\t\t\t\n\t\t\t// let's get the subset in range {0, 10} in ascending order\n\t\t\t//\n\t\t\tList<ZSetEntry> subset = jredis.zrangeSubset(zset, 0, 10);\n\t\t\t\n\t\t\tSystem.out.format (\"\\n\\n%s elements from 0 to 10 - natural order:\\n\\t---\\n\", zset);\n\t\t\tfor(int j=0; j<subset.size(); j++) {\n\t\t\t\t// ZSetEntry uses byte[] as baseline for value\n\t\t\t\t// since we know we put Strings in the set, we can go ahead and decode the byte[] and get our String value back\n\t\t\t\t// value is just a double (primitive).  \n\t\t\t\t\n\t\t\t\tZSetEntry e = subset.get(j);\n\t\t\t\tString value = DefaultCodec.toStr(e.getValue());\n\t\t\t\t\n\t\t\t\tSystem.out.format(\"\\t[%03d]:  {value: %s score: %1.19f}\\n\", j, value, e.getScore());\n\t\t\t}\n\t\t\t\n\t\t\t// & now let's get the subset in range {0, 10} in ascending order\n\t\t\t//\n\t\t\tList<ZSetEntry> revsubset = jredis.zrevrangeSubset(zset, 0, 10);\n\t\t\t\n\t\t\tSystem.out.format (\"\\n\\n%s elements from 0 to 10 - reverse order:\\n\\t---\\n\", zset);\n\t\t\tfor(int j=0; j<revsubset.size(); j++) {\n\t\t\t\tZSetEntry e = revsubset.get(j);\n\t\t\t\tString value = DefaultCodec.toStr(e.getValue());\n\t\t\t\t\n\t\t\t\tSystem.out.format(\"\\t[%03d]:  {value: %s score: %1.19f}\\n\", 100-j, value, e.getScore());\n\t\t\t}\t\t\t\n        }\n        catch (RedisException e) { e.printStackTrace(); }\n\t}\n\t\n\t/**\n\t * Here we're doing the same thing as {@link UsingZrangeSubset#useZRangeSubset(JRedis)} but we're\n\t * using the {@link JRedisFuture} and asynchronous semantics.\n\t */\n\tprivate static void useZRangeSubset (JRedisFuture jredis) {\n\t\t\n\t\tjredis.flushdb();\n\t\tfor(int i=0; i<100; i++){\n\t\t\tjredis.zadd(zset, rand.nextDouble(), getRandomAsciiString(rand, 8));\n\t\t}\n\t\t\n\t\tFuture<List<ZSetEntry>> futureSubset = jredis.zrangeSubset(zset, 0, 10);\n\t\tFuture<List<ZSetEntry>> futureRevSubset = jredis.zrevrangeSubset(zset, 0, 10);\n\t\t\n\t\ttry {\n\t\t\t\n\t\t\tSystem.out.format (\"\\n\\n%s elements from 0 to 10 - natural order:\\n\\t---\\n\", zset);\n\t\t\tList<ZSetEntry> subset = futureSubset.get();\n\t\t\tfor(int j=0; j<subset.size(); j++) {\n\t\t\t\t// ZSetEntry uses byte[] as baseline for value\n\t\t\t\t// since we know we put Strings in the set, we can go ahead and decode the byte[] and get our String value back\n\t\t\t\t// value is just a double (primitive).  \n\t\t\t\t\n\t\t\t\tZSetEntry e = subset.get(j);\n\t\t\t\tString value = DefaultCodec.toStr(e.getValue());\n\t\t\t\t\n\t\t\t\tSystem.out.format(\"\\t[%03d]:  {value: %s score: %1.19f}\\n\", j, value, e.getScore());\n\t\t\t}\n\t\t\t\n\t\t\t// & now let's get the subset in range {0, 10} in ascending order\n\t\t\t//\n\t\t\tList<ZSetEntry> revsubset = futureRevSubset.get();\n\t\t\t\n\t\t\tSystem.out.format (\"\\n\\n%s elements from 0 to 10 - reverse order:\\n\\t---\\n\", zset);\n\t\t\tfor(int j=0; j<revsubset.size(); j++) {\n\t\t\t\tZSetEntry e = revsubset.get(j);\n\t\t\t\tString value = DefaultCodec.toStr(e.getValue());\n\t\t\t\t\n\t\t\t\tSystem.out.format(\"\\t[%03d]:  {value: %s score: %1.19f}\\n\", 100-j, value, e.getScore());\n\t\t\t}\t\t\t\n        }\n        catch (ExecutionException e) {\n\t        e.printStackTrace();\n        }\n        catch (InterruptedException e) {\n\t        e.printStackTrace();\n        }\n\t}\n\t// -- util\n\t/**\n\t * Creates a random ascii string\n\t * @param length\n\t * @return\n\t */\n\tstatic final String getRandomAsciiString (Random random, int length) {\n\t\tStringBuilder builder = new  StringBuilder(length);\n\t\tfor(int i = 0; i<length; i++){\n\t\t\tchar c = (char) (random.nextInt(126-33) + 33);\n\t\t\tbuilder.append(c);\n\t\t}\n\t\treturn builder.toString();\n\t}\n\n}\n"
  },
  {
    "path": "examples/src/main/java/org/jredis/examples/commands/package-info.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n/**\n * This package contains examples of using {@link org.jredis.JRedis} and {@link org.jredis.JRedisFuture} commands.\n */\npackage org.jredis.examples.commands;\n\n"
  },
  {
    "path": "examples/src/main/resources/log4j.properties",
    "content": "# Configure logging for testing\nlog4j.rootLogger=INFO, stdout, logfile\n\nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender\nlog4j.appender.stdout.layout=org.apache.log4j.PatternLayout\nlog4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c] - %m%n\n\nlog4j.appender.logfile=org.apache.log4j.RollingFileAppender\nlog4j.appender.logfile.File=jredis-examples.log\nlog4j.appender.logfile.MaxFileSize=512KB\n\nlog4j.appender.logfile.MaxBackupIndex=1\n\n# Pattern to output: date priority [category] - message\nlog4j.appender.logfile.layout=org.apache.log4j.PatternLayout\nlog4j.appender.logfile.layout.ConversionPattern=%d %-5p [%c] - %m%n\n"
  },
  {
    "path": "extensions/3rd party Licenses/NET.SPY.MEMCACHED LICENSE",
    "content": "Copyright (c) 2006-2009  Dustin Sallings <dustin@spy.net>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "extensions/3rd party Licenses/NET.SPY.MEMCACHED NOTICE",
    "content": "NOTICE:\n\nPortions of the reference implementation libaray for JRedis/extensions uses\nverbatim and/or modified derivatives of original work by Dustin Sallings in\nnet.spy.memcached (Java client for Memcached).  Documentation in extensions/ri\nhighlights such usage in JRedis library.\n\nOriginal work's Copyright notice follows:\n\n-- BEGIN --\n\nCopyright (c) 2006-2009  Dustin Sallings <dustin@spy.net>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n-- END --\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "extensions/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "extensions/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "extensions/README.markdown",
    "content": "# JRedis Extensions\n\nExtended functionality for [JRedis]\n\n[JRedis]: http://github.com/alphazero/jredis\n"
  },
  {
    "path": "extensions/api/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "extensions/api/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "extensions/api/README.markdown",
    "content": "# API/Sepcifications of JRedis Extensions\n\nExtended functionality for [JRedis]\n\n[JRedis]: http://github.com/alphazero/jredis\n"
  },
  {
    "path": "extensions/api/pom.xml",
    "content": "<!-- ~/extensions/api/pom.xml -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <!-- parent -->\n  <parent>\n    <groupId>org.jredis</groupId>\n    <artifactId>jredis-extensions</artifactId>\n\t<version>${jredisVersion}</version>\n  </parent>\n\n  <!-- production | jar -->\n  <name>JRedis - Extensions - API</name>\n  <groupId>org.jredis</groupId>\n  <artifactId>jredis-extensions-api</artifactId>\n  <version>${jredisVersion}</version>\n  <packaging>jar</packaging>\n  \n  <dependencies>\n  \n    <!-- core api -->\n    <dependency>\n      <groupId>org.jredis</groupId>\n      <artifactId>jredis-core-api</artifactId>\n\t  <version>${jredisVersion}</version>\n    </dependency>\n\n    <!-- core ri -->\n    <dependency>\n      <groupId>org.jredis</groupId>\n      <artifactId>jredis-core-ri</artifactId>\n\t  <version>${jredisVersion}</version>\n    </dependency>\n    \n    <!-- unit testing -->\n    <dependency>\n      <groupId>org.testng</groupId>\n      <artifactId>testng</artifactId>\n      <version>6.1.1</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n  \n  <build>\n    <plugins>\n      <plugin>\n        <artifactId>maven-assembly-plugin</artifactId>\n        <version>2.1</version>\n        <executions>\n          <execution>\n            <id>simple-install</id>\n            <phase>package</phase>\n            <goals>\n              <goal>attached</goal>\n            </goals>\n          </execution>\n        </executions>\n        <configuration>\n          <descriptorRefs>\n            <descriptorRef>jar-with-dependencies</descriptorRef>\n          </descriptorRefs>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n  \n</project>\n"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/ClusterModel.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\n\n/**\n * Represent (a potentially active) model of a cluster.  \n * <p>\n * Implementors may throw {@link NotSupportedException} for the optional methods.\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 28, 2010\n * \n */\n\npublic interface ClusterModel {\n\n\t/**\n\t * Indicates if the implementation supports the cluster type.  \n\t * @param type\n\t * @return\n\t */\n\tpublic boolean supports(ClusterType type);\n\t\n\t/**\n\t * Indicates if the {@link ClusterModel} implementation supports dynamic cluster configurations,\n\t * @return true if yes, otherwise false.\n\t */\n\tpublic boolean supportsReconfiguration();\n\n\t/**\n\t * @return the {@link ClusterSpec} that accurately represents the current state\n\t * of the model.\n\t */\n\tpublic ClusterSpec getSpec();\n\n\t/**\n\t * Optional.\n\t * <p>\n\t * Must raise a {@link ClusterModel.Event.Type#NodeAdded} event with the deleted node as\n\t * the event's info.  Event must be raised after the model has transitioned to the new state.\n\t * @param nodeSpec\n\t * @throws IllegalArgumentException\n\t */\n\tpublic void addNode(ClusterNodeSpec nodeSpec) throws IllegalArgumentException; \n\n\t/**\n\t * Optional.\n\t * <p>\n\t * Must raise a {@link ClusterModel.Event.Type#NodeAdded} event with the new node as\n\t * the event's info.  Event must be raised after the model has transitioned to the new state.\n\t * @param nodeSpec\n\t * @throws IllegalArgumentException\n\t */\n\tpublic void removeNode(ClusterNodeSpec nodeSpec) throws IllegalArgumentException;\n\n\t// ------------------------------------------------------------------------\n\t// Cluster semantics\n\n\t/**\n\t * Maps the given key to a specified node of the cluster, by returning its\n\t * {@link ClusterNodeSpec}.\n\t * @param key\n\t * @return\n\t */\n\tpublic ClusterNodeSpec getNodeForKey (byte[] key);\n\n\n\t// ------------------------------------------------------------------------\n\t// Event management\n\n\t/**\n\t * Optinal\n\t * @param modelListener\n\t * @return\n\t */\n\tpublic boolean addListener(Listener modelListener);\n\n\t/**\n\t * Optinal\n\t * @param modelListener\n\t * @return\n\t */\n\tpublic boolean removeListener(Listener modelListener);\n\n\t// ========================================================================\n\t// Inner Types\n\t// ========================================================================\n\n\n\t// ------------------------------------------------------------------------\n\t// EventListener\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Your basic ClusterModel.Event Listener.\n\t *\n\t * @author  joubin (alphazero@sensesay.net)\n\t * @date    Mar 29, 2010\n\t * \n\t */\n\tpublic interface Listener {\n\t\tpublic void onEvent(ClusterModel.Event event);\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Model Events\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Optional event interface for dynamic models which support event\n\t * generation.\n\t * \n\t * @author  joubin (alphazero@sensesay.net)\n\t * @date    Mar 29, 2010\n\t * \n\t */\n\tpublic static class Event extends org.jredis.Event<ClusterModel, ClusterModel.Event.Type, ClusterNodeSpec> {\n\n\t\t/**  */\n\t\tprivate static final long serialVersionUID = 1L;\n\t\t/** generated at Event construction time */\n\t\tprivate final long\t timestamp;\n\t\t/**\n\t\t * @param src\n\t\t * @param type\n\t\t * @param info\n\t\t */\n\t\tpublic Event (ClusterModel src, Type type, ClusterNodeSpec info) {\n\t\t\tsuper(src, type, info);\n\t\t\ttimestamp = System.currentTimeMillis();\n\t\t}\n\t\t\n\t\t/** @return event approximate event generation time. */\n\t\tpublic long getTimestamp () { return timestamp; }\n\n\t\t/** ClusterModel.Event.Types */\n\t\tpublic enum Type {\n\t\t\tInitialized,\n\t\t\tNodeAdded,\n\t\t\tNodeRemoved\n\t\t}\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Support base\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Provides basic support for the {@link ClusterModel} interface for the\n\t * general semantics and features, and, extension points for specialized\n\t * {@link ClusterModel}s.\n\t * <p>\n\t * Support for optional event management methods are provided.\n\t *\n\t * @author  joubin (alphazero@sensesay.net)\n\t * @date    Mar 29, 2010\n\t * \n\t */\n\tabstract public static class Support implements ClusterModel {\n\n\t\t// --------------------------------------------------------------------\n\t\t// properties\n\t\t// --------------------------------------------------------------------\n\t\t/**  */\n\t\tfinal protected ClusterSpec clusterSpec;\n\t\t/**  */\n\t\tfinal private Set<Listener> listeners = new HashSet<Listener>();\n\t\t/**  */\n\t\tfinal protected Object configLock = new Object();\t\n\n\n\t\t// --------------------------------------------------------------------\n\t\t// Constructor\n\t\t// --------------------------------------------------------------------\n\t\t/**\n\t\t * Instantiates and initializes the model.  This constructor will\n\t\t * invoke {@link Support#initializeModel()} immediately after setting\n\t\t * all parameters, including {@link ClusterSpec}.\n\t\t * <p>\n\t\t * Due to initialization cycle, this constructor may throw {@link ClientRuntimeException}\n\t\t * or {@link ProviderException}s.  Refer to the implementation for details.\n\t\t * <p>\n\t\t * Methods that modify the cluster configuration, {@link ClusterModel#addNode(ClusterNodeSpec)} and\n\t\t * {@link ClusterModel#removeNode(ClusterNodeSpec)}, will first use the \n\t\t * {@link ClusterModel#supportsReconfiguration()} to check if such operations \n\t\t * are supported.  If not, a {@link NotSupportedException} is thrown.\n\t\t * <br>\n\t\t * Otherwise, this implementaiton wwill first obtain the {@link Support#configLock}, \n\t\t * and then modify the associated {@link ClusterSpec}, and will invoke the \n\t\t * extension point {@link Support#onNodeAddition(ClusterNodeSpec)} or \n\t\t * {@link Support#onNodeRemoval(ClusterNodeSpec)} to signal the configuration \n\t\t * change to the specialized subclass. Finally, after releasing the model's \n\t\t * config lock, all listerners are notified of the configuration change with\n\t\t * an appropriate {@link ClusterModel.Event}.\n\t\t * \n\t\t * @param clusterSpec\n\t\t */\n\t\tprotected Support(ClusterSpec clusterSpec){\n\t\t\tif(null == clusterSpec) \n\t\t\t\tthrow new IllegalArgumentException(\"clusterSpec param is null\");\n\t\t\tif(!supportsReconfiguration() && clusterSpec.getNodeSpecs().size() == 0)\n\t\t\t\tthrow new IllegalArgumentException(\"clusterSpec has no ClusterNodeSpecs and this model can not be reconfigured.\");\n\t\t\t\n\t\t\tthis.clusterSpec = clusterSpec;\n\t\t\tinitialize();\n\t\t}\n\n\t\t// --------------------------------------------------------------------\n\t\t// Interface\n\t\t// --------------------------------------------------------------------\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#addNode(org.jredis.cluster.ClusterNodeSpec) */\n\t\tfinal public void addNode (ClusterNodeSpec nodeSpec)\n\t\tthrows IllegalArgumentException \n\t\t{\n\t\t\tif(supportsReconfiguration()){\n\t\t\t\tsynchronized (configLock) {\n\t\t\t\t\tclusterSpec.addNode(nodeSpec);\n\t\t\t\t\tonNodeAddition (nodeSpec);\n\t\t\t\t}\n\t\t\t\tnotifyListeners(new ClusterModel.Event(this, ClusterModel.Event.Type.NodeAdded, nodeSpec));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new NotSupportedException(\"Cluster reconfiguration not supported.\");\n\t\t\t}\n\t\t}\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#removeNode(org.jredis.cluster.ClusterNodeSpec) */\n\t\tfinal public void removeNode (ClusterNodeSpec nodeSpec) throws IllegalArgumentException {\n\t\t\tif(supportsReconfiguration()){\n\t\t\t\tif(!clusterSpec.getNodeSpecs().contains(nodeSpec)) throw new IllegalArgumentException(\"NodeSpec not part of cluster spec!\");\n\t\t\t\tsynchronized (configLock) {\n\t\t\t\t\tclusterSpec.removeNode(nodeSpec);\n\t\t\t\t\tonNodeAddition (nodeSpec);\n\t\t\t\t}\n\t\t\t\tnotifyListeners(new ClusterModel.Event(this, ClusterModel.Event.Type.NodeRemoved, nodeSpec));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new NotSupportedException(\"Cluster reconfiguration not supported.\");\n\t\t\t}\n\t\t}\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#getSpec() */\n\t\tfinal public ClusterSpec getSpec () {\n\t\t\treturn clusterSpec;\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#addListener(org.jredis.cluster.ClusterModelListener) */\n\t\tfinal public boolean addListener (Listener modelListener) {\n\t\t\treturn listeners.add(modelListener);\n\t\t}\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#removeListener(org.jredis.cluster.ClusterModelListener) */\n\t\tfinal public boolean removeListener (Listener modelListener) {\n\t\t\treturn listeners.remove(modelListener);\n\t\t}\n\n\t\t// --------------------------------------------------------------------\n\t\t// Internal ops\n\t\t// --------------------------------------------------------------------\n\t\tprivate final void initialize () {\n\t\t\tinitializeModel();\n\t\t}\n\t\t\n\t\tprivate final void notifyListeners(ClusterModel.Event e) {\n\t\t\tfor(ClusterModel.Listener l : listeners)\n\t\t\t\tl.onEvent(e);\n\t\t}\n\t\t// --------------------------------------------------------------------\n\t\t// Extension Points\n\t\t// --------------------------------------------------------------------\n\t\t/**\n\t\t * @param newNode\n\t\t * @return\n\t\t */\n\t\tabstract protected boolean onNodeAddition(ClusterNodeSpec newNode);\n\t\t/**\n\t\t * @param newNode\n\t\t * @return\n\t\t */\n\t\tabstract protected boolean onNodeRemoval(ClusterNodeSpec newNode);\n\t\t/**\n\t\t * \n\t\t */\n\t\tabstract protected void initializeModel();\n\t}\n}\n"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/ClusterNodeSpec.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport java.util.Set;\nimport org.jredis.connector.ConnectionSpec;\n\n/**\n * Contract:\n * <br>\n * Any given pair of {@link ClusterNodeSpec}s with identical <i>id</i>s (per {@link ClusterNodeSpec#getId()}) must\n * also return identical results for {@link ClusterNodeSpec#getKeyForReplicationInstance(int)} and will be considered equivalent. \n * Implementations are required to appropriately override {@link Object#equals(Object)} to enforce this contract for use in \n * Collections (such as {@link Set}.\n * \n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 24, 2010\n * \n */\n\n// this is just a data structure with a few methods - make it a class\npublic interface ClusterNodeSpec {\n\t/**\n\t * @return\n\t */\n\tpublic ConnectionSpec getConnectionSpec();\n\t\n\t/**\n\t * All implementations must provide a cluster wide unique {@link String} identifier for a node.\n\t * @return\n\t */\n\tpublic String getId ();\n\t\n\t/**\n\t * Each node in a consistent hashing scheme is represented a number of times to satisfy the requirements of the\n\t * Consistent Hashing.  The implementation must satisfy the global uniqueness of the returned key within the associated\n\t * cluster.\n\t * <p>\n\t * This is an optional method, but is required for all implementations supporting Consistent Hashing for sharded clusters.\n\t * <p>\n\t * See Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web\n\t * (sec 4).\n\t * @param rangeReplicationIndex \n\t * @return a globally unique {@link String} key. \n\t */\n\tpublic String getKeyForReplicationInstance (int rangeReplicationIndex);\n\t\n\t// ------------------------------------------------------------------------\n\t// Reference Implementation \n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * [TODO: document me!]\n\t *\n\t * @author  joubin (alphazero@sensesay.net)\n\t * @date    Mar 24, 2010\n\t * \n\t */\n\tpublic abstract static class Support implements ClusterNodeSpec {\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Attrs\n\t\t// ------------------------------------------------------------------------\n\t\t/** {@link ConnectionSpec} of this node */\n\t\tfinal protected ConnectionSpec connSpec;\n\t\t\n\t\t/** Cluster wide unique identifier */\n\t\tfinal protected String id;\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// Constructor(s)\n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\t/**\n\t\t * @param connSpec\n\t\t * @throws IllegalArgumentException \n\t\t */\n\t\tpublic Support(ConnectionSpec connSpec){\n\t\t\tif(null == connSpec)\n\t\t\t\tthrow new IllegalArgumentException(\"ConnectionSpec is null\");\n\t\t\t\n\t\t\tthis.connSpec = connSpec;\n\t\t\tthis.id = generateId();\n\t\t}\n\t\t// ------------------------------------------------------------------------\n\t\t// Interface\n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterNodeSpec#getConnectionSpec() */\n//        @Override\n        final public ConnectionSpec getConnectionSpec () { return this.connSpec; }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterNodeSpec#getId() */\n//        @Override\n        final public String getId () { return this.id;}\n        \n\t\t// ------------------------------------------------------------------------\n\t\t// Identity\n\t\t// ------------------------------------------------------------------------\n        /**\n         * Test for equality to enforce {@link ClusterNodeSpec} identity contract spec,\n         * will compare the ids of the two objects.\n         * @throws IllegalArgumentException if arg is null or not a {@link ClusterNodeSpec}\n         */\n        @Override\n        final public boolean equals(Object o) {\n        \tif(null == o) throw new IllegalArgumentException(\"null argument\");\n        \tClusterNodeSpec n = null;\n        \ttry { n = (ClusterNodeSpec) o; }\n        \tcatch (ClassCastException e) { throw new IllegalArgumentException (\"object is not a ClusterNodeSpec\");}\n        \t\n        \treturn this.getId().equals(n.getId());\n        }\n        \n        /**\n         * Enforece {@link ClusterNodeSpec} identity contract by returning the hashcode of the\n         * id.  Delegates to {@link String#hashCode()}\n         */\n        @Override\n        final public int hashCode() {\n        \treturn this.getId().hashCode();\n        }\n        \n        @Override\n        public String toString() { return this.getId(); }\n        \n\t\t// ------------------------------------------------------------------------\n\t\t// Extension points\n\t\t// ------------------------------------------------------------------------\n        /**\n         * Method is called once (and only once) by the constructor to set the\n         * final {@link Support#id} field.  This (default) implementation simply\n         * creates a string of form <ip-address-string-rep>:<0-padded-5-digit-port-number>:<0 padded 2-digit-db-number.\n         * <p>\n         * ex:\n         * <code>\n         * \"127.0.0.1:06379:02\" \n         * </code>\n         * <p>\n         * Optional extension point.\n         * @return\n         */\n        protected abstract String generateId () ;\n\t}\n}\n"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/ClusterSpec.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 24, 2010\n * \n */\n\n// this is just a datastructure with a few methods -- make it a class\npublic interface ClusterSpec {\n\n\t// ------------------------------------------------------------------------\n\t// Node/Key space management and distribution \n\t// ------------------------------------------------------------------------\n\t\n\t// TODO: may wish to use a simple enum here to spec the cluster type (i.e. ConsistentHashing)\n\t// and let the RIs supply a model to suite it.\n//\t\n//\t/**\n//\t * @return the stretegy used to distribute keys across the node space.\n//\t */\n//\tpublic ClusterStrategy  getStrategy();\n//\t\n\tpublic ClusterType getType ();\n\tpublic ClusterSpec setType (ClusterType clusterType);\n\t\n\t// ------------------------------------------------------------------------\n\t// Membership\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @return\n\t */\n\tpublic Set<ClusterNodeSpec> getNodeSpecs();\n\t\n\t/**\n\t * @param nodeSpec\n\t * @return\n\t * @throws IllegalArgumentException if nodeSpec provided is already present.\n\t */\n\tpublic boolean addNode(ClusterNodeSpec nodeSpec);\n\t\n\t/**\n     * @param nodeSpec\n\t * @throws IllegalArgumentException if nodeSpec provided is already present.\n     */\n    public boolean removeNode (ClusterNodeSpec nodeSpec);\n    \n\t/**\n\t * Note that the collection must not include a null member.  \n\t * \n\t * @param nodeSpecs is a {@link Collection} instead of a {@link Set} to \n\t * relax the type requirements, but the required semantics remains set like,\n\t * and duplicate (per {@link ClusterNodeSpec#equals(Object)} elements will\n\t * be rejected.\n\t * @throws IllegalArgumentException if collection includes a null member\n\t * @return per contract of {@link Set#addAll(Collection)}\n\t */\n\tpublic boolean addAll(Collection<ClusterNodeSpec> nodeSpecs);\n\t\n\t/**\n\t * Note that the collection must not include a null member.  \n\t * \n\t * @param nodeSpecs\n\t * @throws IllegalArgumentException if collection includes a null member\n\t * @return per contract of {@link Set#removeAll(Collection)}\n\t */\n\tpublic boolean removeAll(Collection<ClusterNodeSpec> nodeSpecs);\n\t\n\t// ========================================================================\n\t// INNER CLASSES\n\t// ========================================================================\n\t\n\tpublic abstract static class Support implements ClusterSpec {\n\n//\t\t/**  */\n//\t\tfinal protected ClusterModel distributionStrategy;\n\t\tprivate ClusterType type;\n\t\t\n\t\t/**  */\n\t\tfinal protected Set<ClusterNodeSpec> nodeSpecs = new HashSet<ClusterNodeSpec>();\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// constructor (template) \n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\tprotected Support () { }\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// interface\n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\tpublic ClusterType getType() { return type; }\n\t\tpublic ClusterSpec setType(ClusterType type) { this.type = type; return this; }\n\t\t\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterSpec#addAll(java.util.List) */\n//      @Override\n        public boolean addAll (Collection<ClusterNodeSpec> nodes) {\n        \tif(nodes.contains(null)) throw new IllegalArgumentException(\"collection includes a null member\");\n        \treturn  nodeSpecs.addAll(nodes);\n        }\n\n        /* (non-Javadoc) @see org.jredis.cluster.ClusterSpec#removeAll(java.util.Collection) */\n//      @Override\n        public boolean removeAll (Collection<ClusterNodeSpec> nodes) {\n        \tif(nodes.contains(null)) throw new IllegalArgumentException(\"collection includes a null member\");\n        \treturn nodeSpecs.removeAll(nodes);\n        }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterSpec#addNode(org.jredis.cluster.ClusterNodeSpec) */\n//        @Override\n        public boolean addNode (ClusterNodeSpec nodeSpec) {\n        \tif(null == nodeSpec)\n    \t\t\tthrow new IllegalArgumentException(\"null nodeSpec\");\n        \t\n    \t\treturn this.nodeSpecs.add(nodeSpec);\n        }\n\n        /* (non-Javadoc) @see org.jredis.cluster.ClusterSpec#removeNode(org.jredis.cluster.ClusterNodeSpec) */\n        public boolean removeNode (ClusterNodeSpec nodeSpec) {\n        \tif(null == nodeSpec)\n    \t\t\tthrow new IllegalArgumentException(\"null nodeSpec\");\n        \t\n    \t\treturn nodeSpecs.remove(nodeSpec);\n        }\n\n\t\t// ------------------------------------------------------------------------\n\t\t// accessors\n\t\t// ------------------------------------------------------------------------\n        \n//\t\t\n//    \t/* (non-Javadoc) @see org.jredis.cluster.ClusterSpec#getDistributionStrategy() */\n//    \tfinal public ClusterStrategy  getStrategy() {\n//    \t\treturn this.distributionStrategy;\n//    \t}\n    \t\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterSpec#getNodes() */\n//        @Override\n        final public Set<ClusterNodeSpec> getNodeSpecs () {\n        \tSet<ClusterNodeSpec> set = new HashSet<ClusterNodeSpec>(nodeSpecs.size());\n        \tfor(ClusterNodeSpec spec : nodeSpecs)\n        \t\tset.add(spec);\n\t        return set;\n        }\n\n//\t\t// ------------------------------------------------------------------------\n//\t\t// Extension points\n//\t\t// ------------------------------------------------------------------------\n//        protected abstract ClusterModel newStrategy();\n\t}\n\n}\n"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/ClusterType.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\n/**\n * We'll enumerate the various cluster types.\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 30, 2010\n * \n */\npublic enum ClusterType {\n\tCONSISTENT_HASH, \n\tSTATIC_HASH\n}"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/connector/ClusterConnection.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.connector;\n\nimport java.util.Collection;\nimport org.jredis.NotSupportedException;\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\n\n/**\n * An extension of {@link Connection}, as the interface to a cluster of Redis\n * servers (nodes).  \n * <p>\n * Given that this interface effectively represents a group of {@link Connection}s,\n * the implementations must provide a modified semantics regarding the\n * {@link ConnectionSpec} related methods and properties.  \n * <p>\n * <li>In general, we can not expect all the connections in a given cluster to have \n * identical {@link ConnectionSpec}s.  Calls to {@link Connection#getSpec()} must\n * throw a {@link NotSupportedException}.\n * <li>All the underlying {@link Connection}s for the cluster must have the\n * same {@link Connection.Modality} as that which is returned by the cluster's \n * {@link Connection#getModality()} method.\n * <p>\n * Further, some implementations may elect to not support Redis {@link Command}s \n * which are problematic in context of a cluster, and must accurately indicate\n * provision of support for {@link Command}s using the \n * {@link ClusterConnection#supports(Command)} method and \n * {@link ClusterConnection#getSupportedCommands()}.\n * \n * \n * @author  joubin (alphazero@sensesay.net)\n * @date    Apr 3, 2010\n * @see Connection\n * @see ClusterModel\n * @see ClusterSpec\n * @see ClusterNodeSpec\n * @see Command\n */\n\npublic interface ClusterConnection extends Connection{\n\n\t/**\n\t * \n\t * @return the {@link ClusterSpec} instance associated with this {@link ClusterConnection}.\n\t * The returned results must be identical to that which is returned by the \n\t * {@link ClusterModel#getSpec()} of the associated {@link ClusterModel} of this\n\t * connection.\n\t */\n\tpublic ClusterSpec getClusterSpec();\n\t\n\t/**\n\t * @return the {@link ClusterModel} instance associated with this {@link ClusterConnection}\n\t */\n\tpublic ClusterModel getClusterModel();\n\t\n\t/**\n\t * Indicates whether the specific {@link Command} is supported by this {@link ClusterConnection}.\n\t * @param cmd\n\t * @return\n\t */\n\tpublic boolean supports (Command cmd);\n\t\n\t/**\n\t * @return the set of {@link Command}s supported by this {@link ClusterConnection}\n\t */\n\tpublic Collection<Command> getSupportedCommands ();\n}\n"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/model/ConsistentHashCluster.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.model;\n\nimport java.util.SortedMap;\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.ClusterType;\n\n/**\n * Generalized interface for a {@link ClusterModel} using a Consistent Hashing strategy,\n * per the original paper by Karger, et al [1].\n * <p>\n * Requirements:\n * <li>Implementors must return {@link ClusterType#CONSISTENT_HASH} for {@link ClusterSpec#getType()}\n * \n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 30, 2010\n * @see [1]: <a href=\"http://www.akamai.com/dl/technical_publications/ConsistenHashingandRandomTreesDistributedCachingprotocolsforrelievingHotSpotsontheworldwideweb.pdf\">Consistent Hashing and Random Trees</a>\n */\n\n// TODO: extend from a new super DynamicClusterModel and fold all NodeMap event/mod apis to that interface\n\npublic interface ConsistentHashCluster extends ClusterModel {\n\t\n\t/**\n\t * Return the consistent hash node map.  Semantics of the this map are per the consistent hashing strategy paper and Ketama's implementation.\n\t * @return\n\t * @see ConsistentHashCluster.NodeMap\n\t */\n\tNodeMap getNodeMap ();\n\t\n\t// ========================================================================\n\t// Inner Types\n\t// ========================================================================\n\t\n\tpublic interface NodeMap extends SortedMap<Long, ClusterNodeSpec> {\n\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Support\n\t// ------------------------------------------------------------------------\n\t\n\tpublic abstract static class Support extends ClusterModel.Support implements ConsistentHashCluster {\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Properties\n\t\t// ------------------------------------------------------------------------\n\t\t\n\t\t/** what is a sensible value here? */\n\t\tprotected static final double DEFAULT_REPLICATION_CONST = 100;\n\t\t/**  */\n\t\tprotected NodeMap\tnodeMap;\n\t\t/**  */\n\t\tprotected int nodeReplicationCnt;\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// Constructor\n\t\t// ------------------------------------------------------------------------\n\t\t/**\n         * @param clusterSpec\n         */\n        protected Support (ClusterSpec clusterSpec) {\n\t        super(clusterSpec);\n        }\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Extension points\n\t\t// ------------------------------------------------------------------------\n        /**\n         * @return a new (un-initialized) instance of {@link ClusterNodeMap}.  This instance\n         * will be installed as the class's nodeMap attribute.\n         */\n        abstract protected NodeMap newClusterNodeMap();\n        \n        /**\n         * The meats and potatoes of this type of model. Invocation of this method\n         * means a complete computation of the node map per the current {@link ClusterSpec}. \n         */\n        abstract protected void mapNodes();\n        \n        /**\n         * TODO: need to change this to getReplicationConstant and \n         * TODO: extend ClusterSpec to allow setting of arbitrary parameters so it can be user configured.\n         * @return\n         */\n        abstract protected int replicationCount();\n\n        /**\n         * Can be overriden, but extending classes MUST call super.initializeComponents() as the\n         * first statement in the overriding method.\n         */\n        abstract protected void initializeComponents () ;\n//        protected void initializeComponents () {\n//        \tnodeReplicationCnt = replicationCount();\n//        \tnodeMap = newClusterNodeMap();\n//        }\n        \n\t\t// ------------------------------------------------------------------------\n\t\t// Inner ops\n\t\t// ------------------------------------------------------------------------\n        /**\n         * This method will first invoke {@link ConsistentHashCluster.Support#initializeComponents()},\n         * and then will invoke the abstract {@link ConsistentHashCluster.Support#mapNodes()}.\n         * <p>\n         * When this method returns, the cluster model is expected to be ready to service request to \n         * map keys to nodes.\n         * \n         * @see org.jredis.cluster.ClusterModel.Support#initializeModel()\n         */\n        @Override\n        final protected void initializeModel () {\n        \tinitializeComponents();\n//        \thashAlgo = new KetamaHashProvider();\n        \tnodeReplicationCnt = replicationCount();\n        \tnodeMap = newClusterNodeMap();\n        \tmapNodes();\n        }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel.Support#onNodeAddition(org.jredis.cluster.ClusterNodeSpec) */\n        @Override\n        protected boolean onNodeAddition (ClusterNodeSpec newNode) {\n        \tthrow new RuntimeException(\"not implemented\");        \n        }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel.Support#onNodeRemoval(org.jredis.cluster.ClusterNodeSpec) */\n        @Override\n        protected boolean onNodeRemoval (ClusterNodeSpec newNode) {\n        \tthrow new RuntimeException(\"not implemented\");        \n        }\n\n    \t/**\n    \t * TODO: return the map or clone it?  WHY IS METHOD EVEN NECESSARY?\n    \t * @see org.jredis.cluster.model.ConsistentHashCluster#getNodeMap()\n    \t * @return ???\n    \t */\n        public NodeMap getNodeMap () {\n    \t    return nodeMap;\n        }\n        \n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#supports(org.jredis.cluster.ClusterType) */\n        final public boolean supports (ClusterType type) {\n        \treturn type == ClusterType.CONSISTENT_HASH;\n        }\n\t}\n}\n"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/model/StaticHashCluster.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.model;\n\nimport java.util.Set;\nimport org.jredis.NotSupportedException;\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.ClusterType;\nimport org.jredis.cluster.support.HashAlgorithm;\n\n/**\n * A basic {@link ClusterModel} that uses hashing of keys to distribute keys \n * on a static set of nodes.  This type of cluster model obviously does not \n * support reconfiguration and brittle in face of server node failures.\n * <p>\n * Given that, the implementors of interface:\n * <li> must return <b>false</b> for {@link ClusterModel#supportsReconfiguration()}\n * <li> must return <b>true</b> for {@link ClusterModel#supports(org.jredis.cluster.ClusterType)} for {@link ClusterType#STATIC_HASH}\n * <li> must return <b>false</b> for {@link ClusterModel#supports(org.jredis.cluster.ClusterType)} for all other {@link ClusterType}s.\n * <li> must throw {@link NotSupportedException} for {@link ClusterModel#addNode(org.jredis.cluster.ClusterNodeSpec)}\n * <li> must throw {@link NotSupportedException} for {@link ClusterModel#removeNode(org.jredis.cluster.ClusterNodeSpec)}\n * \n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 30, 2010\n * @see ConsistentHashCluster\n * @see ClusterType\n */\n\npublic interface StaticHashCluster extends ClusterModel {\n\n\tpublic abstract static class Support extends ClusterModel.Support implements StaticHashCluster {\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Props\n\t\t// ------------------------------------------------------------------------\n\t\t/** */\n\t\tprotected HashAlgorithm hashAlgo;\n\t\t/**  */\n\t\tprotected int nodeCnt;\n\t\t/**  */\n\t\tprotected ClusterNodeSpec[] nodes;\n\t\t\n\t\t// ------------------------------------------------------------------------\n\t\t// Constructor\n\t\t// ------------------------------------------------------------------------\n\t\t/**\n         * @param clusterSpec\n         */\n        protected Support (ClusterSpec clusterSpec) {\n\t        super(clusterSpec);\n        }\n\n\t\t// ------------------------------------------------------------------------\n\t\t// Extension points\n\t\t// ------------------------------------------------------------------------\n        \n        /**\n         * Extensions are expected to plugin their specific {@link HashAlgorithm} here.\n         * @return\n         */\n        abstract protected HashAlgorithm newHashAlgorithm();\n        \n\t\t// ------------------------------------------------------------------------\n\t\t// finalized super overrides\n\t\t// ------------------------------------------------------------------------\n        \n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel.Support#initializeModel() */\n        @Override\n        final protected void initializeModel () {\n        \thashAlgo = newHashAlgorithm ();\n        \tSet<ClusterNodeSpec> nodeSpecs = clusterSpec.getNodeSpecs();\n        \tnodeCnt = nodeSpecs.size();\n        \tnodes = new ClusterNodeSpec[nodeCnt];\n        \tnodes = nodeSpecs.toArray(nodes);\n        }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel.Support#onNodeAddition(org.jredis.cluster.ClusterNodeSpec) */\n        @Override\n        final protected boolean onNodeAddition (ClusterNodeSpec newNode) {\n        \tthrow new NotSupportedException (\"node addition\");\n        }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel.Support#onNodeRemoval(org.jredis.cluster.ClusterNodeSpec) */\n        @Override\n        final protected boolean onNodeRemoval (ClusterNodeSpec newNode) {\n        \tthrow new NotSupportedException (\"nodeRemoval\");\n        }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#supports(org.jredis.cluster.ClusterType) */\n        final public boolean supports (ClusterType type) {\n\t        return type == ClusterType.STATIC_HASH;\n        }\n\n\t\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#supportsReconfiguration() */\n        final public boolean supportsReconfiguration () {\n\t        return false;\n        }\n\t}\n}\n"
  },
  {
    "path": "extensions/api/src/main/java/org/jredis/cluster/support/HashAlgorithm.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.support;\n\n/**\n * silly me?  Remove this.\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 24, 2010\n * \n */\n\npublic interface HashAlgorithm {\n\tpublic long hash(byte[] kb);\n}\n"
  },
  {
    "path": "extensions/pom.xml",
    "content": "<!-- ~/extensions/pom.xml -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <!-- parent -->\n  <parent>\n    <groupId>org.jredis</groupId>\n    <artifactId>jredis</artifactId>\n    <version>${jredisVersion}</version>\n  </parent>\n\n  <!-- coordination | build pom -->\n  <name>JRedis - Extensions [Build POM]</name>\n  <groupId>org.jredis</groupId>\n  <artifactId>jredis-extensions</artifactId>\n  <version>${jredisVersion}</version>\n  <packaging>pom</packaging>\n\n  <!-- production units -->\n  <modules>\n    <module>api</module>\n    <module>ri</module>\n  </modules>\n  \n  <!-- extensions specific surefire testrunner-->\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-surefire-plugin</artifactId>\n        <configuration>\n          <systemProperties>\n            <!-- TestNG parameters -->\n            <!-- TODO: generic test params should be in the root toplevel pom .. -->\n            <!-- redis core tests | Service params -->\n            <property><name>jredis.cluster.node.cnt</name><value>100</value></property>\n            <property><name>jredis.cluster.node.address.base</name><value>localhost</value></property>\n            <property><name>jredis.cluster.node.port.base</name><value>6379</value></property>\n\n          </systemProperties>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n\n  <!-- info -->\n  <licenses>\n    <license>\n      <name>Apache 2</name>\n      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n      <distribution>all</distribution>\n      <comments>Copyright 2009-2010 (c) Joubin Houshyar - All Right Resererved</comments>\n    </license>\n  </licenses>\n  <developers>\n    <developer>\n      <id>joubin</id>\n      <name>Joubin Houshyar</name>\n      <email>alphazero@sensesay.net</email>\n      <url>http://www.sensesay.net</url>\n      <roles>\n        <role>ReleaseManager</role>\n        <role>Designer</role>\n        <role>Developer</role>\n      </roles>\n      <timezone>UTC-5</timezone>\n    </developer>\n  </developers>\n</project>\n"
  },
  {
    "path": "extensions/ri/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "extensions/ri/NOTICE",
    "content": "Copyright 2009-2012, Joubin Houshyar. \n\nAll parts of the original works in JReids are licensed under the \nApache License ver 2.0 http://www.apache.org/licenses.\n\nEach sub-project contains a NOTICE file with additional notices,\nwhich may contain additional licensing information.\n\nEND OF NOTICE\n\n"
  },
  {
    "path": "extensions/ri/README.markdown",
    "content": "# Reference implementation of JRedis Extensions\n\nExtended functionality for [JRedis]\n\n[JRedis]: http://github.com/alphazero/jredis\n"
  },
  {
    "path": "extensions/ri/pom.xml",
    "content": "<!-- ~/extensions/api/pom.xml -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <!-- parent -->\n  <parent>\n    <groupId>org.jredis</groupId>\n    <artifactId>jredis-extensions</artifactId>\n\t<version>${jredisVersion}</version>\n  </parent>\n\n  <!-- production | jar -->\n  <name>JRedis - Extensions - RI</name>\n  <groupId>org.jredis</groupId>\n  <artifactId>jredis-extensions-ri</artifactId>\n  <version>${jredisVersion}</version>\n  <packaging>jar</packaging>\n  \n  <dependencies>\n  \n    <!-- core api -->\n    <dependency>\n      <groupId>org.jredis</groupId>\n      <artifactId>jredis-core-api</artifactId>\n\t  <version>${jredisVersion}</version>\n    </dependency>\n\n    <!-- core ri -->\n    <dependency>\n      <groupId>org.jredis</groupId>\n      <artifactId>jredis-core-ri</artifactId>\n\t  <version>${jredisVersion}</version>\n    </dependency>\n    \n    <!-- extensions api -->\n    <dependency>\n      <groupId>org.jredis</groupId>\n      <artifactId>jredis-extensions-api</artifactId>\n\t  <version>${jredisVersion}</version>\n    </dependency>\n\n    <!-- unit testing -->\n    <dependency>\n      <groupId>org.testng</groupId>\n      <artifactId>testng</artifactId>\n      <version>6.1.1</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n  \n  <build>\n    <plugins>\n      <plugin>\n        <artifactId>maven-assembly-plugin</artifactId>\n        <version>2.1</version>\n        <executions>\n          <execution>\n            <id>simple-install</id>\n            <phase>package</phase>\n            <goals>\n              <goal>attached</goal>\n            </goals>\n          </execution>\n        </executions>\n        <configuration>\n          <descriptorRefs>\n            <descriptorRef>jar-with-dependencies</descriptorRef>\n          </descriptorRefs>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n  \n</project>\n"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/DefaultClusterNodeSpec.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster;\n\nimport java.net.Socket;\nimport java.util.Formatter;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n\n/**\n * A basic {@link ClusterNodeSpec} that uses the basic configuration information\n * (address, port) to generate unique ids and replication instance keys.  Note that\n * while {@link ConnectionSpec} as of JRedis 1.0 distinguishes between DBs, given\n * that the the Redis 1.3.n compliant library will have stateful connections that would\n * allow use of SELELCT to change the DB, this class also does NOT distinguish between\n * two {@link ConnectionSpec}s that are identical but have different DB specification.\n * \n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 25, 2010\n * \n */\n\npublic class DefaultClusterNodeSpec extends ClusterNodeSpec.Support implements ClusterNodeSpec {\n\t// ------------------------------------------------------------------------\n\t// Attrs\n\t// ------------------------------------------------------------------------\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructor(s)\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @param connSpec\n\t * @throws IllegalArgumentException \n\t */\n\tpublic DefaultClusterNodeSpec(ConnectionSpec connSpec){\n\t\tsuper(connSpec);\n\t}\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ------------------------------------------------------------------------\n\t\n\tpublic static ClusterNodeSpec getSpecFor(Socket conn){\n\t\tif(null == conn) throw new IllegalArgumentException(\"null arg [conn]\");\n\t\tConnectionSpec connSpec = DefaultConnectionSpec.newSpec(conn.getInetAddress(), conn.getPort(), 0, null);\n\t\treturn new DefaultClusterNodeSpec(connSpec);\n\t}\n\t// ------------------------------------------------------------------------\n\t// Identity\n\t// ------------------------------------------------------------------------\n    \n\t// ------------------------------------------------------------------------\n\t// Extension points\n\t// ------------------------------------------------------------------------\n    /**\n     * Method is called once (and only once) by the constructor to set the\n     * final {@link Support#id} field.  This (default) implementation simply\n     * creates a string of form <ip-address-string-rep>:<0-padded-5-digit-port-number>.\n     * <p>ex: <code>\"127.0.0.1:06379\" </code>\n     * <p>\n     * <b>Method is not finalized to allow further specializations</b>\n     * @return\n     */\n    protected String generateId () {\n    \tFormatter fmt = new Formatter();\n    \tfmt.format(\"%s:%05d\", \n    \t\t\tthis.connSpec.getAddress().getHostAddress(),\n    \t\t\tthis.connSpec.getPort()\n    \t\t);\n    \treturn fmt.toString();\n    }\n\n    /**\n     * Default implementation will simply return a string of form\n     * <node-id>[<@see org.jredis.cluster.ClusterNodeSpec#getKeyForCHRangeInstance(int)>]\n     * <p>\n     * Optional extension point. \n     * @param rangeReplicationIndex\n     * @see org.jredis.cluster.ClusterNodeSpec#getKeyForReplicationInstance(int)\n     */\n//    @Override\n    public String getKeyForReplicationInstance (int rangeReplicationIndex) {\n    \tFormatter fmt = new Formatter();\n    \tfmt.format(\"%s[%d]\",  this.id, rangeReplicationIndex);\n    \treturn fmt.toString();\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/DefaultClusterSpec.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster;\n\nimport java.util.Collection;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.ClusterType;\nimport org.jredis.cluster.ClusterSpec.Support;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n\n/**\n * The default ClusterSpec uses the {@link KetamaConsitentHashCluster_reture} as its {@link ClusterModel_deprecated}. \n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 25, 2010\n * \n */\n\npublic class DefaultClusterSpec extends Support implements ClusterSpec {\n\t\n\t/** Default ClusterSpec.Type is {@link ClusterType#CONSISTENT_HASH} */\n\tpublic static final ClusterType DEFAULT_CLUSTER_TYPE = ClusterType.CONSISTENT_HASH;\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructor\n\t// ------------------------------------------------------------------------\n\t\n\tpublic DefaultClusterSpec () {\n\t\tthis(null);\n\t}\n\n\tpublic DefaultClusterSpec (Collection<ClusterNodeSpec> nodeSpecs) {\n\t\tsuper();\n\t\tthis.setType(DEFAULT_CLUSTER_TYPE);\n\t\tif(null != nodeSpecs){\n\t\t\taddAll(nodeSpecs);\n\t\t}\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// public interface\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * @param host\n\t * @param firstPort\n\t * @param lastPort\n\t * @param templateConnSpec\n\t * @return\n\t */\n\tpublic static ClusterSpec newSpecForRange (ConnectionSpec templateConnSpec, int firstPort, int lastPort) {\n\t\tClusterSpec spec = new DefaultClusterSpec();\n\t\tfor(int i=firstPort; i<=lastPort; i++){\n\t\t\tConnectionSpec connSpec = DefaultConnectionSpec.newSpec()\n\t\t\t\t.setAddress(templateConnSpec.getAddress())\n\t\t\t\t.setPort(i)\n\t\t\t\t.setDatabase(templateConnSpec.getDatabase())\n\t\t\t\t.setCredentials(templateConnSpec.getCredentials());\n\t\t\tClusterNodeSpec nodeSpec = new DefaultClusterNodeSpec(connSpec);\n\t\t\tspec.addNode(nodeSpec);\n\t\t}\n\t\treturn spec;\n\t}\n\t// ------------------------------------------------------------------------\n\t// super overrides\n\t// ------------------------------------------------------------------------\n}\n"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/connection/ClusterConnectionBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster.connection;\n\nimport static org.jredis.ri.alphazero.support.Assert.*;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.Future;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.RedisException;\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.connector.ClusterConnection;\nimport org.jredis.connector.Connection;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 29, 2010\n * \n */\n\nabstract public class ClusterConnectionBase implements ClusterConnection, Connection.Listener {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/**  */\n\tfinal protected ClusterModel model;\n\t/**  */\n\tfinal private Set<Command> supportedCmds = new HashSet<Command>();\n\t/**  */\n\tfinal private Map<String, Connection> connections = new HashMap<String, Connection>();\n\t/** Connector Listeners */\n\tfinal private Set<Connection.Listener> listeners = new HashSet<Connection.Listener>();\n\n\t// ------------------------------------------------------------------------\n\t// Constructor\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Convenience form for default immediate connection to the nodes.\n\t * @param model\n\t * @throws ClientRuntimeException\n\t * @see {@link ClusterConnectionBase#ClusterConnectionBase(ClusterModel, boolean)}\n\t */\n\tprotected ClusterConnectionBase (ClusterModel model) \n\tthrows ClientRuntimeException\n\t{\n\t\tthis(model, true);\n\t}\n\n\t/**\n\t * @param model\n\t * @param connectImmediately\n\t * @throws ClientRuntimeException\n\t */\n\tprotected ClusterConnectionBase (ClusterModel model, boolean connectImmediately) \n\tthrows ClientRuntimeException\n\t{\n\t\tthis.model = notNull(model, \"ClusterModel param for constructor\", ClientRuntimeException.class); \n\n\t\t// model integrity checks\n\t\t//\n\t\tClusterSpec spec = notNull(model.getSpec(), \"ClusterModel's ClusterSpec property\", ClientRuntimeException.class); \n\t\tCollection<ClusterNodeSpec> nodeSpecs = notNull(spec.getNodeSpecs(), \"ClusterSpec's nodes\", ClientRuntimeException.class);\n\t\tisTrue(nodeSpecs.size() > 1, \"ClusterSpec node count\", ClientRuntimeException.class);\n\n\t\t// initialize cluster's connections\n\t\tinitialize();\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ===================================================== ClusterConnection\n\t/*\n\t * General methods of the interface are supported in this base class and the\n\t * rest left for the specialized extensions.\n\t */\n\t// ------------------------------------------------------------------------\n\n\t/* (non-Javadoc) @see org.jredis.cluster.connector.ClusterConnection#getClusterModel() */\n\tfinal public ClusterModel getClusterModel () { return model; }\n\n\t/* (non-Javadoc) @see org.jredis.cluster.connector.ClusterConnection#getClusterSpec() */\n\tfinal public ClusterSpec getClusterSpec () { return model.getSpec(); }\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#getSpec() */\n\tfinal public ConnectionSpec getSpec () {\n\t\tthrow new NotSupportedException (\"Per specification -- see org.jredis.cluster.ClusterConnection's specification.\");\n\t}\n\t\n\t/* (non-Javadoc) @see org.jredis.cluster.connector.ClusterConnection#getSupportedCommands() */\n\tfinal public Collection<Command> getSupportedCommands () {\n\t\treturn Collections.unmodifiableSet(supportedCmds);\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.cluster.connector.ClusterConnection#supports(org.jredis.protocol.Command) */\n\tfinal public boolean supports (Command cmd) {\n\t\treturn supportedCmds.contains(cmd);\n\t}\n\t\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#queueRequest(org.jredis.protocol.Command, byte[][]) */\n\tpublic Future<Response> queueRequest (Command cmd, byte[]... args)\n\t        throws ClientRuntimeException, ProviderException \n    {\n\t\tbyte[] key = verifyAndGetKeyForRequest(cmd, args);\n\t\treturn getConnectionForKey(key).queueRequest(cmd, args);\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#serviceRequest(org.jredis.protocol.Command, byte[][]) */\n\tpublic Response serviceRequest (Command cmd, byte[]... args)\n\t        throws RedisException, ClientRuntimeException, ProviderException\n    {\n\t\tbyte[] key = verifyAndGetKeyForRequest(cmd, args);\n\t\treturn getConnectionForKey(key).serviceRequest(cmd, args);\n\t}\n\t// ------------------------------------------------------------------------\n\t// Event management\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#addListener(org.jredis.connector.Connection.Listener) */\n\tfinal public boolean addListener(Listener connListener){\n\t\treturn listeners.add(connListener);\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#removeListener(org.jredis.connector.Connection.Listener) */\n\tfinal public boolean removeListener(Listener connListener){\n\t\treturn listeners.remove(connListener);\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// =================================================== Connection.Listener\n\t/*\n\t * TODO: monitor all connections and deal with faults\n\t */\n\t// ------------------------------------------------------------------------\n\n\tpublic void onEvent(Connection.Event event) {\n\t\tConnection conn = event.getSource();\n\t\tif(!connections.containsKey(conn)){\n\t\t\tthrow new ProviderException(\"ClusterConnection receiving events for unrelated connection!\");\n\t\t}\n\t\t\n\t\t// TODO: deal with it!\n\t\tConnection.Event.Type type = event.getType();\n\t\tswitch (type) {\n\t\tcase DISCONNECTED:\n\t\t\tbreak;\n\t\tcase CONNECTED:\n\t\t\tbreak;\n\t\tcase FAULTED:\n\t\t\tbreak;\n\t\t}\n\t\tthrow new ProviderException(\"[BUG] lazy programmer -- TODOs here!\");\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Internal ops\n\t// ------------------------------------------------------------------------\n\n\tfinal private byte[] verifyAndGetKeyForRequest(Command cmd, byte[]...args) \n\t{\n\t\tnotNull(args, \"[BUG]: args for request is null!\", ProviderException.class);\n\t\tisTrue(args.length > 0, \"[BUG]: expecting at least 1 arg for the request (and a key at that)\", ProviderException.class);\n\t\tisTrue(supports(cmd), cmd.name() + \" is not supported\", NotSupportedException.class);\n\t\treturn args[0];\n\t\t\n\t}\n\tfinal protected void initialize () throws ClientRuntimeException, ProviderException {\n\t\tmapSupportedCommands();\n\t\tinitializeConnections();\n\t\tinitializeComponents();\n\t}\n\n\tfinal private void initializeConnections () throws ClientRuntimeException, ProviderException {\n\t\tfor(ClusterNodeSpec nodeSpec : model.getSpec().getNodeSpecs()){\n\t\t\tConnection conn = null;\n\t\t\tif(getModality() == Connection.Modality.Synchronous){\n\t\t\t\tconn = notNull(createSynchConnection(nodeSpec), \"\", ProviderException.class);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconn = notNull(createAsynchConnection(nodeSpec), \"\", ProviderException.class);\n\t\t\t}\n\t\t\tconnections.put(nodeSpec.getId(), conn);\n\t\t\t// TODO: add set as listener to connection\n\t\t}\n\t}\n\t/**\n\t * Default implementation simply includes all {@link Command}s with {@link Command.RequestType}s\n\t * that include key params in the request.\n\t */\n\tfinal private void mapSupportedCommands () {\n\t\t// filter out the unsupported commands\n\t\t//\n\t\tfor(Command cmd : Command.values()){\n\t\t\tswitch (cmd.requestType){\n\t\t\t\n\t\t\t// -- NOT SUPPORTED --\n\t\t\tcase BULK_SET:\n\t\t\tcase NO_ARG:\n\t\t\tcase VALUE:\n\t\t\t\tif(!affirmLackOfSupportFor(cmd))\n\t\t\t\t\tsupportedCmds.add(cmd);\n\t\t\t\tbreak;\n\n\t\t\t\t// -- SUPPORTED --\n\t\t\tcase KEY:\n\t\t\tcase KEY_CNT_VALUE:\n\t\t\tcase KEY_IDX_VALUE:\n\t\t\tcase KEY_KEY:\n\t\t\tcase KEY_KEY_VALUE:\n\t\t\tcase KEY_NUM:\n\t\t\tcase KEY_NUM_NUM:\n\t\t\tcase KEY_NUM_NUM_OPTS:\n\t\t\tcase KEY_SPEC:\n\t\t\tcase KEY_VALUE:\n\t\t\tcase MULTI_KEY:\n\t\t\t\tif(affirmSupportFor(cmd))\n\t\t\t\t\tsupportedCmds.add(cmd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tfinal protected Connection getConnectionForKey(byte[] key){\n\t\tClusterNodeSpec nodeSpec = model.getNodeForKey(key);\n\t\tString nodeId = nodeSpec.getId();\n\t\t\n\t\t// TEMP TEMP TEMP.\n\t\treturn connections.get(nodeId);\n\t}\n\t// ------------------------------------------------------------------------\n\t// Internal ops : Extension points\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Extension point for subclasses.  This method is guaranteed to be called\n\t * exactly once during the instantiation process. \n\t */\n\tabstract protected void initializeComponents () ;\n\n\t/**\n\t * By default returns true.  Override to veto default command mappings.\n     * @param cmd\n     * @return\n     */\n    protected boolean affirmSupportFor (Command cmd) { return true; }\n\n\t/**\n\t * By default returns true.  Override to veto default command mappings.\n     * @param cmd\n     * @return\n     */\n    protected boolean affirmLackOfSupportFor (Command cmd) {return true; }\n\n\t/**\n     * @param nodeSpec\n     * @return\n     */\n    protected Connection createAsynchConnection (ClusterNodeSpec nodeSpec) {\n    \tthrow new ProviderException(\"Not implemented in the abstract base!\");\n    }\n\n\t/**\n     * @param nodeSpec\n     * @return\n     */\n    protected Connection createSynchConnection (ClusterNodeSpec nodeSpec) {\n    \tthrow new ProviderException(\"Not implemented in the abstract base!\");\n    }\n\n\n}\n"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/connection/SynchClusterConnection.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster.connection;\n\nimport java.util.concurrent.Future;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ProviderException;\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.connector.Connection;\nimport org.jredis.protocol.Command;\nimport org.jredis.protocol.Response;\nimport org.jredis.ri.alphazero.connection.SynchConnection;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Apr 3, 2010\n * \n */\n\npublic class SynchClusterConnection extends ClusterConnectionBase {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n     * @param model\n     * @throws ClientRuntimeException\n     */\n    protected SynchClusterConnection (ClusterModel model, boolean connectImmediately) throws ClientRuntimeException {\n\t    super(model, connectImmediately);\n    }\n\n\t// ------------------------------------------------------------------------\n\t// Constructor\n\t// ------------------------------------------------------------------------\n\t/**\n     * @param model\n     * @throws ClientRuntimeException\n     */\n    protected SynchClusterConnection (ClusterModel model) throws ClientRuntimeException {\n\t    super(model);\n    }\n\n\t/* (non-Javadoc) @see org.jredis.ri.cluster.connection.ClusterConnectionBase#initializeComponents() */\n\t@Override\n\tprotected void initializeComponents () {\n\t\t// TODO Auto-generated method stub\n\t\tthrow new ProviderException(\"[LAZY] implement me!\");\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ===================================================== ClusterConnection\n\t/*\n\t * General methods of the interface are supported in this base class and the\n\t * rest left for the specialized extensions.\n\t */\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#getModality() */\n\tfinal public Modality getModality () { return Connection.Modality.Synchronous; }\n\n\t/* (non-Javadoc) @see org.jredis.connector.Connection#queueRequest(org.jredis.protocol.Command, byte[][]) */\n\tfinal public Future<Response> queueRequest (Command cmd, byte[]... args)\n\t        throws ClientRuntimeException, ProviderException \n    {\n\t\tthrow new NotSupportedException(\"Not supported by abstract base class\");\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Super overrides\n\t// ------------------------------------------------------------------------\n\t/**\n     * @param nodeSpec\n     * @return\n     */\n    protected Connection createSynchConnection (ClusterNodeSpec nodeSpec) {\n    \tConnection conn = null;\n    \tconn = new SynchConnection(nodeSpec.getConnectionSpec(), true);\n    \treturn conn;\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/model/BasicStaticHashCluster.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster.model;\n\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.model.StaticHashCluster;\nimport org.jredis.cluster.support.HashAlgorithm;\n\n/**\n * As barebones as it gets. Uses the key's hashCode() (that is {@link byte[]#hashCode()})\n * to compute a node index, using a basic hashcode % nodeCnt as the index to the nodes list.\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 30, 2010\n * \n */\n\npublic class BasicStaticHashCluster extends StaticHashCluster.Support implements StaticHashCluster {\n\t\n\t// ------------------------------------------------------------------------\n\t// Constructor\n\t// ------------------------------------------------------------------------\n\t/**\n     * @param clusterSpec\n     */\n    public BasicStaticHashCluster (ClusterSpec clusterSpec) {\n\t    super(clusterSpec);\n    }\n\n\t// ------------------------------------------------------------------------\n\t// super overrides\n\t// ------------------------------------------------------------------------\n    \n\t/* (non-Javadoc) @see org.jredis.cluster.model.StaticHashCluster.Support#newHashAlgorithm() */\n    @Override\n    protected HashAlgorithm newHashAlgorithm () {\n    \t// TDOO: get this from the clusterspec\n\t    return new HashAlgorithm() {\n\t\t\tpublic long hash (byte[] kb) {\n\t            return kb.hashCode();\n            }\n\t    };\n    }\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#getNodeForKey(byte[]) */\n    public ClusterNodeSpec getNodeForKey (byte[] key) {\n\t    int nodeIdx = (int) (hashAlgo.hash(key)%nodeCnt);\n\t    return nodes[nodeIdx];\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/model/KetamaClusterModel.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster.model;\n\nimport java.util.Set;\nimport java.util.SortedMap;\nimport java.util.TreeMap;\nimport org.jredis.ProviderException;\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\n//import org.jredis.cluster.model.ClusterNodeMap;\nimport org.jredis.cluster.model.ConsistentHashCluster;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.jredis.ri.cluster.support.CryptoHashUtils;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 29, 2010\n * \n */\n\npublic class KetamaClusterModel extends ConsistentHashCluster.Support implements ConsistentHashCluster {\n\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t/**  */\n\tprotected KetamaHashProvider hashAlgo;\n\t\n\t// ------------------------------------------------------------------------\n\t// Properties\n\t// ------------------------------------------------------------------------\n\t\n\t/** \n\t * Instantiate and initialize the node mape of a Ketama-based {@link ClusterModel}.\n     * @param clusterSpec\n     */\n    public KetamaClusterModel (ClusterSpec clusterSpec) {\n\t    super(clusterSpec);\n    }\n\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ------------------------------------------------------------------------\n    \n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#getNodeForKey(byte[]) */\n\tpublic ClusterNodeSpec getNodeForKey (byte[] key) {\n\t\tlong hash = hashAlgo.hash(key);\n\t\tfinal ClusterNodeSpec rv;\n\t\tif(!nodeMap.containsKey(hash)) {\n\t\t\t// Java 1.6 adds a ceilingKey method, but I'm still stuck in 1.5\n\t\t\t// in a lot of places, so I'm doing this myself.\n\t\t\tSortedMap<Long, ClusterNodeSpec> tailMap=nodeMap.tailMap(hash);\n\t\t\tif(tailMap.isEmpty()) {\n\t\t\t\thash = nodeMap.firstKey();\n\t\t\t} \n\t\t\telse {\n\t\t\t\thash=tailMap.firstKey();\n\t\t\t}\n\t\t}\n\t\trv = nodeMap.get(hash);\n\t\treturn rv;\n\t}\n\t\n//\t/**\n//\t * TODO: return the map or clone it?  WHY IS METHOD EVEN NECESSARY?\n//\t * @see org.jredis.cluster.model.ConsistentHashCluster#getNodeMap()\n//\t * @return ???\n//\t */\n//    public NodeMap getNodeMap () {\n//\t    return nodeMap;\n//    }\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel#supportsReconfiguration() */\n    public boolean supportsReconfiguration () {\n\t    return false;\n    }\n    \n    // ------------------------------------------------------------------------\n    // Inner Ops\n    // ------------------------------------------------------------------------\n    \n\t/**\n\t * Per original paper on consistent hashing, the replication count of any given bucket is\n\t * k*log(C), where C is the number of buckets (i.e. nodes).  We're using {@link KetamaNodeMapper#DEFAULT_REPLICATION_CONST}\n\t * as k.\n\t * \n     * @param nodeCnt number of server nodes (\"buckets\" per original paper) in the Ketama cluster\n     * @return\n     */\n    @Override\n    final protected int replicationCount(){\n    \tint nodeCnt = clusterSpec.getNodeSpecs().size();\n    \treturn (int) (Math.log(nodeCnt) * DEFAULT_REPLICATION_CONST);    \t\n    }\n    \n    @Override\n    final protected NodeMap newClusterNodeMap() {return new KetamaNodeMap(); }\n    \n    @Override\n    final protected void initializeComponents() {\n//    \tsuper.initializeComponents();\n    \thashAlgo = new KetamaHashProvider();\n    }\n\n\t/**\n\t * This method is a slightly modified version of net.spy.memcached.KetamaNodeLocator's constructor.\n\t * @see <a href=\"http://github.com/????????/\">GIT HUB LINK HERE ...</a>\n\t */\n\n    @Override\n\tfinal protected void mapNodes () \n\t{\t\t\n\t\ttry {\n\t\t\tSet<ClusterNodeSpec> \tnodes = clusterSpec.getNodeSpecs();\n\t\t\tfor(ClusterNodeSpec node : nodes) {\n\t\t\t\tmapNode(node);\n\t\t\t}\n\t\t\tif(nodeMap.size() != (nodeReplicationCnt/4) * nodes.size() * 4) {\n\t\t\t\tLog.error(\"nodeMap size: \" + nodeMap.size() + \" | expected: \" + nodeReplicationCnt * nodes.size());\n\t\t\t\tthrow new ProviderException (\"[BUG]: expecting node map size to be multiple of replication count * cluster node count\");\n\t\t\t}\n\t\t}\n\t\tcatch (ClassCastException e) {\n\t\t\tthrow new ProviderException (\"[BUG] KetamaNodeMappingAlgorithm requires a KetamaHashAlgorithm\");\n\t\t}\n\t}\n\n\tprivate boolean mapNode(ClusterNodeSpec node){\n\t\t// Dustin says: \"Ketama does some special work with md5 where it reuses chunks.\"\n\t\tfor(int i=0; i<nodeReplicationCnt / 4; i++) {\n\t\t\tbyte[] digest;\n\t\t\tdigest = CryptoHashUtils.computeMd5(node.getKeyForReplicationInstance(i));\n\t\t\tfor(int h=0;h<4;h++) {\n\t\t\t\t// Joubin says: here's we're calling a KetamaHashProvider specific method that does the \n\t\t\t\t// Ketama chunking per above.  \n\t\t\t\tnodeMap.put(hashAlgo.hash(digest, h), node);\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n    \n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel.Support#onNodeAddition(org.jredis.cluster.ClusterNodeSpec) */\n    @Override\n    protected boolean onNodeAddition (ClusterNodeSpec newNode) {\n    \tthrow new ProviderException(\"[BUG] basic KetamaClusterModel does NOT support reconfiguration of nodes\");\n    }\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModel.Support#onNodeRemoval(org.jredis.cluster.ClusterNodeSpec) */\n    @Override\n    protected boolean onNodeRemoval (ClusterNodeSpec newNode) {\n    \tthrow new ProviderException(\"[BUG] basic KetamaClusterModel does NOT support reconfiguration of nodes\");\n    }\n\n    \n    // ========================================================================\n    // Inner Types\n    // ========================================================================\n    \n\t// ------------------------------------------------------------------------\n\t// ClusterNodeMap impl.\n\t// ------------------------------------------------------------------------\n\t\n    @SuppressWarnings(\"serial\")\n//    public static class NodeMap extends TreeMap<Long, ClusterNodeSpec> implements SortedMap<Long, ClusterNodeSpec>{\n    public class KetamaNodeMap extends TreeMap<Long, ClusterNodeSpec> implements ConsistentHashCluster.NodeMap {\n    \t// TODO: iterator, etc.\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/model/KetamaHashProvider.java",
    "content": "/* -- BEGIN NOTICE --\n * \n * This class uses in parts extant and/or modified code from net.spy.memcached.HashAlgorithm\n * by Dustin Sallings.  See this module's 3rd party license folder for license details.\n * \n * -- END NOTICE -- \n * \n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\n\npackage org.jredis.ri.cluster.model;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.cluster.support.HashAlgorithm;\nimport org.jredis.ri.cluster.support.CryptoHashUtils;\n\n/**\n * The Ketama consistent hash algorithm as implemented by Dustin Sallings,\n * with some minor (non-algorithmic) modifications.\n * <p>\n * <b>Note</b> that if certain expected cryptographic algorithms expected to be \n * present in your JRE are not available, {@link ClientRuntimeException}s \n * will be thrown.\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 25, 2010\n * \n */\n\npublic class KetamaHashProvider implements HashAlgorithm {\n\n\t// ------------------------------------------------------------------------\n\t// Interface\n\t// ------------------------------------------------------------------------\n\n\t/**\n\t * Uses MD5 digest.  \n\t * <p>\n\t * Contains code from net.spy.memecached.\n\t * @ Copyright (c) 2006-2009  Dustin Sallings <dustin@spy.net>\n\t * \n\t * @param b bytes to be hashed\n\t */\n//\t@Override\n\tpublic long hash (byte[] b) {\n\t\tif(null == b || b.length ==0) throw new IllegalArgumentException();\n\t\t\n\t\t/* Copyright (c) 2006-2009  Dustin Sallings <dustin@spy.net> */\n\t\t/* -- BEGIN code segment */\n\t\tbyte[] kb;\n\t\tlong rv = 0;\n        kb = CryptoHashUtils.computeMd5(b);\n\t\trv = ((long) (kb[3] & 0xFF) << 24)\n\t\t| ((long) (kb[2] & 0xFF) << 16)\n\t\t| ((long) (kb[1] & 0xFF) << 8)\n\t\t| (kb[0] & 0xFF);\n\t\t/* -- END code segment */\n\t\t\n\t\treturn rv;\n\t}\n\t// ------------------------------------------------------------------------\n\t// Ketama specific and for Ketama package only\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * Rip of the inner loop of the KetamaNodeLocator's constructor, in full.\n\t * <p>\n\t * @ Copyright (c) 2006-2009  Dustin Sallings <dustin@spy.net>\n\t * \n\t * @param digest\n\t * @param h\n\t * @return\n\t */\n\tlong hash (byte[] digest, int h) {\n\t\treturn \n\t\t\t((long)(digest[3+h*4]&0xFF) << 24)\n\t\t\t| ((long)(digest[2+h*4]&0xFF) << 16)\n\t\t\t| ((long)(digest[1+h*4]&0xFF) << 8)\n\t\t\t| (digest[h*4]&0xFF);\n\t}\n}"
  },
  {
    "path": "extensions/ri/src/main/java/org/jredis/ri/cluster/support/CryptoHashUtils.java",
    "content": "/* -- BEGIN NOTICE --\n * \n * This class uses in parts extant and/or modified code from net.spy.memcached.HashAlgorithm\n * by Dustin Sallings.  See this module's 3rd party license folder for license details.\n * \n * -- END NOTICE -- \n * \n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster.support;\n\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport org.jredis.ClientRuntimeException;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 26, 2010\n * \n */\n\npublic class CryptoHashUtils {\n\t/**\n\t * Get the md5 of the given key. \n\t * @throws ClientRuntimeException if MD5 algorithm is not supported.\n\t * @throws IllegalArgumentException if input is null or zero length\n\t * \n\t * @Copyright (c) 2006-2009  Dustin Sallings <dustin@spy.net> \n\t */\n\tpublic static byte[] computeMd5(byte[] b) throws ClientRuntimeException{\n\t\tif(null == b) throw new IllegalArgumentException (\"null input\");\n\t\tif(b.length == 0) throw new IllegalArgumentException (\"zero length input\");\n\t\tMessageDigest md5 = null;\n\t\ttry {\n\t        md5 = MessageDigest.getInstance(\"MD5\");\n\t\t\tmd5.reset();\n\t\t\tmd5.update(b);\n        }\n        catch (NoSuchAlgorithmException e) {\n        \tthrow new ClientRuntimeException(\"MD5 Message Digest algorithm is not present in this JRE\", e);\n        }\n\t\treturn md5.digest();\n\t}\n\t\n\t/**\n\t * @param s\n\t * @return\n\t * @throws ClientRuntimeException\n\t * @throws IllegalArgumentException if input is null or zero length\n\t */\n\tpublic static byte[] computeMd5(String s) throws ClientRuntimeException{\n\t\tif(null == s) throw new IllegalArgumentException (\"null input\");\n\t\treturn computeMd5(s.getBytes());\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/ClusterModelProviderTestBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.jredis.NotSupportedException;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.jredis.ri.cluster.DefaultClusterNodeSpec;\nimport org.jredis.test.util.RunningAverage;\nimport org.testng.annotations.Test;\nimport static org.jredis.cluster.ClusterSuiteTestData.*;\nimport static org.testng.Assert.*;\n\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 29, 2010\n * \n */\n//@Test(suiteName=\"extensions-cluster-model\")\npublic abstract class ClusterModelProviderTestBase extends RefImplTestSuiteBase<ClusterModel> {\n\n\t// ------------------------------------------------------------------------\n\t// Extension point\n\t// ------------------------------------------------------------------------\n\t\n    /**\n     * @param clusterSpec\n     * @return\n     */\n    protected abstract ClusterModel newClusterModel (ClusterSpec clusterSpec) ;\n    \n    /**\n     * @return a {@link ClusterSpec} suitable for instantiating a provider instance\n     */\n    protected abstract ClusterSpec newClusterSpec () ;\n\n\t/**\n\t * @return the ClusterSpec.Type that the provider is supposed to support\n\t */\n\tprotected abstract ClusterType getSupportedClusterType ();\n\t// ------------------------------------------------------------------------\n\t// Specification Interface tested\n\t// ------------------------------------------------------------------------\n\t/* (non-Javadoc) @see org.jredis.cluster.ProviderTestBase#getSpecificationClass() */\n\t@Override\n\tprotected Class<?> getSpecificationClass () {\n\t\treturn ClusterModel.class;\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ProviderTestBase#newProviderInstance() */\n\t@Override\n\tprotected ClusterModel newProviderInstance () {\n\t\treturn newClusterModel(newClusterSpec());\n\t}\n\t\n\t\n\t// ------------------------------------------------------------------------\n\t// Test general contract of SPECS for Cluster and its Nodes\n\t// ------------------------------------------------------------------------\n\t@Test\n\tpublic void metaTest (){\n\t\tLog.log(\"[META] test the test suite assumptions!\");\n\n\t\tClusterType clusterType = getSupportedClusterType();\n\t\tassertNotNull(clusterType, \"getSupportedClusterType\");\n\t\t\n\t\tClusterSpec testSpec = newClusterSpec();\n\t\tassertNotNull(testSpec, \"newClusterSpec should not return null\");\n\t\t\n\t\tassertEquals(testSpec.getType(), clusterType, \"asserted supported cluster type and type from the newClusterSpec should be the same\");\n\t\t\n\t\tClusterModel model = newProviderInstance();\n\t\tassertNotNull(model, \"newProviderInstance should not return null\");\n\t}\n\t\n\t@Test\n\tpublic void testClusterSpecPropertyOps () {\n\t\tLog.log(\"test ClusterSpec accessors\");\n\n\t\t// null spec arg on construct must raise an error\n\t\t//\n\t\tboolean didRaiseEx;\n\t\tdidRaiseEx = false;\n\t\ttry {\n\t\t\t@SuppressWarnings(\"unused\")\n            ClusterModel m = newClusterModel(null);\n\t\t}\n\t\tcatch (IllegalArgumentException e) { didRaiseEx = true; }\n\t\tcatch (RuntimeException whatsthis) { fail(\"unexpected exception raised during op\", whatsthis); }\n\t\tassertTrue(didRaiseEx, \"IllegalArgumentException raise is expected\");\n\t\t\n\t\t// spec arg with no nodes on construct is not an error if \n\t\t// model supports reconfiguration\n\t\t//\n\t\tboolean supportsReconfig = newProviderInstance().supportsReconfiguration();\n\t\tdidRaiseEx = false;\n\t\ttry {\n\t\t\tClusterSpec s = newClusterSpec();\n\t\t\ts.removeAll(s.getNodeSpecs());\n\t\t\tassertTrue(s.getNodeSpecs().size() == 0, \"cluster spec should have no node specs now\");\n            newClusterModel(s);\n\t\t}\n\t\tcatch (IllegalArgumentException e) { didRaiseEx = true; }\n\t\tcatch (RuntimeException whatsthis) { fail(\"unexpected exception raised during op\", whatsthis); }\n\t\tassertTrue(didRaiseEx && !supportsReconfig , \"expected only if non reconfigurable\");\n\n\t\tClusterSpec spec = newClusterSpec();\n\t\tClusterModel model = newClusterModel(spec);\n\t\tassertNotNull(newProviderInstance().getSpec(), \"clusterSpec property should be non-null\");\n\t\tassertEquals(model.getSpec(), spec, \"expecting returned property to be the spec used in constructor\");\n\t}\n\t\n\t@Test\n\tpublic void testReconfigOfNonReconfigurableModel () {\n\t\tLog.log(\"test reconfiguration for static configuration models\");\n\t\t\n\t\t// skip the test if not applicable to this provider\n\t\t//\n\t\tif(provider.supportsReconfiguration()) {\n\t\t\tLog.log(\"Skipping test; not applicable.\");\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t// create a new model, get its spec, and pick one node to remove\n\t\t// this should raise an exception\n\t\tClusterModel model = newProviderInstance();\n\t\tClusterSpec clusterSpec = provider.getSpec();\n\t\tClusterNodeSpec nodeSpec = null;\n\t\tfor(ClusterNodeSpec n : clusterSpec.getNodeSpecs()){\n\t\t\tnodeSpec = n;\n\t\t\tbreak;\n\t\t}\n\t\tboolean didRaiseEx;\n\t\tdidRaiseEx = false;\n\t\ttry {\n\t\t\tmodel.removeNode(nodeSpec);\n\t\t}\n\t\tcatch (NotSupportedException e) { didRaiseEx = true; }\n\t\tcatch (RuntimeException whatsthis) { fail(\"unexpected exception raised during op\", whatsthis); }\n\t\tassertTrue(didRaiseEx, \"NotSupportedException raise is expected\");\n\t\t\n\t\t// so far so good.\n\t\t// now lets add a node\n\t\tdidRaiseEx = false;\n\t\ttry {\n\t\t\tmodel.addNode(new DefaultClusterNodeSpec(DefaultConnectionSpec.newSpec()));\n\t\t}\n\t\tcatch (NotSupportedException e) { didRaiseEx = true; }\n\t\tcatch (RuntimeException whatsthis) { fail(\"unexpected exception raised during op\", whatsthis); }\n\t\tassertTrue(didRaiseEx, \"NotSupportedException raise is expected\");\n\t}\n\t@Test\n\tpublic void testReconfigOfReconfigurableModel () {\n\t\tLog.log(\"test reconfiguration for dynamic configuration models\");\n\t\t\n\t\t// skip the test if not applicable to this provider\n\t\t//\n\t\tif(!provider.supportsReconfiguration()) {\n\t\t\tLog.log(\"Skipping test; not applicable.\");\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t// create a new model, get its spec, and pick one node to remove\n\t\t//\n\t\tClusterModel model = newProviderInstance();\n\t\tClusterSpec clusterSpec = provider.getSpec();\n\t\tClusterNodeSpec nodeSpec = null;\n\t\tfor(ClusterNodeSpec n : clusterSpec.getNodeSpecs()){\n\t\t\tnodeSpec = n;\n\t\t\tbreak;\n\t\t}\n\t\tmodel.removeNode(nodeSpec);\n\t\t\n\t\t// now lets add a node\n\t\t//\n\t\tmodel.addNode(new DefaultClusterNodeSpec(DefaultConnectionSpec.newSpec().setPort(9999)));\n\t}\n\t@Test\n\tpublic void testKeyDistribution (){\n\t\tlong keycnt = data.MEDIUM_CNT;\n\t\tLog.log(\"test key distribution with \" + keycnt + \" keys\");\n\n\t\t// get the node for a number of keys and check the distribution\n\t\t// across the nodes.  Very difficult to have a definitive tests here\n\t\t// without spec'ing distribution metric (e.g. limits on std-dev), but\n\t\t// at least all nodes should have keys asigned to them, as a general start.\n\t\t\n\t\tMap<ClusterNodeSpec, Long> distribution = new HashMap<ClusterNodeSpec, Long>();\n\t\t\n\t\tClusterModel model = newProviderInstance();\n\t\tassertNotNull(model, \"newProviderInstance should not return null\");\n\t\t\n\t\t// we simply count the keys assigned to each node\n\t\t// \n\t\tfor(int i=0; i<keycnt; i++){\n\t\t\tString key = getRandomAsciiString(512);\n\t\t\tbyte[] keybytes = key.getBytes();\n\t\t\tClusterNodeSpec nodeSpec = model.getNodeForKey(keybytes);\n\t\t\tLong cnt = distribution.get(nodeSpec);\n\t\t\tcnt = cnt == null ? 1 : cnt.longValue()+1;\n\t\t\tdistribution.put(nodeSpec, cnt);\n\t\t}\n\n\t\t// and now lets do some basic analysis\n\t\t// we'll need the ClusterSpec to get the nodes\n\t\t\n\t\tClusterSpec clusterSpec = provider.getSpec();\n\t\tassertNotNull(clusterSpec, \"cluster spec must not be null\");\n\t\t\n\t\tRunningAverage avg = new RunningAverage();\n\t\tint nodeCnt = clusterSpec.getNodeSpecs().size();\n\t\tNumber[] data = new Number[nodeCnt];\n\t\tint i = 0;\n\t\tfor(ClusterNodeSpec n : clusterSpec.getNodeSpecs()){\n\t\t\tLong cnt = distribution.get(n);\n\t\t\tavg.onMeasure(cnt);\n\t\t\tdata[i++] = cnt;\n\t\t}\n\t\tassertTrue(avg.getMin() > 0, \"No node should have zero keys assigned to it\");\n\t\tassertTrue(avg.getMax() > 0, \"No node should have zero keys assigned to it\");\n\t\tLog.log(\"Distributed %d keys in a %d node cluster:\\n\\t Key/node distribution -- AVG: %d - MIN: %d - MAX: %d\\n\", keycnt, nodeCnt, avg.get(), avg.getMin(), avg.getMax());\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/ClusterNodeSpecProviderTestBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 24, 2010\n */\n// TODO: look into the data provider attrib of the annotation ...\n@Test(suiteName=\"extensions-cluster-specs-1\")\nabstract \npublic class ClusterNodeSpecProviderTestBase extends RefImplTestSuiteBase<ClusterNodeSpec> {\n\n\t// ------------------------------------------------------------------------\n\t// Specification Interface tested\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc) @see org.jredis.cluster.ProviderTestBase#getSpecificationClass() */\n\tprotected final Class<?> getSpecificationClass () {\n\t\treturn ClusterNodeSpec.class;\n\t}\n\n    /**\n     * Ok, so its a hack.  (TODO: add a context param to this method in super).\n     * @param connectionSpec\n     * @return\n     */\n    protected abstract ClusterNodeSpec newProviderInstance (ConnectionSpec connectionSpec) ;\n\n\t// ------------------------------------------------------------------------\n\t// Test general contract of SPECS for Cluster and its Nodes\n\t// ------------------------------------------------------------------------\n\t@Test\n\tpublic void testIdentityContract () {\n\t\tLog.log(\"Testing ClusterNodeSpec identity contract enforcement: [Object.equals() | Object.hashCode()]\");\n\t\tint db = 10;\n\t\tint anotherDb = 2;\n\t\tConnectionSpec node1Spec = DefaultConnectionSpec.newSpec(\"127.0.0.1\", 6379, db, null);\n\t\tConnectionSpec node2Spec = DefaultConnectionSpec.newSpec(\"127.0.0.1\", 6379, db, null);\n\t\tConnectionSpec node3Spec = DefaultConnectionSpec.newSpec(\"127.0.0.1\", 6379, anotherDb, null);\n\t\t\n\t\tClusterNodeSpec node1 = newProviderInstance(node1Spec);\n\t\tClusterNodeSpec node2 = newProviderInstance(node2Spec);\n\t\tClusterNodeSpec node3 = newProviderInstance(node3Spec);\n\t\t\n\t\tassertTrue(node1.getId().equals(node2.getId()), \"ids should be identical\");\n\t\tassertTrue(node1.hashCode() == node2.hashCode(), \"hashCodes should be equal\");\n\t\tassertTrue(node1.equals(node2), \"nodes must be considered equivalent\");\n\t\tassertTrue(node2.equals(node1), \"nodes must be considered equivalent [transitive test]\");\n\t\t\n\t\t\n\t\t// test equivalence of DB# of node's ConnectionSpec in identity tests\n\t\t// these should all pass\n\t\t\n\t\tassertTrue(node1.getId().equals(node3.getId()), \"ids should be identical\");\n\t\tassertTrue(node1.hashCode() == node3.hashCode(), \"hashCodes should be equal\");\n\t\tassertTrue(node1.equals(node3), \"nodes must be considered equivalent\");\n\t\tassertTrue(node3.equals(node1), \"nodes must be considered equivalent [transitive test]\");\n\n\t\t// now lets raise some errors\n\t\tboolean didRaiseError;\n\t\t\n\t\t// test arg constraint checking\n\t\t//\n\t\tdidRaiseError = false;\n\t\tClusterNodeSpec nullRef = null;\n\t\ttry {\n\t\t\tnode1.equals(nullRef);\n\t\t}\n\t\tcatch (IllegalArgumentException e){\n\t\t\tdidRaiseError = true;\n\t\t}\n\t\tif(!didRaiseError) fail(\"Expecting an IllegalArgumentException raised for null input arg to equals()\");\n\t\t\n\t\tdidRaiseError = false;\n\t\tObject foo = new Object();\n\t\ttry {\n\t\t\tnode1.equals(foo);\n\t\t}\n\t\tcatch (IllegalArgumentException e){\n\t\t\tdidRaiseError = true;\n\t\t}\n\t\tif(!didRaiseError) fail(\"Expecting an IllegalArgumentException raised for invalid object type arg to equals()\");\n\t}\n\t\n\t/**\n\t * We have the full port range of an IPv4 address as our clusterNodes.  Here\n\t * we make sure the ids are unique.\n\t */\n\t@Test\n\tpublic void testIdGeneration () {\n\t\tLog.log(\"Testing ClusterNodeSpec.getId() ...\");\n\t\t\n\t\tSet<String> generatedIdSet = new HashSet<String>(data.connSpecs.length);\n\t\tLog.log(\"... testing a cluster with member cnt: \" + data.connSpecs.length);\n\t\t\n\t\tfor(ConnectionSpec connSpec : data.connSpecs){\n\t\t\tClusterNodeSpec nodeSpec = newProviderInstance(connSpec);\n\t\t\tString nodeId = nodeSpec.getId();\n\t\t\tassertTrue(generatedIdSet.add(nodeId), \"generated ID should be unique but was not: \" + nodeId);\n\t\t}\n\t}\n\t\n\t/**\n\t * We test the Consitent Hash Key for uniqueness.  Testing the full port range * reasonable_inst_cnt will\n\t * exhaust the memory so we'll limit to a subset of ports.\n\t */\n\t@Test\n\tpublic void testGetKeyForCHRangeInstance () {\n\t\tint instanceCnt = 100;\n\t\tint nodeCnt = 100;\n\t\tLog.log(\"Testing CHRange key uqniueness for \"+instanceCnt+\" instances in the ring... this will take a while! (TODO: cnt should be a parameter!)\");\n\t\tSet<String> chRangeKeys = new HashSet<String>(nodeCnt*instanceCnt);\n\n\t\tint n = 0;\n\t\tfor(ConnectionSpec connSpec : data.connSpecs){\n\t\t\tClusterNodeSpec nodeSpec = newProviderInstance(connSpec);\n\t\t\tfor(int i=0; i<instanceCnt; i++) {\n\t\t\t\tString nodeInstanceCHKey = nodeSpec.getKeyForReplicationInstance(i);\n\t\t\t\tassertTrue(chRangeKeys.add(nodeInstanceCHKey), \"generated ConsistentHash Key for node \"+nodeSpec.getId()+\" for instance \"+i+\" should be unique but was not: \" + nodeInstanceCHKey);\n\t\t\t}\n\t\t\tif(++n > 100) break;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/ClusterSpecProviderTestBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport java.util.Collection;\nimport java.util.HashSet;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 24, 2010\n */\n//TODO: look into the data provider attrib of the annotation ...\n@Test(suiteName=\"extensions-cluster-specs-2\")\nabstract \npublic class ClusterSpecProviderTestBase extends RefImplTestSuiteBase<ClusterSpec> {\n\n\t// ------------------------------------------------------------------------\n\t// Extension point\n\t// ------------------------------------------------------------------------\n\t\n    protected abstract ClusterNodeSpec newNodeSpec (ConnectionSpec connectionSpec) ;\n\n\t// ------------------------------------------------------------------------\n\t// Specification Interface tested\n\t// ------------------------------------------------------------------------\n\t\n\tprotected final Class<?> getSpecificationClass () {\n\t\treturn ClusterSpec.class;\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// Test general contract of SPECS for Cluster and its Nodes\n\t// ------------------------------------------------------------------------\n\t\n\t@Test\n\tpublic void testGetType() {\n\t\tLog.log(\"Testing ClusterSpec.getType()\");\n\t\tassertNotNull(provider.getType(), \"getType() must never return null\");\n\t}\n\t\n\t@Test\n\tpublic void testSetType() {\n\t\tLog.log(\"Testing ClusterSpec.setType()\");\n\t\t\n\t\t// Note: don't use provider instance as we are changing various settings here\n\t\t// and don't want to break assumptions down the hierarchy chain.\n\n\t\tClusterType clusterType = null;\n\t\tClusterSpec clusterSpec = newProviderInstance();\n\t\tClusterType prevType = clusterSpec.getType();\n\t\tassertNotNull(prevType, \"getType() must never return null\");\n\t\t// just pick something else\n\t\tfor(ClusterType type : ClusterType.values()){\n\t\t\tif(type != prevType){\n\t\t\t\tclusterType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassertNotNull(clusterType, \"[BUG] why couldn't we find another different type?\");\n\t\t\n\t\t// use the setter and test various requirements.\n\t\tClusterSpec chainedRes = clusterSpec.setType(clusterType);\n\t\ttestChainedResult(chainedRes, clusterSpec);\n\t\t\n\t\tassertEquals(clusterSpec.getType(), clusterType, \"getType() result must match the ref used for setType()\");\n\t}\n\t\n\t@Test\n\tpublic void testAddAndRemoveAll() {\n\t\tLog.log(\"Testing ClusterSpec addAll() | removeAll()\");\n\t\tClusterSpec clusterSpec = newProviderInstance();\n\t\t\n\t\tLog.log(\"Test with cluster spec with %d node specs ..\", clusterSpec.getNodeSpecs().size());\n\t\tCollection<ClusterNodeSpec> nodes = new HashSet<ClusterNodeSpec>();\n\t\tfor(int i=0; i<10; i++){\n\t\t\tnodes.add(newNodeSpec(data.connSpecs[i]));\n\t\t}\n\t\tassertTrue(clusterSpec.addAll(nodes), \"addAll should return true\");\n\t\tassertFalse(clusterSpec.addAll(nodes), \"dup addAll should return false\");\n\t\t\n\t\tassertTrue(clusterSpec.removeAll(nodes), \"removeAll should return true\");\n\t\tassertFalse(clusterSpec.removeAll(nodes), \"second removeAll should return false\");\n\t\t\n\t\t// test constraint against collections with a null member\n\t\tnodes.clear();\n\t\tassertTrue(nodes.add(null), \"collection w null input\");\n\t\tfor(int i=0; i<10; i++) {\n\t\t\tnodes.add(newNodeSpec(data.connSpecs[i]));\n\t\t}\n\t\tassertTrue(nodes.contains(null), \"collection has a null input\");\n\t\tboolean didRaiseEx;\n\t\tdidRaiseEx = false;\n\t\ttry {\n\t\t\tclusterSpec.addAll(nodes);\n\t\t}\n\t\tcatch (IllegalArgumentException e) { didRaiseEx = true; }\n\t\tcatch (RuntimeException whatsthis) { fail(\"unexpected exception raised during op\", whatsthis); }\n\t\tassertTrue(didRaiseEx, \"IllegalArgumentException raise is expected\");\n\t\t\n\t\tdidRaiseEx = false;\n\t\ttry {\n\t\t\tclusterSpec.removeAll(nodes);\n\t\t}\n\t\tcatch (IllegalArgumentException e) { didRaiseEx = true; }\n\t\tcatch (RuntimeException whatsthis) { fail(\"unexpected exception raised during op\", whatsthis); }\n\t\tassertTrue(didRaiseEx, \"IllegalArgumentException raise is expected\");\n\t\t\n\t\t\n\t}\n\t\n\t\n\t@Test\n\tpublic void testRemoveNodeSpec() {\n\t\tLog.log(\"Testing ClusterSpec.addNodeSpec()\");\n\t\tClusterSpec clusterSpec = newProviderInstance();\n\t\t\n\t\tfor(int i=0; i<10; i++){\n\t\t\tClusterNodeSpec nodeSpec = newNodeSpec(data.connSpecs[i]);\n\t\t\tassertTrue(clusterSpec.addNode(nodeSpec));\n\t\t}\n\t\t\n\t\tfor(int i=0; i<10; i++){\n\t\t\tClusterNodeSpec nodeSpec = newNodeSpec(data.connSpecs[i]);\n\t\t\tassertTrue(clusterSpec.removeNode(nodeSpec));\n\t\t}\n\t}\n\t\n\t@Test\n\tpublic void testAddNodeSpec() {\n\t\tLog.log(\"Testing ClusterSpec.addNodeSpec()\");\n\t\tClusterSpec clusterSpec = newProviderInstance();\n\t\t\n\t\tClusterNodeSpec nodeSpec = null;\n\t\t\n\t\tnodeSpec = newNodeSpec(data.connSpecs[0]);\n\t\tassertTrue(clusterSpec.addNode(nodeSpec));\n\t\t\n\t\tnodeSpec = newNodeSpec(data.connSpecs[1]);\n\t\tassertTrue(clusterSpec.addNode(nodeSpec));\n\t\t\n\t\t\n\t\t// now lets raise some errors\n\t\tboolean didRaiseError;\n\t\t\n\t\t// should not allow adding of duplicate ClusterNodeSpecs\n\t\tdidRaiseError = false;\n\t\t\n\t\tassertTrue(clusterSpec.addNode(newNodeSpec(data.defRedisDb10Port7777ConnSpec)), \"add of unique spec should be possible and must return the clusterSpec instance\");\n\t\tassertFalse(clusterSpec.addNode(newNodeSpec(data.defRedisDb10Port7777ConnSpec_dup)), \"add of duplicate spec is expected to raise a runtime exception\");\n\t\t\n\t\t// should not allow adding of null specs\n\t\tdidRaiseError = false;\n\t\tClusterNodeSpec nullRef = null;\n\t\ttry {\n\t\t\tclusterSpec.addNode(nullRef);\n\t\t}\n\t\tcatch (IllegalArgumentException e){\n\t\t\tdidRaiseError = true;\n\t\t}\n\t\tif(!didRaiseError) fail(\"Expecting an IllegalArgumentException raised for null input arg to add()\");\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// helper methods\n\t// ------------------------------------------------------------------------\n\t\n\tprivate final void testChainedResult (ClusterSpec res, ClusterSpec expected) {\n\t\tassertNotNull(res, \"fluent interface setters must return non null values\");\n\t\tassertEquals(res, expected, \"setter result must be the same reference as the original\");\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/ClusterSuiteTestData.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport static org.testng.Assert.fail;\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\nimport java.util.Formatter;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Random;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\n\n/**\n * We'll use a singleton for our test data to minimize jvm heap impact\n * of the potentially very large test data.\n * <p>\n * This class uses the Reference Implementation classes where necessary.  Implementations\n * are required to be interoperable and this should not present a problem for testing other\n * providers of the JReds Cluster specs.\n * \n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 27, 2010\n */\n\npublic class ClusterSuiteTestData {\n\t\n\t/** singleton instance - otherwise multiple test runs kill the jvm heap */\n\tstatic private final ClusterSuiteTestData instance = new ClusterSuiteTestData();\n\t// ------------------------------------------------------------------------\n\t// General RI Test Suite Parameters with default values to avoid XML\n\t// ------------------------------------------------------------------------\n\t\n\t// data size\n\tfinal public int\tSMALL_DATA =  128;\n\tfinal public int\tMEDIUM_DATA = 1024 * 2;\n\tfinal public int\tLARGE_DATA =  1024 * 512;\n\t\n\t// iterations\n\tfinal public int\tSMALL_CNT \t= 100;\n\tfinal public int\tMEDIUM_CNT \t= 10000;\n\tfinal public int\tLARGE_CNT \t= 1000000;\n\t\n\tfinal public int \tNODE_CNT\t= MEDIUM_CNT;\n\t\n\tfinal public String CLUSTER_NODES_ADDRESS_BASE = \"127.0.0.1\";\n\tfinal public int \tCLUSTER_NODES_PORT_BASE = 6379;\n\tfinal public int\tdb = 10;\n\t\n\t// ------------------------------------------------------------------------\n\t// General RI Test Suite test data\n\t// ------------------------------------------------------------------------\n//\tpublic final Set<ClusterNodeSpec> clusterNodeSpecs = new HashSet<ClusterNodeSpec>();\n\tpublic ConnectionSpec[] connSpecs;\n//\tpublic final ClusterNodeSpec[] clusterNodeSpecsArray;\n\t\n//\tpublic ClusterNodeSpec defaultRedisWithDb10ClusterNodeSpec;\n//\tpublic ClusterNodeSpec defaultRedisWithDb10ClusterNodeSpec_dup;\n\n\tpublic ConnectionSpec defRedisDb10Port7777ConnSpec;\n\tpublic ConnectionSpec defRedisDb10Port7777ConnSpec_dup;\n\tpublic Map<Object, Object>\tdataMap = new HashMap<Object, Object>();\n\n\t// ------------------------------------------------------------------------\n\t// Access\n\t// ------------------------------------------------------------------------\n\t/**\n\t * @return the singleton instance of  {@link ClusterSuiteTestData}\n\t */\n\tpublic static ClusterSuiteTestData getInstance () {\n\t\treturn instance;\n\t}\n\t// ------------------------------------------------------------------------\n\t// Const\n\t// ------------------------------------------------------------------------\n\tprivate ClusterSuiteTestData () {\n//\t\tClusterNodeSpec nodeSpec = null;\n\t\tconnSpecs = new ConnectionSpec[NODE_CNT];\n\t\tfor(int i=0;i<NODE_CNT; i++) {\n\t\t\tInetAddress address = getInetAddressFor(CLUSTER_NODES_ADDRESS_BASE);\n\t\t\tConnectionSpec connSpec = getConnectionSpecFor(address, CLUSTER_NODES_PORT_BASE+i, db);\n\t\t\tconnSpecs[i] = connSpec;\n//\t\t\tnodeSpec = new DefaultClusterNodeSpec (connSpec);\n//\t\t\tclusterNodeSpecs.add(nodeSpec);\n\t\t}\n\n\t\t// sets are a pain if you just want a member\n//\t\tclusterNodeSpecsArray = new ClusterNodeSpec[clusterNodeSpecs.size()];\n//\t\tclusterNodeSpecs.toArray(clusterNodeSpecsArray);\n\n\n\t\tdefRedisDb10Port7777ConnSpec = DefaultConnectionSpec.newSpec(\"127.0.0.1\", 7777, db, null);\n\t\tdefRedisDb10Port7777ConnSpec_dup = DefaultConnectionSpec.newSpec(\"127.0.0.1\", 7777, db, null);\n\t\t\n//\t\tLog.log(\"clusterNodeSpecsArray: \" + clusterNodeSpecsArray);\n//\t\tfor(ClusterNodeSpec s : clusterNodeSpecsArray)\n//\t\t\tif (null == s) Log.log(\"NULL clusterNodeSpec: \" + s);\n\n\t\tLog.log(\"[ClusterSuiteTestData] Suite test data initialized\");\n\t}\t\n\t\n\t// ------------------------------------------------------------------------\n\t// Helper methods\n\t// ------------------------------------------------------------------------\n\n\tstatic public final Random random = new Random(System.currentTimeMillis());\n\n\t/**\n\t * Creates a random ascii string\n\t * @param length\n\t * @return\n\t */\n\tstatic public String getRandomAsciiString (int length) {\n\t\tStringBuilder builder = new  StringBuilder(length);\n\t\tfor(int i = 0; i<length; i++){\n\t\t\tchar c = (char) (random.nextInt(126-33) + 33);\n\t\t\tbuilder.append(c);\n\t\t}\n\t\treturn builder.toString();\n\t}\n\n\t/**\n\t * Creates a buffer of given size filled with random byte values\n\t * @param size\n\t * @return\n\t */\n\tstatic public byte[] getRandomBytes(int size) {\n\t\tint len = size;\n\t\tbyte[]\tbuff = new byte[len];\n\t\trandom.nextBytes(buff);\n\t\treturn buff;\n\t}\n\n\t/**\n\t * @return\n\t */\n\tstatic public String getRandomIPv$HostName () {\n\t\tFormatter fmt = new Formatter();\n\t\tfmt.format(\"%d.%d.%d.%d\", \n\t\t\trandom.nextInt(255),\n\t\t\trandom.nextInt(255),\n\t\t\trandom.nextInt(255),\n\t\t\trandom.nextInt(255)\n\t\t);\n\t\treturn fmt.toString();\n\t}\n\t\n\tstatic public InetAddress getInetAddressFor (String hostName) {\n\t\tInetAddress address = null;\n\t\ttry {\n\t\t\taddress = InetAddress.getByName(hostName);\n\t\t}\n\t\tcatch (UnknownHostException e) {\n\t\t\tfail(\"In suite setup for random address <\"+hostName+\">\", e);\n\t\t}\n\t\treturn address;\n\t}\n\tstatic public ConnectionSpec getConnectionSpecFor (InetAddress address, int port, int db) {\n\t\tConnectionSpec connSpec = DefaultConnectionSpec.newSpec().setAddress(address).setPort(port).setDatabase(db);\n\t\treturn connSpec;\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/ProviderTestBase.java",
    "content": "/*\n *   Copyright 2009 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport org.jredis.ClientRuntimeException;\n//import org.jredis.JRedis;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.BeforeTest;\nimport static org.testng.Assert.*;\n\n/**\n * Support for tests of interface <code>T</code> implementation providers.\n * \n * @author  Joubin Houshyar (alphazero@sensesay.net)\n * @version alpha.0, Oct 10, 2009\n * @since   alpha.0\n * \n */\n\npublic abstract class ProviderTestBase <T> {\n\t\n\t// ========================================================================\n\t// Test Properties\n\t// ========================================================================\n\t\n\t/** the JRedis implementation being tested */\n\tprotected T provider = null;\n\tprotected Class<?> specClass = null;\n\t// ------------------------------------------------------------------------\n\t// JRedisFuture Provider initialize methods\n\t// ------------------------------------------------------------------------\n\t/**\n\t * Sets the {@link JRedis} implementation provider for the test suite\n\t */\n\t@BeforeTest\n\tpublic void initialize () {\n\t\ttry {\n\t\t\tspecClass = getSpecificationClass();\n\t\t\tassertNotNull(specClass, \"getSpecificationClass() returned null\");\n\t\t\tprovider = newProviderInstance();\n\t\t\tassertNotNull(provider, \"newProviderInstance() returned null\");\n\t\t\tLog.log(\"\\n\\nTEST: \" +\n\t\t\t\t\t\"\\n\\t-----------------------------------------------\\n\" +\n\t\t\t\t\t\"\\tSpec Interface: %s\\n\" +\n\t\t\t\t\t\"\\tProvider Class: %s\" +\n\t\t\t\t\t\"\\n\\t-----------------------------------------------\\n\", \n\t\t\t\t\tspecClass.getCanonicalName(),\n\t\t\t\t\tprovider.getClass().getCanonicalName());\n        }\n        catch (ClientRuntimeException e) {\n        \tLog.error(e.getLocalizedMessage());\n        }\n\t}\n\t\n\t/**\n\t * Extension point:  Tests for specific implementations of <code>T</code> \n\t * implement this method to create the provider instance.\n\t * @return <code>T</code> implementation instance\n\t */\n\tprotected abstract T newProviderInstance () ;\n\t/**\n\t * @return\n\t */\n\tprotected abstract Class<?> getSpecificationClass () ;\n\t\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/RefImplTestSuiteBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster;\n\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeSuite;\nimport org.testng.annotations.Parameters;\n\n/**\n * As base for all org.jredis.cluster[...] tests, this class is mainly responsible\n * for \n * <li> [-TODO] initialize the test suite parameters through testNG injection from module's pom\n * <li> [-TODO] get and initialize the test data singleton   \n * <li> providing any required helper methods\n * <b>\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 24, 2010\n */\n\npublic abstract class RefImplTestSuiteBase <T> extends ProviderTestBase <T>{\n\n\t// ------------------------------------------------------------------------\n\t// General RI Test Suite Parameters with default values to avoid XML\n\t// ------------------------------------------------------------------------\n\t\n\tprotected int\t\tNODE_CNT =  10;\n\tprotected String \tCLUSTER_NODES_ADDRESS_BASE = \"127.0.0.1\";\n\tprotected int \t\tCLUSTER_NODES_PORT_BASE = 6379;\n\t\n\t\n\t/** data holds the ref to a singleton class with all the test data */\n\tprotected ClusterSuiteTestData data;\n\n\t@Parameters({ \n//\t\t\"jredis.test.password\", \n//\t\t\"jredis.test.host\", \n//\t\t\"jredis.test.port\",\n//\t\t\"jredis.test.db.1\",\n//\t\t\"jredis.test.db.2\",\n//\n//\t\t\"jredis.test.datasize.small\",\n//\t\t\"jredis.test.datasize.medium\",\n//\t\t\"jredis.test.datasize.large\",\n//\t\t\"jredis.test.cnt.small\",\n//\t\t\"jredis.test.cnt.medium\",\n//\t\t\"jredis.test.cnt.large\",\n//\t\t\"jredis.test.expire.secs\",\n//\t\t\"jredis.test.expire.wait.millisecs\"\n\t\t\"jredis.cluster.node.cnt\",\n\t\t\"jredis.cluster.node.address.base\",\n\t\t\"jredis.cluster.node.port.base\"\n\t})\n\t@BeforeSuite\n\tpublic void suiteParametersInit(\n//\t\tString password, \n//\t\tString host, \n//\t\tint port,\n//\t\tint db1,\n//\t\tint db2,\n\n\t\tint \tnodecnt,\n\t\tString \tnodesAddressBase,\n\t\tint\t\tnodesPortBase\n\t) \n\t{\n\t\tNODE_CNT = nodecnt;\n\t\tCLUSTER_NODES_ADDRESS_BASE = nodesAddressBase;\n\t\tCLUSTER_NODES_PORT_BASE = nodesPortBase;\n\t\t\n//\t\tLog.log(\"nodecnt: %d\", NODE_CNT);\n//\t\tLog.log(\"cluster nodes address base: %s\", CLUSTER_NODES_ADDRESS_BASE);\n//\t\tLog.log(\"cluster nodes port base:    %d\", CLUSTER_NODES_PORT_BASE);\n//\t\tLog.log(\"nodecnt: %d\", NODE_CNT);\n//\t\tLog.log(\"[extensions.cluster] Suite parameters initialized <suiteParametersInit>\");\n\t\t\n\t\tdata = setupTestSuiteData();\n\t\tAssert.assertNotNull(data, \"ClusterSuiteTestData instance obtained is null\");\n\t}\n\t/**\n\t * a do nothing method - keeping it around in case I change my mind about using the\n\t * singleton test data class.\n\t * @return\n\t */\n\tprivate ClusterSuiteTestData setupTestSuiteData () {\n\t\treturn ClusterSuiteTestData.getInstance();\n\t}\t\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/models/BasicStaticHashClusterTest.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.models;\n\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.jredis.ri.cluster.DefaultClusterNodeSpec;\nimport org.jredis.ri.cluster.DefaultClusterSpec;\nimport org.jredis.ri.cluster.model.BasicStaticHashCluster;\n\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 31, 2010\n * \n */\n@Test(suiteName=\"basic static hash\")\npublic class BasicStaticHashClusterTest extends StaticHashClusterProviderTestBase {\n\n\t// ------------------------------------------------------------------------\n\t// super overrides\n\t// ------------------------------------------------------------------------\n\t\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModelProviderTestBase#newClusterModel(org.jredis.cluster.ClusterSpec) */\n\t@Override\n\tprotected ClusterModel newClusterModel (ClusterSpec clusterSpec) {\n\t\tClusterModel model = null;\n\t\ttry {\n\t\t\tmodel = new BasicStaticHashCluster(clusterSpec);\n\t\t}\n\t\tcatch (RuntimeException e){\n\t\t\tLog.error(\"NOTE: propagating error > \" + e.getLocalizedMessage());\n\t\t\tthrow e;\n\t\t}\n\t\treturn model;\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModelProviderTestBase#newClusterSpec() */\n\t@Override\n\tprotected ClusterSpec newClusterSpec () {\n\t\tClusterSpec spec = new DefaultClusterSpec();\n\t\tfor(int i=0; i<100; i++){\n\t\t\tClusterNodeSpec node = new DefaultClusterNodeSpec(DefaultConnectionSpec.newSpec(\"localhost\", 6379+i, 0, null));\n\t\t\tspec.addNode(node);\n\t\t}\n\t\treturn spec;\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// BasicStaticHashCluster specific tests\n\t// ------------------------------------------------------------------------\n    @Test\n    public void fooTest() {\n    \tLog.log(\"Foo test for BasicStaticHash\");\n    \tassertTrue(true);\n    }\n\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/models/ConsistentHashClusterProviderTestBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.models;\n\nimport java.util.Collection;\nimport org.jredis.cluster.ClusterModelProviderTestBase;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.ClusterType;\nimport org.jredis.cluster.model.ConsistentHashCluster;\nimport org.jredis.ri.alphazero.support.Log;\n\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 30, 2010\n * \n */\n\npublic abstract class ConsistentHashClusterProviderTestBase extends ClusterModelProviderTestBase {\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModelProviderTestBase#getSupportedClusterType() */\n    @Override\n    protected ClusterType getSupportedClusterType () {\n\t    return ClusterType.CONSISTENT_HASH;\n    }\n\t// ------------------------------------------------------------------------\n\t// ConsistentHashCluster generic tests\n\t// ------------------------------------------------------------------------\n    @Test\n    public void compatibilityTest() {\n    \t\n    \tLog.log(\"Test provider support for Consistent Hashing\");\n    \tassertNotNull(provider, \"provider is null!\");\n    \tassertTrue(provider.supports(ClusterType.CONSISTENT_HASH), \"A ConsistentHashCluster model must support Type.CONSISTENT_HASH\");\n    }\n    \n    @Test\n    public void basicNodeMapTest() {\n    \tLog.log(\"Basic nodemap test of Consistent Hashing cluster model\");\n    \t\n    \tConsistentHashCluster model = (ConsistentHashCluster) newProviderInstance();\n    \tassertNotNull(model, \"model should not be null\");\n    \t\n    \tClusterSpec spec = model.getSpec();\n    \tassertNotNull(spec, \"spec should not be null\");\n    \t\n    \tConsistentHashCluster.NodeMap nodeMap = model.getNodeMap();\n    \tassertNotNull(nodeMap, \"node map should not be null\");\n    \t\n    \tCollection<ClusterNodeSpec> nodes = nodeMap.values();\n    \tassertNotNull(nodes, \"value set of node map should not be null\");\n    \t\n    \t// regardless of what hash (key) they are mapped to,\n    \t// we expected the value set of NodeMap to contain each and every\n    \t// ClusterNodeSpec in the ClusterSpec of the model\n    \t//\n\t\tLog.log(\"NOTE: %d nodes\", spec.getNodeSpecs().size());\n\t\tLog.log(\"NOTE: size of value set is %d \", nodes.size());\n\t\tint missCnt = 0;\n    \tfor(ClusterNodeSpec node : spec.getNodeSpecs()){\n    \t\tif(!nodes.contains(node)){\n    \t\t\tmissCnt ++;\n    \t\t}\n//    \t\tassertTrue(nodes.contains(node), \"nodeSpec should be in the value set of NodeMap: \" + node);\n    \t}\n\t\tLog.log(\"BUG: missing %d nodes!\", missCnt);\n\t\tassertEquals(missCnt, 0, \"There should be no nodes missing from the node map\");\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/models/KetamaClusterModelTest.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.models;\n\nimport org.jredis.cluster.ClusterModel;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.jredis.ri.cluster.DefaultClusterNodeSpec;\nimport org.jredis.ri.cluster.DefaultClusterSpec;\nimport org.jredis.ri.cluster.model.KetamaClusterModel;\n\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * {@link KetamaClusterModel} specific tests.  All generic and C.H. specific tests are\n * defined higher in the hierarchy chain.\n * \n * <p>Uses the {@link DefaultClusterSpec} for tests.\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 29, 2010\n * \n */\n\n@Test(suiteName=\"ketama\")\npublic class KetamaClusterModelTest extends ConsistentHashClusterProviderTestBase {\n\n\t// ------------------------------------------------------------------------\n\t// super overrides\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModelProviderTestBase#newClusterModel(org.jredis.cluster.ClusterSpec) */\n\t@Override\n\tprotected ClusterModel newClusterModel (ClusterSpec clusterSpec) {\n\t\tClusterModel model = null;\n\t\ttry {\n\t\t\tmodel = new KetamaClusterModel(clusterSpec);\n\t\t}\n\t\tcatch (RuntimeException e){\n\t\t\tLog.error(\"NOTE: propagating error > \" + e.getLocalizedMessage());\n\t\t\tthrow e;\n\t\t}\n\t\treturn model;\n\t}\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModelProviderTestBase#newClusterSpec() */\n\t@Override\n\tprotected ClusterSpec newClusterSpec () {\n\t\tClusterSpec spec = new DefaultClusterSpec();\n\t\tfor(int i=0; i<100; i++){\n\t\t\tClusterNodeSpec node = new DefaultClusterNodeSpec(DefaultConnectionSpec.newSpec(\"localhost\", 6379+i, 0, null));\n\t\t\tspec.addNode(node);\n\t\t}\n\t\treturn spec;\n\t}\n\n//\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModelProviderTestBase#getSupportedClusterType() */\n//    @Override\n//    protected ClusterType getSupportedClusterType () {\n//\t    return ClusterType.CONSISTENT_HASH;\n//    }\n    \n\t// ------------------------------------------------------------------------\n\t// Ketama specific tests\n\t// ------------------------------------------------------------------------\n    @Test\n    public void fooTest() {\n    \tLog.log(\"Foo test for KetamaClusterModel\");\n    \tassertTrue(true);\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/models/KetamaHashAlgoTest.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.models;\n\nimport org.jredis.cluster.support.HashAlgorithm;\nimport org.jredis.cluster.support.HashAlgorithmProviderTestBase;\nimport org.jredis.ri.cluster.model.KetamaHashProvider;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 27, 2010\n * \n */\n\npublic class KetamaHashAlgoTest extends HashAlgorithmProviderTestBase {\n\n\t// ------------------------------------------------------------------------\n\t// super overrides\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc) @see org.jredis.cluster.ProviderTestBase#newProviderInstance() */\n\t@Override\n\tprotected HashAlgorithm newProviderInstance () {\n\t\treturn new KetamaHashProvider();\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/models/StaticHashClusterProviderTestBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.models;\n\nimport java.util.Set;\nimport org.jredis.NotSupportedException;\nimport org.jredis.cluster.ClusterModelProviderTestBase;\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.ClusterType;\nimport org.jredis.cluster.model.StaticHashCluster;\nimport org.jredis.ri.alphazero.support.Log;\n\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 31, 2010\n * \n */\n\npublic abstract class StaticHashClusterProviderTestBase extends ClusterModelProviderTestBase \n{\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterModelProviderTestBase#getSupportedClusterType() */\n\t@Override\n\tprotected final ClusterType getSupportedClusterType () {\n\t\treturn ClusterType.CONSISTENT_HASH;\n\t}\n\n\t// ------------------------------------------------------------------------\n\t// StaticHashCluster generic tests\n\t// ------------------------------------------------------------------------\n\t\n    @Test\n    public void compatibilityTest() {\n    \t\n    \tLog.log(\"Test provider conformance to static hashing requirements\");\n    \tassertNotNull(provider, \"provider is null!\");\n    \t\n    \t// 1 - Must support the STATIC HASH and nothing else\n    \tassertTrue(provider.supports(ClusterType.STATIC_HASH), \"A StaticHashCluster model must support Type.CONSISTENT_HASH\");\n    \tassertFalse(provider.supports(ClusterType.CONSISTENT_HASH), \"A StaticHashCluster model can not support other cluster types beyond Type.CONSISTENT_HASH\");\n    \t\n    \t// 2 - Must not be reconfigurable\n    \tassertFalse(provider.supportsReconfiguration(), \"Static hash clusters can not be reconfigured.\");\n    \t\n    \t// 3 - Must not support any of the NodeMap modification ops, indicated by raising the specified ProviderException class\n    \tboolean didRaiseEx;    \t\n\t\tClusterSpec clusterSpec = this.newClusterSpec();\n\t\tSet<ClusterNodeSpec> nodeSpecs =  clusterSpec.getNodeSpecs();\n\t\tassertTrue(nodeSpecs.size() > 0, \"node specs set size must be greater than zero.\");\n\t\tClusterNodeSpec aNodeSpec =  (ClusterNodeSpec) nodeSpecs.toArray()[0];\n\t\t\n    \tdidRaiseEx = false;\n    \ttry {\n    \t\tprovider.addNode(aNodeSpec);\n    \t}\n    \tcatch (NotSupportedException expected) {didRaiseEx = true;}\n    \tcatch (Throwable whatsthis) {fail (\"Unexpected exception raised by provider method\", whatsthis);}\n    \tif(!didRaiseEx) { fail(\"Provider failed to raise exception for addNode()\");}\n\t\t\n    \tdidRaiseEx = false;\n    \ttry {\n    \t\tprovider.removeNode(aNodeSpec);\n    \t}\n    \tcatch (NotSupportedException expected) {didRaiseEx = true;}\n    \tcatch (Throwable whatsthis) {fail (\"Unexpected exception raised by provider method\", whatsthis);}\n    \tif(!didRaiseEx) { fail(\"Provider failed to raise exception for removeNode()\");}\n\n    }\n    \n    @Test\n    public void testStaticHash() {\n    \tLog.log(\"Basic nodemap test of Consistent Hashing cluster model\");\n    \t\n    \tStaticHashCluster model = (StaticHashCluster) newProviderInstance();\n    \tassertNotNull(model, \"model should not be null\");\n    \t\n    \tClusterSpec spec = model.getSpec();\n    \tassertNotNull(spec, \"spec should not be null\");\n    }    \n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/cluster/support/HashAlgorithmProviderTestBase.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.cluster.support;\n\n\n\nimport static org.testng.Assert.assertTrue;\nimport static org.testng.Assert.fail;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.cluster.RefImplTestSuiteBase;\nimport org.jredis.cluster.support.HashAlgorithm;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.testng.annotations.Test;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 26, 2010\n * \n */\n\n@Test(suiteName=\"extensions-cluster-specs-algorithms-1\")\nabstract\npublic class HashAlgorithmProviderTestBase extends RefImplTestSuiteBase<HashAlgorithm>{\n\n\t// ------------------------------------------------------------------------\n\t// Specification Interface tested\n\t// ------------------------------------------------------------------------\n\t\n\tprotected final Class<?> getSpecificationClass () {\n\t\treturn HashAlgorithm.class;\n\t}\n\t\n\t// ------------------------------------------------------------------------\n    // Tests\n\t// ------------------------------------------------------------------------\n\t@SuppressWarnings(\"static-access\")\n\t@Test\n\tpublic void testHashByteArray() {\n\t\tLog.log(\"Testing HashAlgorithm hash(byte[])\");\n\t\tHashAlgorithm hashAlgo = newProviderInstance();\n\t\ttry {\n\t        int c = 2000;\n\t        int cnt = (int) (10 * Math.log(c)) * c;\n        \tLog.log(\"Test hashing %d keys\", cnt);\n\t        Set<Long> hashSet = new HashSet<Long>(cnt);\n\t        for(int i=0; i<cnt; i++){\n\t        \tlong hash = hashAlgo.hash(data.getRandomBytes(255));\n\t        \tboolean didAdd = hashSet.add(hash);\n\t        \tif(!didAdd){\n\t        \t\tLog.log(\"[NOTE] got a collision (hash: %d) at idx: %d!\", hash, i);\n\t        \t}\n\t        }\n//\t        assertEquals(hashSet.size(), cnt);\n\t        if(hashSet.size() == cnt)\n\t        \tLog.log(\"Hashed %d keys with no collisions\", cnt);\n\t        else\n\t        \tLog.log(\"Hashed %d keys with %d collisions\", cnt, cnt - hashSet.size());\n\t        \n\t        // edge case - NULL input not allowed\n\t        boolean didRaiseError = false;\n\t        try {\n\t\t\t\tbyte[] nullref = null;\n\t        \thashAlgo.hash(nullref);\n\t        }\n\t        catch (IllegalArgumentException e){ didRaiseError = true; }\n\t        catch (RuntimeException what) { fail(\"Unexpected runtime exception raised\",what); }\n        \tassertTrue(didRaiseError, \"Expecting a raised exception for null input\");\n\t        \n\t        // edge case - zero length input not allowed\n\t        didRaiseError = false;\n\t        try {\n\t\t\t\tbyte[] zerobytes = data.getRandomBytes(0);\n\t\t\t\thashAlgo.hash(zerobytes);\n\t        }\n\t        catch (IllegalArgumentException e){ didRaiseError = true; }\n\t        catch (RuntimeException what) { fail(\"Unexpected runtime exception raised\",what); }\n        \tassertTrue(didRaiseError, \"Expecting a raised exception for zero length input\");\n        }\n        catch (ClientRuntimeException e) {\n\t        fail(\"Required cryptographic algorithm (MD5) is not available\", e);\n        }\n        catch (RuntimeException whatsthis){\n        \tfail(\"Unexpected exception class thrown\", whatsthis);\n        }\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/ri/cluster/ClusterNodeSpecImplTest.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster;\n\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterNodeSpecProviderTestBase;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.alphazero.connection.DefaultConnectionSpec;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 27, 2010\n * \n */\n\npublic class ClusterNodeSpecImplTest extends ClusterNodeSpecProviderTestBase {\n\t/* (non-Javadoc) @see org.jredis.ri.ProviderTestBase#newProviderInstance() */\n    @Override\n    final protected ClusterNodeSpec newProviderInstance () {\n\t    return new DefaultClusterNodeSpec (DefaultConnectionSpec.newSpec());\n    }\n    /* (non-Javadoc) @see org.jredis.cluster.ClusterNodeSpecProviderTestBase#newProviderInstance(org.jredis.connector.ConnectionSpec) */\n    @Override\n    final protected ClusterNodeSpec newProviderInstance (ConnectionSpec connectionSpec) {\n\t    return new DefaultClusterNodeSpec (connectionSpec);\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/ri/cluster/DefaultClusterSpecTest.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster;\n\nimport org.jredis.cluster.ClusterNodeSpec;\nimport org.jredis.cluster.ClusterSpec;\nimport org.jredis.cluster.ClusterSpecProviderTestBase;\nimport org.jredis.connector.ConnectionSpec;\nimport org.jredis.ri.cluster.DefaultClusterSpec;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 27, 2010\n * \n */\n\npublic class DefaultClusterSpecTest extends ClusterSpecProviderTestBase {\n\t/* (non-Javadoc) @see org.jredis.ri.ProviderTestBase#newProviderInstance() */\n    @Override\n    protected ClusterSpec newProviderInstance () {\n\t    return new DefaultClusterSpec ();\n    }\n\n\t/* (non-Javadoc) @see org.jredis.cluster.ClusterSpecProviderTestBase#newNodeSpec(org.jredis.connector.ConnectionSpec) */\n    @Override\n    protected ClusterNodeSpec newNodeSpec (ConnectionSpec connectionSpec) {\n\t    return new DefaultClusterNodeSpec(connectionSpec);\n    }\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/ri/cluster/support/CryptoHashUtilTest.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.ri.cluster.support;\n\nimport org.jredis.ClientRuntimeException;\nimport org.jredis.cluster.RefImplTestSuiteBase;\nimport org.jredis.ri.alphazero.support.Log;\nimport org.jredis.ri.cluster.support.CryptoHashUtils;\nimport org.testng.annotations.Test;\nimport static org.testng.Assert.*;\n\n/**\n * [TODO: document me!]\n *\n * @author  joubin (alphazero@sensesay.net)\n * @date    Mar 27, 2010\n * \n */\n\n@Test(suiteName=\"extensions-ri-cluster-tests2\")\npublic class CryptoHashUtilTest extends RefImplTestSuiteBase<Object> {\n\n\t// ------------------------------------------------------------------------\n\t// Specification Interface tested\n\t// ------------------------------------------------------------------------\n\t\n\t/* (non-Javadoc) @see org.jredis.ri.ProviderTestBase#newProviderInstance() */\n    @Override\n    protected Object newProviderInstance () {\n\t    return new CryptoHashUtils();\n    }\n\tprotected final Class<?> getSpecificationClass () {\n\t\treturn CryptoHashUtils.class;\n\t}\n\t\n\t// ------------------------------------------------------------------------\n\t// Tests\n\t// ------------------------------------------------------------------------\n\t\n\t/**\n\t * Test computeMd5 using byte[]\n\t */\n\t@SuppressWarnings(\"static-access\")\n    @Test\n\tpublic void testComputeMd5 () {\n\t\tLog.log(\"Testing Crptographic function computeMd5(byte[])\");\n\t\t\n\t\ttry {\n\t\t\tbyte[] data1 = data.getRandomBytes(255);\n\t        byte[] data1_md5 = CryptoHashUtils.computeMd5(data1);\n\t        assertNotNull(data1_md5, \"md5 digest should not be null\");\n\t        assertNotSame(data1_md5, data1, \"md5 digest result shoud not be the same as the input array\");\n\t        assertTrue(data1_md5.length > 0, \"md5 digest length should be non-zero\");\n\t        \n\t        // edge case - NULL input not allowed\n\t        boolean didRaiseError = false;\n\t        try {\n\t\t\t\tbyte[] nullref = null;\n\t        \tCryptoHashUtils.computeMd5(nullref);\n\t        }\n\t        catch (IllegalArgumentException e){ didRaiseError = true; }\n\t        catch (RuntimeException what) { fail(\"Unexpected runtime exception raised\",what); }\n        \tassertTrue(didRaiseError, \"Expecting a raised exception for null input\");\n\t        \n\t        // edge case - zero length input not allowed\n\t        didRaiseError = false;\n\t        try {\n\t\t\t\tbyte[] zerobytes = data.getRandomBytes(0);\n\t        \tCryptoHashUtils.computeMd5(zerobytes);\n\t        }\n\t        catch (IllegalArgumentException e){ didRaiseError = true; }\n\t        catch (RuntimeException what) { fail(\"Unexpected runtime exception raised\",what); }\n        \tassertTrue(didRaiseError, \"Expecting a raised exception for zero length input\");\n        }\n        catch (ClientRuntimeException e) {\n\t        fail(\"Required cryptographic algorithm (MD5) is not available\", e);\n        }\n        catch (RuntimeException whatsthis){\n        \tfail(\"Unexpected exception class thrown\", whatsthis);\n        }\n\t}\n}\n"
  },
  {
    "path": "extensions/ri/src/test/java/org/jredis/test/util/RunningAverage.java",
    "content": "/*\n *   Copyright 2009-2010 Joubin Houshyar\n * \n *   Licensed under the Apache License, Version 2.0 (the \"License\");\n *   you may not use this file except in compliance with the License.\n *   You may obtain a copy of the License at\n *    \n *   http://www.apache.org/licenses/LICENSE-2.0\n *    \n *   Unless required by applicable law or agreed to in writing, software\n *   distributed under the License is distributed on an \"AS IS\" BASIS,\n *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *   See the License for the specific language governing permissions and\n *   limitations under the License.\n */\n\npackage org.jredis.test.util;\n\npublic class RunningAverage {\n\tprivate float  avg;\n\tprivate long\tmax;\n\tprivate long\tmin = Long.MAX_VALUE;\n\tprivate long  n;\n\tpublic RunningAverage() {\n\t\tavg = 0;\n\t\tn = 0;\n\t}\n\tpublic long onMeasure (long delta){\n\t\tavg =((avg*n)+delta)/(++n);\n\t\tif(delta > max) max = delta;\n\t\tif(delta < min) min = delta;\n\t\treturn (long) avg;\n\t}\n    public long get () { return (long) avg; }\n\t/**\n     * @return\n     */\n    public long getMin () { return min; }\n    public long getMax () { return max; }\n\t/**\n     * \n     */\n    public long getCount () { return n; }\n}\n"
  },
  {
    "path": "pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<!-- coordination | build super pom -->\n\t<name>JRedis [Build POM]</name>\n\t<groupId>org.jredis</groupId>\n\t<artifactId>jredis</artifactId>\n\t<version>a.0-SNAPSHOT</version>\n\t<packaging>pom</packaging>\n\t<!-- <properties> <jredisVersion>a.0-SNAPSHOT</jredisVersion> </properties> -->\n\t<!-- production units -->\n\t<modules>\n\t\t<module>core</module>\n\t\t<module>examples</module>\n\t\t<!-- next time be more careful when you pull ..\n\t\t<module>extensions</module>\n\t\t-->\n\t</modules>\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-source-plugin</artifactId>\n\t\t\t\t<version>2.1.2</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>attach-sources</id>\n\t\t\t\t\t\t<phase>verify</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>jar</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\n\t\t\t<!-- JDK Compliance level -->\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.apache.maven.plugins</groupId>\n\t\t\t\t<artifactId>maven-compiler-plugin</artifactId>\n\t\t\t\t<version>2.0.2</version>\n\t\t\t\t<configuration>\n\t\t\t\t\t<source>1.6</source>\n\t\t\t\t\t<target>1.6</target>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\n\t\t\t<!-- surefire testrunner <plugin> <groupId>org.apache.maven.plugins</groupId> \n\t\t\t\t<artifactId>maven-surefire-plugin</artifactId> <configuration> <systemProperties> \n\t\t\t\t<property><name>redis.host</name> <value>localhost</value></property> <property><name>redis.port</name> \n\t\t\t\t<value>6379</value></property> <property><name>redis.password</name> <value>jredis</value></property> \n\t\t\t\t<property><name>redis.db.1</name> <value>13</value></property> <property><name>redis.db.2</name> \n\t\t\t\t<value>10</value></property> </systemProperties> </configuration> </plugin> -->\n\t\t</plugins>\n\t</build>\n\n\t<dependencyManagement>\n\t\t<!-- testing only -->\n\t\t<dependencies>\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.testng</groupId>\n\t\t\t\t<artifactId>testng</artifactId>\n\t\t\t\t<version>7.7.0</version>\n\t\t\t\t<scope>test</scope>\n\t\t\t</dependency>\n\t\t</dependencies>\n\t</dependencyManagement>\n\n\t<!-- info -->\n\t<inceptionYear>2009</inceptionYear>\n\t<licenses>\n\t\t<license>\n\t\t\t<name>Apache 2</name>\n\t\t\t<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n\t\t\t<distribution>all</distribution>\n\t\t\t<comments>Copyright 2009 (c) Joubin Houshyar - All Right Reserved</comments>\n\t\t</license>\n\t</licenses>\n\t<developers>\n\t\t<developer>\n\t\t\t<id>alphazero</id>\n\t\t\t<name>Joubin Houshyar</name>\n\t\t\t<email>alphazero@sensesay.net</email>\n\t\t\t<url>http://github.com/alphazero</url>\n\t\t\t<roles>\n\t\t\t\t<role>ReleaseManager</role>\n\t\t\t\t<role>Designer</role>\n\t\t\t\t<role>Developer</role>\n\t\t\t</roles>\n\t\t\t<timezone>UTC-5</timezone>\n\t\t</developer>\n\t\t<developer>\n\t\t\t<id>robey</id>\n\t\t\t<name>Robey Pointer</name>\n\t\t\t<email>robey@lag.net</email>\n\t\t\t<url>http://github.com/robey</url>\n\t\t\t<roles>\n\t\t\t\t<role>Contributor</role>\n\t\t\t</roles>\n\t\t\t<timezone>UTC-8</timezone>\n\t\t</developer>\n\t\t<developer>\n\t\t\t<id>szegedi</id>\n\t\t\t<name>Attila Szegedi</name>\n\t\t\t<url>http://github.com/szegedi</url>\n\t\t\t<roles>\n\t\t\t\t<role>Contributor</role>\n\t\t\t</roles>\n\t\t\t<timezone>UTC-8</timezone>\n\t\t</developer>\n\t\t<developer>\n\t\t\t<id>anthonylauzon</id>\n\t\t\t<name>Anthony Lauzon</name>\n\t\t\t<url>http://github.com/anthonylauzon</url>\n\t\t\t<roles>\n\t\t\t\t<role>Contributor</role>\n\t\t\t</roles>\n\t\t</developer>\n\t\t<developer>\n\t\t\t<id>gv0tch0</id>\n\t\t\t<name>Nik Kolev</name>\n\t\t\t<email>nkolev@gmail.com</email>\n\t\t\t<url>http://github.com/gv0tch0</url>\n\t\t\t<roles>\n\t\t\t\t<role>Contributor</role>\n\t\t\t</roles>\n\t\t\t<timezone>UTC-5</timezone>\n\t\t</developer>\n\t</developers>\n</project>\n"
  },
  {
    "path": "redis_version_compliance.txt",
    "content": "compliance:      Redis 3.0\ntested with:\t Redis 2.9.102 (4ad1b2f8/0) 64 bit\n\n-- compliance report (see api/src/test/org/jredis/compliance package --\n\n/// non-compliance report for JRedis       //////////////\n[ 0] auth\n[ 1] setex\n[ 2] setbit\n[ 3] getbit\n[ 4] setrange\n[ 5] getrange\n[ 6] select\n[ 7] shutdown\n[ 8] lpushx\n[ 9] rpushx\n[10] linsert\n[11] sync\n[12] monitor\n[13] persist\n[14] zrevrangebyscore\n[15] exec\n[16] blpop\n[17] brpop\n[18] brpoplpush\n[19] strlen\n[20] hsetnx\n[21] hmset\n[22] hmget\n[23] zunionstore\n[24] zinterstore\n[25] config\n[26] hincrby\n[27] subscribe\n[28] unsubscribe\n[29] psubscribe\n[30] punsubscribe\n[31] publish\n[32] watch\n[33] unwatch\n[34] object\n[35] client\n\n/////////////////////////////////////////////////////////\n\n/// non-compliance report for JRedisFuture //////////////\n[ 0] auth\n[ 1] setex\n[ 2] setbit\n[ 3] getbit\n[ 4] setrange\n[ 5] getrange\n[ 6] select\n[ 7] shutdown\n[ 8] lpushx\n[ 9] rpushx\n[10] linsert\n[11] sync\n[12] monitor\n[13] persist\n[14] zrevrangebyscore\n[15] multi\n[16] exec\n[17] discard\n[18] blpop\n[19] brpop\n[20] brpoplpush\n[21] strlen\n[22] hsetnx\n[23] hmset\n[24] hmget\n[25] zunionstore\n[26] zinterstore\n[27] config\n[28] hincrby\n[29] subscribe\n[30] unsubscribe\n[31] psubscribe\n[32] punsubscribe\n[33] publish\n[34] watch\n[35] unwatch\n[36] object\n[37] client\n\n/////////////////////////////////////////////////////////\n"
  }
]