Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit ed9b544e10b84cd43348ddfab7068b610a5df1f7 @antirez antirez committed Mar 22, 2009
Showing with 13,641 additions and 0 deletions.
  1. +12 −0 BETATESTING.txt
  2. +1 −0 BUGS
  3. +10 −0 COPYING
  4. +58 −0 Makefile
  5. +1 −0 README
  6. +17 −0 TODO
  7. +285 −0 adlist.c
  8. +90 −0 adlist.h
  9. +368 −0 ae.c
  10. +106 −0 ae.h
  11. +268 −0 anet.c
  12. +49 −0 anet.h
  13. +460 −0 benchmark.c
  14. +28 −0 client-libraries/README
  15. +2 −0 client-libraries/erlang/.hg_archival.txt
  16. +2 −0 client-libraries/erlang/.hgignore
  17. +22 −0 client-libraries/erlang/LICENSE
  18. +29 −0 client-libraries/erlang/Makefile
  19. +1 −0 client-libraries/erlang/include/erldis.hrl
  20. +9 −0 client-libraries/erlang/src/Makefile
  21. +272 −0 client-libraries/erlang/src/client.erl
  22. +82 −0 client-libraries/erlang/src/erldis.erl
  23. +68 −0 client-libraries/erlang/src/proto.erl
  24. +51 −0 client-libraries/erlang/support/include.mk
  25. +12 −0 client-libraries/erlang/test/Makefile
  26. +88 −0 client-libraries/erlang/test/erldis_tests.erl
  27. +10 −0 client-libraries/erlang/test/proto_tests.erl
  28. +330 −0 client-libraries/php/redis.php
  29. +78 −0 client-libraries/php/tests.php
  30. +930 −0 client-libraries/python/redis.py
  31. +20 −0 client-libraries/ruby/LICENSE
  32. +31 −0 client-libraries/ruby/README.markdown
  33. +12 −0 client-libraries/ruby/README.rdoc
  34. +58 −0 client-libraries/ruby/Rakefile
  35. +15 −0 client-libraries/ruby/bench.rb
  36. +33 −0 client-libraries/ruby/bin/distredis
  37. +16 −0 client-libraries/ruby/examples/basic.rb
  38. +18 −0 client-libraries/ruby/examples/incr-decr.rb
  39. +26 −0 client-libraries/ruby/examples/list.rb
  40. +36 −0 client-libraries/ruby/examples/sets.rb
  41. +11 −0 client-libraries/ruby/fill.rb
  42. +188 −0 client-libraries/ruby/lib/better_timeout.rb
  43. +111 −0 client-libraries/ruby/lib/dist_redis.rb
  44. +73 −0 client-libraries/ruby/lib/hash_ring.rb
  45. +836 −0 client-libraries/ruby/lib/redis.rb
  46. +267 −0 client-libraries/ruby/spec/redis_spec.rb
  47. +4 −0 client-libraries/ruby/spec/spec_helper.rb
  48. +116 −0 client-libraries/ruby/tasks/redis.tasks.rb
  49. +579 −0 dict.c
  50. +136 −0 dict.h
  51. +121 −0 doc/Benchmarks.html
  52. +39 −0 doc/BgsaveCommand.html
  53. +44 −0 doc/CommandReference.html
  54. +36 −0 doc/Credits.html
  55. +38 −0 doc/DbsizeCommand.html
  56. +42 −0 doc/DelCommand.html
  57. +37 −0 doc/DesignPatterns.html
  58. +42 −0 doc/ExistsCommand.html
  59. +47 −0 doc/FAQ.html
  60. +39 −0 doc/FlushallCommand.html
  61. +39 −0 doc/FlushdbCommand.html
  62. +39 −0 doc/GetCommand.html
  63. +43 −0 doc/IncrCommand.html
  64. +50 −0 doc/InfoCommand.html
  65. +42 −0 doc/KeysCommand.html
  66. +39 −0 doc/LastsaveCommand.html
  67. +41 −0 doc/LindexCommand.html
  68. +42 −0 doc/LlenCommand.html
  69. +41 −0 doc/LpopCommand.html
  70. +42 −0 doc/LrangeCommand.html
  71. +43 −0 doc/LremCommand.html
  72. +39 −0 doc/LsetCommand.html
  73. +47 −0 doc/LtrimCommand.html
  74. +42 −0 doc/MoveCommand.html
  75. +143 −0 doc/ProtocolSpecification.html
  76. +38 −0 doc/QuitCommand.html
  77. +109 −0 doc/README.html
  78. +39 −0 doc/RandomkeyCommand.html
  79. +39 −0 doc/RenameCommand.html
  80. +44 −0 doc/RenamenxCommand.html
  81. +44 −0 doc/ReplyTypes.html
  82. +40 −0 doc/RpushCommand.html
  83. +43 −0 doc/SaddCommand.html
  84. +39 −0 doc/SaveCommand.html
  85. +42 −0 doc/ScardCommand.html
  86. +39 −0 doc/SelectCommand.html
  87. +39 −0 doc/SetCommand.html
  88. +42 −0 doc/SetnxCommand.html
  89. +39 −0 doc/ShutdownCommand.html
  90. +40 −0 doc/SinterCommand.html
  91. +39 −0 doc/SinterstoreCommand.html
  92. +43 −0 doc/SismemberCommand.html
  93. +39 −0 doc/SmembersCommand.html
  94. +60 −0 doc/SortCommand.html
  95. +43 −0 doc/SremCommand.html
  96. +38 −0 doc/TemplateCommand.html
  97. +252 −0 doc/TwitterAlikeExample.html
  98. +44 −0 doc/TypeCommand.html
  99. +40 −0 doc/VersionControl.html
  100. +36 −0 doc/index.html
  101. BIN doc/redis.png
  102. +25 −0 doc/style.css
  103. +340 −0 redis-cli.c
  104. +3,037 −0 redis.c
  105. +66 −0 redis.conf
  106. +329 −0 sds.c
  107. +63 −0 sds.h
  108. +807 −0 test-redis.tcl
  109. +82 −0 zmalloc.c
  110. +40 −0 zmalloc.h
@@ -0,0 +1,12 @@
+Hello betatester!
+
+This Redis Server distribution is just a preview, it is by no mean an usable
+product, but probably it can already give you some feeling about what the
+final release is going to be.
+
+Be aware that if you want to use Redis in production the server may not be perfectly stable or may cotanin unfixed bugs. We did our best to ensure this distribution is of good quality and bug free but the development is currently very fast.
+
+Please send feedbacks to antirez at gmail dot com.
+
+Enjoy,
+antirez
1 BUGS
@@ -0,0 +1 @@
+Plese check http://code.google.com/p/redis/issues/list
10 COPYING
@@ -0,0 +1,10 @@
+Copyright (c) 2006-2009, Salvatore Sanfilippo
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,58 @@
+# Redis Makefile
+# Copyright (C) 2009 Salvatore Sanfilippo <antirez at gmail dot com>
+# This file is released under the BSD license, see the COPYING file
+
+DEBUG?= -g
+CFLAGS?= -O2 -Wall -W -DSDS_ABORT_ON_OOM
+CCOPT= $(CFLAGS)
+
+OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o
+BENCHOBJ = ae.o anet.o benchmark.o sds.o adlist.o zmalloc.o
+CLIOBJ = anet.o sds.o adlist.o redis-cli.o zmalloc.o
+
+PRGNAME = redis-server
+BENCHPRGNAME = redis-benchmark
+CLIPRGNAME = redis-cli
+
+all: redis-server redis-benchmark redis-cli
+
+# Deps (use make dep to generate this)
+adlist.o: adlist.c adlist.h
+ae.o: ae.c ae.h
+anet.o: anet.c anet.h
+benchmark.o: benchmark.c ae.h anet.h sds.h adlist.h
+dict.o: dict.c dict.h
+redis-cli.o: redis-cli.c anet.h sds.h adlist.h
+redis.o: redis.c ae.h sds.h anet.h dict.h adlist.h
+sds.o: sds.c sds.h
+sha1.o: sha1.c sha1.h
+zmalloc.o: zmalloc.c
+
+redis-server: $(OBJ)
+ $(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ)
+ @echo ""
+ @echo "Hint: To run the test-redis.tcl script is a good idea."
+ @echo "Launch the redis server with ./redis-server, then in another"
+ @echo "terminal window enter this directory and run 'make test'."
+ @echo ""
+
+redis-benchmark: $(BENCHOBJ)
+ $(CC) -o $(BENCHPRGNAME) $(CCOPT) $(DEBUG) $(BENCHOBJ)
+
+redis-cli: $(CLIOBJ)
+ $(CC) -o $(CLIPRGNAME) $(CCOPT) $(DEBUG) $(CLIOBJ)
+
+.c.o:
+ $(CC) -c $(CCOPT) $(DEBUG) $(COMPILE_TIME) $<
+
+clean:
+ rm -rf $(PRGNAME) $(BENCHPRGNAME) $(CLIPRGNAME) *.o
+
+dep:
+ $(CC) -MM *.c
+
+test:
+ tclsh test-redis.tcl
+
+bench:
+ ./redis-benchmark
1 README
@@ -0,0 +1 @@
+Check the 'doc' directory. doc/README.html is a good starting point :)
17 TODO
@@ -0,0 +1,17 @@
+BETA 8 TODO
+- keys expire
+- sunion ssub
+- write integers in a special way on disk (and on memory?)
+- compact types for disk storing of short strings (no 4 bytes overhead!)
+- network layer stresser in test in demo
+- maxclients directive
+- check 'server.dirty' everywere
+- replication tests
+- command line client. If the last argument of a bulk command is missing get it from stdin. Example:
+ $ echo "bar" | redis-client SET foo
+ $ redis-client SET foo bar
+ $ redis-client GET foo
+ bar
+ $
+- Make Redis aware of the memory it is using thanks to getrusage() and report this info with the INFO command.
+- INFO command: clients, slave/master, requests/second in the last N seconds, memory usage, uptime, dirty, lastsave
285 adlist.c
@@ -0,0 +1,285 @@
+/* adlist.c - A generic doubly linked list implementation
+ *
+ * Copyright (c) 2006-2009, Salvatore Sanfilippo <antirez at gmail dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Redis nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdlib.h>
+#include "adlist.h"
+#include "zmalloc.h"
+
+/* Create a new list. The created list can be freed with
+ * AlFreeList(), but private value of every node need to be freed
+ * by the user before to call AlFreeList().
+ *
+ * On error, NULL is returned. Otherwise the pointer to the new list. */
+list *listCreate(void)
+{
+ struct list *list;
+
+ if ((list = zmalloc(sizeof(*list))) == NULL)
+ return NULL;
+ list->head = list->tail = NULL;
+ list->len = 0;
+ list->dup = NULL;
+ list->free = NULL;
+ list->match = NULL;
+ return list;
+}
+
+/* Free the whole list.
+ *
+ * This function can't fail. */
+void listRelease(list *list)
+{
+ unsigned int len;
+ listNode *current, *next;
+
+ current = list->head;
+ len = list->len;
+ while(len--) {
+ next = current->next;
+ if (list->free) list->free(current->value);
+ zfree(current);
+ current = next;
+ }
+ zfree(list);
+}
+
+/* Add a new node to the list, to head, contaning the specified 'value'
+ * pointer as value.
+ *
+ * On error, NULL is returned and no operation is performed (i.e. the
+ * list remains unaltered).
+ * On success the 'list' pointer you pass to the function is returned. */
+list *listAddNodeHead(list *list, void *value)
+{
+ listNode *node;
+
+ if ((node = zmalloc(sizeof(*node))) == NULL)
+ return NULL;
+ node->value = value;
+ if (list->len == 0) {
+ list->head = list->tail = node;
+ node->prev = node->next = NULL;
+ } else {
+ node->prev = NULL;
+ node->next = list->head;
+ list->head->prev = node;
+ list->head = node;
+ }
+ list->len++;
+ return list;
+}
+
+/* Add a new node to the list, to tail, contaning the specified 'value'
+ * pointer as value.
+ *
+ * On error, NULL is returned and no operation is performed (i.e. the
+ * list remains unaltered).
+ * On success the 'list' pointer you pass to the function is returned. */
+list *listAddNodeTail(list *list, void *value)
+{
+ listNode *node;
+
+ if ((node = zmalloc(sizeof(*node))) == NULL)
+ return NULL;
+ node->value = value;
+ if (list->len == 0) {
+ list->head = list->tail = node;
+ node->prev = node->next = NULL;
+ } else {
+ node->prev = list->tail;
+ node->next = NULL;
+ list->tail->next = node;
+ list->tail = node;
+ }
+ list->len++;
+ return list;
+}
+
+/* Remove the specified node from the specified list.
+ * It's up to the caller to free the private value of the node.
+ *
+ * This function can't fail. */
+void listDelNode(list *list, listNode *node)
+{
+ if (node->prev)
+ node->prev->next = node->next;
+ else
+ list->head = node->next;
+ if (node->next)
+ node->next->prev = node->prev;
+ else
+ list->tail = node->prev;
+ if (list->free) list->free(node->value);
+ zfree(node);
+ list->len--;
+}
+
+/* Returns a list iterator 'iter'. After the initialization every
+ * call to listNextElement() will return the next element of the list.
+ *
+ * This function can't fail. */
+listIter *listGetIterator(list *list, int direction)
+{
+ listIter *iter;
+
+ if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL;
+ if (direction == AL_START_HEAD)
+ iter->next = list->head;
+ else
+ iter->next = list->tail;
+ iter->direction = direction;
+ return iter;
+}
+
+/* Release the iterator memory */
+void listReleaseIterator(listIter *iter) {
+ zfree(iter);
+}
+
+/* Return the next element of an iterator.
+ * It's valid to remove the currently returned element using
+ * listDelNode(), but not to remove other elements.
+ *
+ * The function returns a pointer to the next element of the list,
+ * or NULL if there are no more elements, so the classical usage patter
+ * is:
+ *
+ * iter = listGetItarotr(list,<direction>);
+ * while ((node = listNextIterator(iter)) != NULL) {
+ * DoSomethingWith(listNodeValue(node));
+ * }
+ *
+ * */
+listNode *listNextElement(listIter *iter)
+{
+ listNode *current = iter->next;
+
+ if (current != NULL) {
+ if (iter->direction == AL_START_HEAD)
+ iter->next = current->next;
+ else
+ iter->next = current->prev;
+ }
+ return current;
+}
+
+/* Duplicate the whole list. On out of memory NULL is returned.
+ * On success a copy of the original list is returned.
+ *
+ * The 'Dup' method set with listSetDupMethod() function is used
+ * to copy the node value. Otherwise the same pointer value of
+ * the original node is used as value of the copied node.
+ *
+ * The original list both on success or error is never modified. */
+list *listDup(list *orig)
+{
+ list *copy;
+ listIter *iter;
+ listNode *node;
+
+ if ((copy = listCreate()) == NULL)
+ return NULL;
+ copy->dup = orig->dup;
+ copy->free = orig->free;
+ copy->match = orig->match;
+ iter = listGetIterator(orig, AL_START_HEAD);
+ while((node = listNextElement(iter)) != NULL) {
+ void *value;
+
+ if (copy->dup) {
+ value = copy->dup(node->value);
+ if (value == NULL) {
+ listRelease(copy);
+ listReleaseIterator(iter);
+ return NULL;
+ }
+ } else
+ value = node->value;
+ if (listAddNodeTail(copy, value) == NULL) {
+ listRelease(copy);
+ listReleaseIterator(iter);
+ return NULL;
+ }
+ }
+ listReleaseIterator(iter);
+ return copy;
+}
+
+/* Search the list for a node matching a given key.
+ * The match is performed using the 'match' method
+ * set with listSetMatchMethod(). If no 'match' method
+ * is set, the 'value' pointer of every node is directly
+ * compared with the 'key' pointer.
+ *
+ * On success the first matching node pointer is returned
+ * (search starts from head). If no matching node exists
+ * NULL is returned. */
+listNode *listSearchKey(list *list, void *key)
+{
+ listIter *iter;
+ listNode *node;
+
+ iter = listGetIterator(list, AL_START_HEAD);
+ while((node = listNextElement(iter)) != NULL) {
+ if (list->match) {
+ if (list->match(node->value, key)) {
+ listReleaseIterator(iter);
+ return node;
+ }
+ } else {
+ if (key == node->value) {
+ listReleaseIterator(iter);
+ return node;
+ }
+ }
+ }
+ listReleaseIterator(iter);
+ return NULL;
+}
+
+/* Return the element at the specified zero-based index
+ * where 0 is the head, 1 is the element next to head
+ * and so on. Negative integers are used in order to count
+ * from the tail, -1 is the last element, -2 the penultimante
+ * and so on. If the index is out of range NULL is returned. */
+listNode *listIndex(list *list, int index) {
+ listNode *n;
+
+ if (index < 0) {
+ index = (-index)-1;
+ n = list->tail;
+ while(index-- && n) n = n->prev;
+ } else {
+ n = list->head;
+ while(index-- && n) n = n->next;
+ }
+ return n;
+}
Oops, something went wrong.

0 comments on commit ed9b544

Please sign in to comment.