redis-server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. data/LICENSE +38 -0
  2. data/README.md +33 -0
  3. data/bin/redis +114 -0
  4. data/redis/Makefile +5 -0
  5. data/redis/extconf.rb +3 -0
  6. data/redis/redis-2.2.11/00-RELEASENOTES +199 -0
  7. data/redis/redis-2.2.11/BUGS +1 -0
  8. data/redis/redis-2.2.11/CONTRIBUTING +13 -0
  9. data/redis/redis-2.2.11/COPYING +10 -0
  10. data/redis/redis-2.2.11/Changelog +1032 -0
  11. data/redis/redis-2.2.11/INSTALL +30 -0
  12. data/redis/redis-2.2.11/Makefile +22 -0
  13. data/redis/redis-2.2.11/README +83 -0
  14. data/redis/redis-2.2.11/TODO +4 -0
  15. data/redis/redis-2.2.11/client-libraries/README +11 -0
  16. data/redis/redis-2.2.11/deps/hiredis/COPYING +10 -0
  17. data/redis/redis-2.2.11/deps/hiredis/Makefile +115 -0
  18. data/redis/redis-2.2.11/deps/hiredis/README.md +311 -0
  19. data/redis/redis-2.2.11/deps/hiredis/TODO +2 -0
  20. data/redis/redis-2.2.11/deps/hiredis/adapters/ae.h +95 -0
  21. data/redis/redis-2.2.11/deps/hiredis/adapters/libev.h +113 -0
  22. data/redis/redis-2.2.11/deps/hiredis/adapters/libevent.h +76 -0
  23. data/redis/redis-2.2.11/deps/hiredis/async.c +321 -0
  24. data/redis/redis-2.2.11/deps/hiredis/async.h +112 -0
  25. data/redis/redis-2.2.11/deps/hiredis/example-ae.c +53 -0
  26. data/redis/redis-2.2.11/deps/hiredis/example-libev.c +47 -0
  27. data/redis/redis-2.2.11/deps/hiredis/example-libevent.c +48 -0
  28. data/redis/redis-2.2.11/deps/hiredis/example.c +67 -0
  29. data/redis/redis-2.2.11/deps/hiredis/fmacros.h +15 -0
  30. data/redis/redis-2.2.11/deps/hiredis/hiredis.c +1058 -0
  31. data/redis/redis-2.2.11/deps/hiredis/hiredis.h +170 -0
  32. data/redis/redis-2.2.11/deps/hiredis/net.c +170 -0
  33. data/redis/redis-2.2.11/deps/hiredis/net.h +43 -0
  34. data/redis/redis-2.2.11/deps/hiredis/sds.c +479 -0
  35. data/redis/redis-2.2.11/deps/hiredis/sds.h +77 -0
  36. data/redis/redis-2.2.11/deps/hiredis/test.c +479 -0
  37. data/redis/redis-2.2.11/deps/hiredis/util.h +40 -0
  38. data/redis/redis-2.2.11/deps/linenoise/Makefile +10 -0
  39. data/redis/redis-2.2.11/deps/linenoise/README.markdown +45 -0
  40. data/redis/redis-2.2.11/deps/linenoise/example.c +27 -0
  41. data/redis/redis-2.2.11/deps/linenoise/linenoise.c +609 -0
  42. data/redis/redis-2.2.11/deps/linenoise/linenoise.h +55 -0
  43. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER +214 -0
  44. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER-2 +343 -0
  45. data/redis/redis-2.2.11/doc/AppendCommand.html +48 -0
  46. data/redis/redis-2.2.11/doc/AppendOnlyFileHowto.html +41 -0
  47. data/redis/redis-2.2.11/doc/AuthCommand.html +39 -0
  48. data/redis/redis-2.2.11/doc/Benchmarks.html +129 -0
  49. data/redis/redis-2.2.11/doc/BgrewriteaofCommand.html +41 -0
  50. data/redis/redis-2.2.11/doc/BgsaveCommand.html +39 -0
  51. data/redis/redis-2.2.11/doc/BlpopCommand.html +51 -0
  52. data/redis/redis-2.2.11/doc/BrpoplpushCommand.html +39 -0
  53. data/redis/redis-2.2.11/doc/CommandReference.html +47 -0
  54. data/redis/redis-2.2.11/doc/Comparisons.html +42 -0
  55. data/redis/redis-2.2.11/doc/ConfigCommand.html +76 -0
  56. data/redis/redis-2.2.11/doc/Configuration.html +38 -0
  57. data/redis/redis-2.2.11/doc/ConnectionHandlingSidebar.html +36 -0
  58. data/redis/redis-2.2.11/doc/ControlCommandsSidebar.html +36 -0
  59. data/redis/redis-2.2.11/doc/Credits.html +38 -0
  60. data/redis/redis-2.2.11/doc/DbsizeCommand.html +38 -0
  61. data/redis/redis-2.2.11/doc/DelCommand.html +41 -0
  62. data/redis/redis-2.2.11/doc/DesignPatterns.html +37 -0
  63. data/redis/redis-2.2.11/doc/EventLibray.html +44 -0
  64. data/redis/redis-2.2.11/doc/ExistsCommand.html +42 -0
  65. data/redis/redis-2.2.11/doc/ExpireCommand.html +96 -0
  66. data/redis/redis-2.2.11/doc/FAQ.html +70 -0
  67. data/redis/redis-2.2.11/doc/Features.html +38 -0
  68. data/redis/redis-2.2.11/doc/FlushallCommand.html +39 -0
  69. data/redis/redis-2.2.11/doc/FlushdbCommand.html +39 -0
  70. data/redis/redis-2.2.11/doc/FromSqlToDataStructures.html +37 -0
  71. data/redis/redis-2.2.11/doc/GenericCommandsSidebar.html +36 -0
  72. data/redis/redis-2.2.11/doc/GetCommand.html +39 -0
  73. data/redis/redis-2.2.11/doc/GetbitCommand.html +39 -0
  74. data/redis/redis-2.2.11/doc/GetsetCommand.html +38 -0
  75. data/redis/redis-2.2.11/doc/HackingStrings.html +83 -0
  76. data/redis/redis-2.2.11/doc/HashCommandsSidebar.html +36 -0
  77. data/redis/redis-2.2.11/doc/Hashes.html +37 -0
  78. data/redis/redis-2.2.11/doc/HdelCommand.html +39 -0
  79. data/redis/redis-2.2.11/doc/HexistsCommand.html +39 -0
  80. data/redis/redis-2.2.11/doc/HgetCommand.html +39 -0
  81. data/redis/redis-2.2.11/doc/HgetallCommand.html +40 -0
  82. data/redis/redis-2.2.11/doc/HincrbyCommand.html +45 -0
  83. data/redis/redis-2.2.11/doc/HlenCommand.html +38 -0
  84. data/redis/redis-2.2.11/doc/HmgetCommand.html +40 -0
  85. data/redis/redis-2.2.11/doc/HmsetCommand.html +40 -0
  86. data/redis/redis-2.2.11/doc/HsetCommand.html +40 -0
  87. data/redis/redis-2.2.11/doc/HsetnxCommand.html +41 -0
  88. data/redis/redis-2.2.11/doc/IncrCommand.html +43 -0
  89. data/redis/redis-2.2.11/doc/InfoCommand.html +48 -0
  90. data/redis/redis-2.2.11/doc/IntroductionToRedisDataTypes.html +152 -0
  91. data/redis/redis-2.2.11/doc/KeysCommand.html +43 -0
  92. data/redis/redis-2.2.11/doc/LastsaveCommand.html +39 -0
  93. data/redis/redis-2.2.11/doc/LindexCommand.html +40 -0
  94. data/redis/redis-2.2.11/doc/ListCommandsSidebar.html +36 -0
  95. data/redis/redis-2.2.11/doc/Lists.html +42 -0
  96. data/redis/redis-2.2.11/doc/LlenCommand.html +41 -0
  97. data/redis/redis-2.2.11/doc/LpopCommand.html +41 -0
  98. data/redis/redis-2.2.11/doc/LrangeCommand.html +47 -0
  99. data/redis/redis-2.2.11/doc/LremCommand.html +41 -0
  100. data/redis/redis-2.2.11/doc/LsetCommand.html +38 -0
  101. data/redis/redis-2.2.11/doc/LtrimCommand.html +47 -0
  102. data/redis/redis-2.2.11/doc/MgetCommand.html +52 -0
  103. data/redis/redis-2.2.11/doc/MonitorCommand.html +63 -0
  104. data/redis/redis-2.2.11/doc/MoveCommand.html +42 -0
  105. data/redis/redis-2.2.11/doc/MsetCommand.html +44 -0
  106. data/redis/redis-2.2.11/doc/MultiExecCommand.html +166 -0
  107. data/redis/redis-2.2.11/doc/NonexistentCommands.html +51 -0
  108. data/redis/redis-2.2.11/doc/ObjectHashMappers.html +39 -0
  109. data/redis/redis-2.2.11/doc/Pipelining.html +36 -0
  110. data/redis/redis-2.2.11/doc/ProgrammingExamples.html +38 -0
  111. data/redis/redis-2.2.11/doc/ProtocolSpecification.html +137 -0
  112. data/redis/redis-2.2.11/doc/PublishSubscribe.html +115 -0
  113. data/redis/redis-2.2.11/doc/QuickStart.html +68 -0
  114. data/redis/redis-2.2.11/doc/QuitCommand.html +38 -0
  115. data/redis/redis-2.2.11/doc/README.html +119 -0
  116. data/redis/redis-2.2.11/doc/RandomkeyCommand.html +39 -0
  117. data/redis/redis-2.2.11/doc/Redis0100ChangeLog.html +67 -0
  118. data/redis/redis-2.2.11/doc/Redis0900ChangeLog.html +56 -0
  119. data/redis/redis-2.2.11/doc/RedisBigData.html +61 -0
  120. data/redis/redis-2.2.11/doc/RedisCLI.html +37 -0
  121. data/redis/redis-2.2.11/doc/RedisEventLibrary.html +70 -0
  122. data/redis/redis-2.2.11/doc/RedisGuides.html +37 -0
  123. data/redis/redis-2.2.11/doc/RedisInternals.html +38 -0
  124. data/redis/redis-2.2.11/doc/RedisPipelining.html +93 -0
  125. data/redis/redis-2.2.11/doc/RedisStatus.html +56 -0
  126. data/redis/redis-2.2.11/doc/Redis_1_2_0_Changelog.html +40 -0
  127. data/redis/redis-2.2.11/doc/Redis_2_0_0_Changelog.html +62 -0
  128. data/redis/redis-2.2.11/doc/Redis_2_0_Whats_new.html +59 -0
  129. data/redis/redis-2.2.11/doc/RenameCommand.html +39 -0
  130. data/redis/redis-2.2.11/doc/RenamenxCommand.html +42 -0
  131. data/redis/redis-2.2.11/doc/ReplicationHowto.html +43 -0
  132. data/redis/redis-2.2.11/doc/ReplyTypes.html +42 -0
  133. data/redis/redis-2.2.11/doc/RoadMap.html +38 -0
  134. data/redis/redis-2.2.11/doc/RpoplpushCommand.html +44 -0
  135. data/redis/redis-2.2.11/doc/RpushCommand.html +40 -0
  136. data/redis/redis-2.2.11/doc/SaddCommand.html +41 -0
  137. data/redis/redis-2.2.11/doc/SaveCommand.html +39 -0
  138. data/redis/redis-2.2.11/doc/ScardCommand.html +41 -0
  139. data/redis/redis-2.2.11/doc/SdiffCommand.html +45 -0
  140. data/redis/redis-2.2.11/doc/SdiffstoreCommand.html +38 -0
  141. data/redis/redis-2.2.11/doc/SelectCommand.html +39 -0
  142. data/redis/redis-2.2.11/doc/SetCommand.html +39 -0
  143. data/redis/redis-2.2.11/doc/SetCommandsSidebar.html +36 -0
  144. data/redis/redis-2.2.11/doc/SetbitCommand.html +45 -0
  145. data/redis/redis-2.2.11/doc/SetexCommand.html +42 -0
  146. data/redis/redis-2.2.11/doc/SetnxCommand.html +51 -0
  147. data/redis/redis-2.2.11/doc/SetrangeCommand.html +58 -0
  148. data/redis/redis-2.2.11/doc/Sets.html +36 -0
  149. data/redis/redis-2.2.11/doc/ShutdownCommand.html +39 -0
  150. data/redis/redis-2.2.11/doc/SideBar.html +36 -0
  151. data/redis/redis-2.2.11/doc/SinterCommand.html +40 -0
  152. data/redis/redis-2.2.11/doc/SinterstoreCommand.html +39 -0
  153. data/redis/redis-2.2.11/doc/SismemberCommand.html +42 -0
  154. data/redis/redis-2.2.11/doc/SlaveofCommand.html +41 -0
  155. data/redis/redis-2.2.11/doc/SmembersCommand.html +38 -0
  156. data/redis/redis-2.2.11/doc/SmoveCommand.html +44 -0
  157. data/redis/redis-2.2.11/doc/SortCommand.html +75 -0
  158. data/redis/redis-2.2.11/doc/SortedSetCommandsSidebar.html +36 -0
  159. data/redis/redis-2.2.11/doc/SortedSets.html +36 -0
  160. data/redis/redis-2.2.11/doc/Speed.html +38 -0
  161. data/redis/redis-2.2.11/doc/SponsorshipHistory.html +38 -0
  162. data/redis/redis-2.2.11/doc/SpopCommand.html +40 -0
  163. data/redis/redis-2.2.11/doc/SrandmemberCommand.html +40 -0
  164. data/redis/redis-2.2.11/doc/SremCommand.html +42 -0
  165. data/redis/redis-2.2.11/doc/StringCommandsSidebar.html +36 -0
  166. data/redis/redis-2.2.11/doc/Strings.html +37 -0
  167. data/redis/redis-2.2.11/doc/StrlenCommand.html +39 -0
  168. data/redis/redis-2.2.11/doc/SubstrCommand.html +52 -0
  169. data/redis/redis-2.2.11/doc/SunionCommand.html +40 -0
  170. data/redis/redis-2.2.11/doc/SunionstoreCommand.html +38 -0
  171. data/redis/redis-2.2.11/doc/SupportedLanguages.html +60 -0
  172. data/redis/redis-2.2.11/doc/SupportedPlatforms.html +37 -0
  173. data/redis/redis-2.2.11/doc/TemplateCommand.html +38 -0
  174. data/redis/redis-2.2.11/doc/TtlCommand.html +38 -0
  175. data/redis/redis-2.2.11/doc/TwitterAlikeExample.html +250 -0
  176. data/redis/redis-2.2.11/doc/TypeCommand.html +46 -0
  177. data/redis/redis-2.2.11/doc/UnstableSource.html +39 -0
  178. data/redis/redis-2.2.11/doc/VirtualMemorySpecification.html +156 -0
  179. data/redis/redis-2.2.11/doc/VirtualMemoryUserGuide.html +66 -0
  180. data/redis/redis-2.2.11/doc/ZaddCommand.html +43 -0
  181. data/redis/redis-2.2.11/doc/ZcardCommand.html +41 -0
  182. data/redis/redis-2.2.11/doc/ZincrbyCommand.html +42 -0
  183. data/redis/redis-2.2.11/doc/ZrangeCommand.html +42 -0
  184. data/redis/redis-2.2.11/doc/ZrangebyscoreCommand.html +77 -0
  185. data/redis/redis-2.2.11/doc/ZrankCommand.html +43 -0
  186. data/redis/redis-2.2.11/doc/ZremCommand.html +42 -0
  187. data/redis/redis-2.2.11/doc/ZremrangebyrankCommand.html +39 -0
  188. data/redis/redis-2.2.11/doc/ZremrangebyscoreCommand.html +39 -0
  189. data/redis/redis-2.2.11/doc/ZscoreCommand.html +41 -0
  190. data/redis/redis-2.2.11/doc/ZunionCommand.html +42 -0
  191. data/redis/redis-2.2.11/doc/ZunionstoreCommand.html +43 -0
  192. data/redis/redis-2.2.11/doc/index.html +43 -0
  193. data/redis/redis-2.2.11/doc/redis.png +0 -0
  194. data/redis/redis-2.2.11/doc/style.css +25 -0
  195. data/redis/redis-2.2.11/redis.conf +417 -0
  196. data/redis/redis-2.2.11/src/Makefile +177 -0
  197. data/redis/redis-2.2.11/src/adlist.c +325 -0
  198. data/redis/redis-2.2.11/src/adlist.h +92 -0
  199. data/redis/redis-2.2.11/src/ae.c +390 -0
  200. data/redis/redis-2.2.11/src/ae.h +117 -0
  201. data/redis/redis-2.2.11/src/ae_epoll.c +91 -0
  202. data/redis/redis-2.2.11/src/ae_kqueue.c +93 -0
  203. data/redis/redis-2.2.11/src/ae_select.c +72 -0
  204. data/redis/redis-2.2.11/src/anet.c +347 -0
  205. data/redis/redis-2.2.11/src/anet.h +57 -0
  206. data/redis/redis-2.2.11/src/aof.c +675 -0
  207. data/redis/redis-2.2.11/src/config.c +627 -0
  208. data/redis/redis-2.2.11/src/config.h +64 -0
  209. data/redis/redis-2.2.11/src/db.c +543 -0
  210. data/redis/redis-2.2.11/src/debug.c +314 -0
  211. data/redis/redis-2.2.11/src/dict.c +721 -0
  212. data/redis/redis-2.2.11/src/dict.h +156 -0
  213. data/redis/redis-2.2.11/src/fmacros.h +15 -0
  214. data/redis/redis-2.2.11/src/help.h +638 -0
  215. data/redis/redis-2.2.11/src/intset.c +422 -0
  216. data/redis/redis-2.2.11/src/intset.h +19 -0
  217. data/redis/redis-2.2.11/src/lzf.h +100 -0
  218. data/redis/redis-2.2.11/src/lzfP.h +159 -0
  219. data/redis/redis-2.2.11/src/lzf_c.c +295 -0
  220. data/redis/redis-2.2.11/src/lzf_d.c +150 -0
  221. data/redis/redis-2.2.11/src/mkreleasehdr.sh +9 -0
  222. data/redis/redis-2.2.11/src/multi.c +268 -0
  223. data/redis/redis-2.2.11/src/networking.c +899 -0
  224. data/redis/redis-2.2.11/src/object.c +484 -0
  225. data/redis/redis-2.2.11/src/pqsort.c +197 -0
  226. data/redis/redis-2.2.11/src/pqsort.h +15 -0
  227. data/redis/redis-2.2.11/src/pubsub.c +267 -0
  228. data/redis/redis-2.2.11/src/rdb.c +1020 -0
  229. data/redis/redis-2.2.11/src/redis-benchmark.c +530 -0
  230. data/redis/redis-2.2.11/src/redis-check-aof.c +185 -0
  231. data/redis/redis-2.2.11/src/redis-check-dump.c +681 -0
  232. data/redis/redis-2.2.11/src/redis-cli.c +773 -0
  233. data/redis/redis-2.2.11/src/redis.c +1677 -0
  234. data/redis/redis-2.2.11/src/redis.h +1022 -0
  235. data/redis/redis-2.2.11/src/release.c +13 -0
  236. data/redis/redis-2.2.11/src/replication.c +557 -0
  237. data/redis/redis-2.2.11/src/sds.c +639 -0
  238. data/redis/redis-2.2.11/src/sds.h +78 -0
  239. data/redis/redis-2.2.11/src/sha1.c +276 -0
  240. data/redis/redis-2.2.11/src/sha1.h +17 -0
  241. data/redis/redis-2.2.11/src/solarisfixes.h +22 -0
  242. data/redis/redis-2.2.11/src/sort.c +389 -0
  243. data/redis/redis-2.2.11/src/syncio.c +154 -0
  244. data/redis/redis-2.2.11/src/t_hash.c +476 -0
  245. data/redis/redis-2.2.11/src/t_list.c +986 -0
  246. data/redis/redis-2.2.11/src/t_set.c +610 -0
  247. data/redis/redis-2.2.11/src/t_string.c +438 -0
  248. data/redis/redis-2.2.11/src/t_zset.c +1084 -0
  249. data/redis/redis-2.2.11/src/testhelp.h +54 -0
  250. data/redis/redis-2.2.11/src/util.c +243 -0
  251. data/redis/redis-2.2.11/src/valgrind.sup +5 -0
  252. data/redis/redis-2.2.11/src/version.h +1 -0
  253. data/redis/redis-2.2.11/src/vm.c +1149 -0
  254. data/redis/redis-2.2.11/src/ziplist.c +1323 -0
  255. data/redis/redis-2.2.11/src/ziplist.h +15 -0
  256. data/redis/redis-2.2.11/src/zipmap.c +455 -0
  257. data/redis/redis-2.2.11/src/zipmap.h +48 -0
  258. data/redis/redis-2.2.11/src/zmalloc.c +278 -0
  259. data/redis/redis-2.2.11/src/zmalloc.h +47 -0
  260. data/redis/redis-2.2.11/tests/assets/default.conf +308 -0
  261. data/redis/redis-2.2.11/tests/integration/aof.tcl +104 -0
  262. data/redis/redis-2.2.11/tests/integration/redis-cli.tcl +208 -0
  263. data/redis/redis-2.2.11/tests/integration/replication.tcl +98 -0
  264. data/redis/redis-2.2.11/tests/support/redis.tcl +241 -0
  265. data/redis/redis-2.2.11/tests/support/server.tcl +294 -0
  266. data/redis/redis-2.2.11/tests/support/test.tcl +190 -0
  267. data/redis/redis-2.2.11/tests/support/tmpfile.tcl +15 -0
  268. data/redis/redis-2.2.11/tests/support/util.tcl +296 -0
  269. data/redis/redis-2.2.11/tests/test_helper.tcl +221 -0
  270. data/redis/redis-2.2.11/tests/unit/auth.tcl +15 -0
  271. data/redis/redis-2.2.11/tests/unit/basic.tcl +616 -0
  272. data/redis/redis-2.2.11/tests/unit/cas.tcl +135 -0
  273. data/redis/redis-2.2.11/tests/unit/expire.tcl +74 -0
  274. data/redis/redis-2.2.11/tests/unit/other.tcl +240 -0
  275. data/redis/redis-2.2.11/tests/unit/printver.tcl +6 -0
  276. data/redis/redis-2.2.11/tests/unit/protocol.tcl +62 -0
  277. data/redis/redis-2.2.11/tests/unit/pubsub.tcl +195 -0
  278. data/redis/redis-2.2.11/tests/unit/quit.tcl +40 -0
  279. data/redis/redis-2.2.11/tests/unit/sort.tcl +189 -0
  280. data/redis/redis-2.2.11/tests/unit/type/hash.tcl +300 -0
  281. data/redis/redis-2.2.11/tests/unit/type/list.tcl +819 -0
  282. data/redis/redis-2.2.11/tests/unit/type/set.tcl +334 -0
  283. data/redis/redis-2.2.11/tests/unit/type/zset.tcl +587 -0
  284. data/redis/redis-2.2.11/utils/build-static-symbols.tcl +22 -0
  285. data/redis/redis-2.2.11/utils/generate-command-help.rb +112 -0
  286. data/redis/redis-2.2.11/utils/mktarball.sh +13 -0
  287. data/redis/redis-2.2.11/utils/redis-copy.rb +78 -0
  288. data/redis/redis-2.2.11/utils/redis-sha1.rb +52 -0
  289. data/redis/redis-2.2.11/utils/redis_init_script +42 -0
  290. metadata +362 -0
@@ -0,0 +1,64 @@
1
+ #ifndef __CONFIG_H
2
+ #define __CONFIG_H
3
+
4
+ #ifdef __APPLE__
5
+ #include <AvailabilityMacros.h>
6
+ #endif
7
+
8
+ /* Use tcmalloc's malloc_size() when available.
9
+ * When tcmalloc is used, native OSX malloc_size() may never be used because
10
+ * this expects a different allocation scheme. Therefore, *exclusively* use
11
+ * either tcmalloc or OSX's malloc_size()! */
12
+ #if defined(USE_TCMALLOC)
13
+ #include <google/tcmalloc.h>
14
+ #if TC_VERSION_MAJOR >= 1 && TC_VERSION_MINOR >= 6
15
+ #define HAVE_MALLOC_SIZE 1
16
+ #define redis_malloc_size(p) tc_malloc_size(p)
17
+ #endif
18
+ #elif defined(__APPLE__)
19
+ #include <malloc/malloc.h>
20
+ #define HAVE_MALLOC_SIZE 1
21
+ #define redis_malloc_size(p) malloc_size(p)
22
+ #endif
23
+
24
+ /* define redis_fstat to fstat or fstat64() */
25
+ #if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
26
+ #define redis_fstat fstat64
27
+ #define redis_stat stat64
28
+ #else
29
+ #define redis_fstat fstat
30
+ #define redis_stat stat
31
+ #endif
32
+
33
+ /* test for proc filesystem */
34
+ #ifdef __linux__
35
+ #define HAVE_PROCFS 1
36
+ #endif
37
+
38
+ /* test for task_info() */
39
+ #if defined(__APPLE__)
40
+ #define HAVE_TASKINFO 1
41
+ #endif
42
+
43
+ /* test for backtrace() */
44
+ #if defined(__APPLE__) || defined(__linux__)
45
+ #define HAVE_BACKTRACE 1
46
+ #endif
47
+
48
+ /* test for polling API */
49
+ #ifdef __linux__
50
+ #define HAVE_EPOLL 1
51
+ #endif
52
+
53
+ #if (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
54
+ #define HAVE_KQUEUE 1
55
+ #endif
56
+
57
+ /* define aof_fsync to fdatasync() in Linux and fsync() for all the rest */
58
+ #ifdef __linux__
59
+ #define aof_fsync fdatasync
60
+ #else
61
+ #define aof_fsync fsync
62
+ #endif
63
+
64
+ #endif
@@ -0,0 +1,543 @@
1
+ #include "redis.h"
2
+
3
+ #include <signal.h>
4
+
5
+ /*-----------------------------------------------------------------------------
6
+ * C-level DB API
7
+ *----------------------------------------------------------------------------*/
8
+
9
+ robj *lookupKey(redisDb *db, robj *key) {
10
+ dictEntry *de = dictFind(db->dict,key->ptr);
11
+ if (de) {
12
+ robj *val = dictGetEntryVal(de);
13
+
14
+ /* Update the access time for the aging algorithm.
15
+ * Don't do it if we have a saving child, as this will trigger
16
+ * a copy on write madness. */
17
+ if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1)
18
+ val->lru = server.lruclock;
19
+
20
+ if (server.vm_enabled) {
21
+ if (val->storage == REDIS_VM_MEMORY ||
22
+ val->storage == REDIS_VM_SWAPPING)
23
+ {
24
+ /* If we were swapping the object out, cancel the operation */
25
+ if (val->storage == REDIS_VM_SWAPPING)
26
+ vmCancelThreadedIOJob(val);
27
+ } else {
28
+ int notify = (val->storage == REDIS_VM_LOADING);
29
+
30
+ /* Our value was swapped on disk. Bring it at home. */
31
+ redisAssert(val->type == REDIS_VMPOINTER);
32
+ val = vmLoadObject(val);
33
+ dictGetEntryVal(de) = val;
34
+
35
+ /* Clients blocked by the VM subsystem may be waiting for
36
+ * this key... */
37
+ if (notify) handleClientsBlockedOnSwappedKey(db,key);
38
+ }
39
+ }
40
+ server.stat_keyspace_hits++;
41
+ return val;
42
+ } else {
43
+ server.stat_keyspace_misses++;
44
+ return NULL;
45
+ }
46
+ }
47
+
48
+ robj *lookupKeyRead(redisDb *db, robj *key) {
49
+ expireIfNeeded(db,key);
50
+ return lookupKey(db,key);
51
+ }
52
+
53
+ robj *lookupKeyWrite(redisDb *db, robj *key) {
54
+ expireIfNeeded(db,key);
55
+ return lookupKey(db,key);
56
+ }
57
+
58
+ robj *lookupKeyReadOrReply(redisClient *c, robj *key, robj *reply) {
59
+ robj *o = lookupKeyRead(c->db, key);
60
+ if (!o) addReply(c,reply);
61
+ return o;
62
+ }
63
+
64
+ robj *lookupKeyWriteOrReply(redisClient *c, robj *key, robj *reply) {
65
+ robj *o = lookupKeyWrite(c->db, key);
66
+ if (!o) addReply(c,reply);
67
+ return o;
68
+ }
69
+
70
+ /* Add the key to the DB. If the key already exists REDIS_ERR is returned,
71
+ * otherwise REDIS_OK is returned, and the caller should increment the
72
+ * refcount of 'val'. */
73
+ int dbAdd(redisDb *db, robj *key, robj *val) {
74
+ /* Perform a lookup before adding the key, as we need to copy the
75
+ * key value. */
76
+ if (dictFind(db->dict, key->ptr) != NULL) {
77
+ return REDIS_ERR;
78
+ } else {
79
+ sds copy = sdsdup(key->ptr);
80
+ dictAdd(db->dict, copy, val);
81
+ return REDIS_OK;
82
+ }
83
+ }
84
+
85
+ /* If the key does not exist, this is just like dbAdd(). Otherwise
86
+ * the value associated to the key is replaced with the new one.
87
+ *
88
+ * On update (key already existed) 0 is returned. Otherwise 1. */
89
+ int dbReplace(redisDb *db, robj *key, robj *val) {
90
+ if (dictFind(db->dict,key->ptr) == NULL) {
91
+ sds copy = sdsdup(key->ptr);
92
+ dictAdd(db->dict, copy, val);
93
+ return 1;
94
+ } else {
95
+ dictReplace(db->dict, key->ptr, val);
96
+ return 0;
97
+ }
98
+ }
99
+
100
+ int dbExists(redisDb *db, robj *key) {
101
+ return dictFind(db->dict,key->ptr) != NULL;
102
+ }
103
+
104
+ /* Return a random key, in form of a Redis object.
105
+ * If there are no keys, NULL is returned.
106
+ *
107
+ * The function makes sure to return keys not already expired. */
108
+ robj *dbRandomKey(redisDb *db) {
109
+ struct dictEntry *de;
110
+
111
+ while(1) {
112
+ sds key;
113
+ robj *keyobj;
114
+
115
+ de = dictGetRandomKey(db->dict);
116
+ if (de == NULL) return NULL;
117
+
118
+ key = dictGetEntryKey(de);
119
+ keyobj = createStringObject(key,sdslen(key));
120
+ if (dictFind(db->expires,key)) {
121
+ if (expireIfNeeded(db,keyobj)) {
122
+ decrRefCount(keyobj);
123
+ continue; /* search for another key. This expired. */
124
+ }
125
+ }
126
+ return keyobj;
127
+ }
128
+ }
129
+
130
+ /* Delete a key, value, and associated expiration entry if any, from the DB */
131
+ int dbDelete(redisDb *db, robj *key) {
132
+ /* If VM is enabled make sure to awake waiting clients for this key:
133
+ * deleting the key will kill the I/O thread bringing the key from swap
134
+ * to memory, so the client will never be notified and unblocked if we
135
+ * don't do it now. */
136
+ if (server.vm_enabled) handleClientsBlockedOnSwappedKey(db,key);
137
+ /* Deleting an entry from the expires dict will not free the sds of
138
+ * the key, because it is shared with the main dictionary. */
139
+ if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr);
140
+ return dictDelete(db->dict,key->ptr) == DICT_OK;
141
+ }
142
+
143
+ /* Empty the whole database */
144
+ long long emptyDb() {
145
+ int j;
146
+ long long removed = 0;
147
+
148
+ for (j = 0; j < server.dbnum; j++) {
149
+ removed += dictSize(server.db[j].dict);
150
+ dictEmpty(server.db[j].dict);
151
+ dictEmpty(server.db[j].expires);
152
+ }
153
+ return removed;
154
+ }
155
+
156
+ int selectDb(redisClient *c, int id) {
157
+ if (id < 0 || id >= server.dbnum)
158
+ return REDIS_ERR;
159
+ c->db = &server.db[id];
160
+ return REDIS_OK;
161
+ }
162
+
163
+ /*-----------------------------------------------------------------------------
164
+ * Type agnostic commands operating on the key space
165
+ *----------------------------------------------------------------------------*/
166
+
167
+ void flushdbCommand(redisClient *c) {
168
+ server.dirty += dictSize(c->db->dict);
169
+ touchWatchedKeysOnFlush(c->db->id);
170
+ dictEmpty(c->db->dict);
171
+ dictEmpty(c->db->expires);
172
+ addReply(c,shared.ok);
173
+ }
174
+
175
+ void flushallCommand(redisClient *c) {
176
+ touchWatchedKeysOnFlush(-1);
177
+ server.dirty += emptyDb();
178
+ addReply(c,shared.ok);
179
+ if (server.bgsavechildpid != -1) {
180
+ kill(server.bgsavechildpid,SIGKILL);
181
+ rdbRemoveTempFile(server.bgsavechildpid);
182
+ }
183
+ rdbSave(server.dbfilename);
184
+ server.dirty++;
185
+ }
186
+
187
+ void delCommand(redisClient *c) {
188
+ int deleted = 0, j;
189
+
190
+ for (j = 1; j < c->argc; j++) {
191
+ if (dbDelete(c->db,c->argv[j])) {
192
+ touchWatchedKey(c->db,c->argv[j]);
193
+ server.dirty++;
194
+ deleted++;
195
+ }
196
+ }
197
+ addReplyLongLong(c,deleted);
198
+ }
199
+
200
+ void existsCommand(redisClient *c) {
201
+ expireIfNeeded(c->db,c->argv[1]);
202
+ if (dbExists(c->db,c->argv[1])) {
203
+ addReply(c, shared.cone);
204
+ } else {
205
+ addReply(c, shared.czero);
206
+ }
207
+ }
208
+
209
+ void selectCommand(redisClient *c) {
210
+ int id = atoi(c->argv[1]->ptr);
211
+
212
+ if (selectDb(c,id) == REDIS_ERR) {
213
+ addReplyError(c,"invalid DB index");
214
+ } else {
215
+ addReply(c,shared.ok);
216
+ }
217
+ }
218
+
219
+ void randomkeyCommand(redisClient *c) {
220
+ robj *key;
221
+
222
+ if ((key = dbRandomKey(c->db)) == NULL) {
223
+ addReply(c,shared.nullbulk);
224
+ return;
225
+ }
226
+
227
+ addReplyBulk(c,key);
228
+ decrRefCount(key);
229
+ }
230
+
231
+ void keysCommand(redisClient *c) {
232
+ dictIterator *di;
233
+ dictEntry *de;
234
+ sds pattern = c->argv[1]->ptr;
235
+ int plen = sdslen(pattern), allkeys;
236
+ unsigned long numkeys = 0;
237
+ void *replylen = addDeferredMultiBulkLength(c);
238
+
239
+ di = dictGetIterator(c->db->dict);
240
+ allkeys = (pattern[0] == '*' && pattern[1] == '\0');
241
+ while((de = dictNext(di)) != NULL) {
242
+ sds key = dictGetEntryKey(de);
243
+ robj *keyobj;
244
+
245
+ if (allkeys || stringmatchlen(pattern,plen,key,sdslen(key),0)) {
246
+ keyobj = createStringObject(key,sdslen(key));
247
+ if (expireIfNeeded(c->db,keyobj) == 0) {
248
+ addReplyBulk(c,keyobj);
249
+ numkeys++;
250
+ }
251
+ decrRefCount(keyobj);
252
+ }
253
+ }
254
+ dictReleaseIterator(di);
255
+ setDeferredMultiBulkLength(c,replylen,numkeys);
256
+ }
257
+
258
+ void dbsizeCommand(redisClient *c) {
259
+ addReplyLongLong(c,dictSize(c->db->dict));
260
+ }
261
+
262
+ void lastsaveCommand(redisClient *c) {
263
+ addReplyLongLong(c,server.lastsave);
264
+ }
265
+
266
+ void typeCommand(redisClient *c) {
267
+ robj *o;
268
+ char *type;
269
+
270
+ o = lookupKeyRead(c->db,c->argv[1]);
271
+ if (o == NULL) {
272
+ type = "none";
273
+ } else {
274
+ switch(o->type) {
275
+ case REDIS_STRING: type = "string"; break;
276
+ case REDIS_LIST: type = "list"; break;
277
+ case REDIS_SET: type = "set"; break;
278
+ case REDIS_ZSET: type = "zset"; break;
279
+ case REDIS_HASH: type = "hash"; break;
280
+ default: type = "unknown"; break;
281
+ }
282
+ }
283
+ addReplyStatus(c,type);
284
+ }
285
+
286
+ void saveCommand(redisClient *c) {
287
+ if (server.bgsavechildpid != -1) {
288
+ addReplyError(c,"Background save already in progress");
289
+ return;
290
+ }
291
+ if (rdbSave(server.dbfilename) == REDIS_OK) {
292
+ addReply(c,shared.ok);
293
+ } else {
294
+ addReply(c,shared.err);
295
+ }
296
+ }
297
+
298
+ void bgsaveCommand(redisClient *c) {
299
+ if (server.bgsavechildpid != -1) {
300
+ addReplyError(c,"Background save already in progress");
301
+ return;
302
+ }
303
+ if (rdbSaveBackground(server.dbfilename) == REDIS_OK) {
304
+ addReplyStatus(c,"Background saving started");
305
+ } else {
306
+ addReply(c,shared.err);
307
+ }
308
+ }
309
+
310
+ void shutdownCommand(redisClient *c) {
311
+ if (prepareForShutdown() == REDIS_OK)
312
+ exit(0);
313
+ addReplyError(c,"Errors trying to SHUTDOWN. Check logs.");
314
+ }
315
+
316
+ void renameGenericCommand(redisClient *c, int nx) {
317
+ robj *o;
318
+
319
+ /* To use the same key as src and dst is probably an error */
320
+ if (sdscmp(c->argv[1]->ptr,c->argv[2]->ptr) == 0) {
321
+ addReply(c,shared.sameobjecterr);
322
+ return;
323
+ }
324
+
325
+ if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL)
326
+ return;
327
+
328
+ incrRefCount(o);
329
+ if (dbAdd(c->db,c->argv[2],o) == REDIS_ERR) {
330
+ if (nx) {
331
+ decrRefCount(o);
332
+ addReply(c,shared.czero);
333
+ return;
334
+ }
335
+ dbReplace(c->db,c->argv[2],o);
336
+ }
337
+ dbDelete(c->db,c->argv[1]);
338
+ touchWatchedKey(c->db,c->argv[1]);
339
+ touchWatchedKey(c->db,c->argv[2]);
340
+ server.dirty++;
341
+ addReply(c,nx ? shared.cone : shared.ok);
342
+ }
343
+
344
+ void renameCommand(redisClient *c) {
345
+ renameGenericCommand(c,0);
346
+ }
347
+
348
+ void renamenxCommand(redisClient *c) {
349
+ renameGenericCommand(c,1);
350
+ }
351
+
352
+ void moveCommand(redisClient *c) {
353
+ robj *o;
354
+ redisDb *src, *dst;
355
+ int srcid;
356
+
357
+ /* Obtain source and target DB pointers */
358
+ src = c->db;
359
+ srcid = c->db->id;
360
+ if (selectDb(c,atoi(c->argv[2]->ptr)) == REDIS_ERR) {
361
+ addReply(c,shared.outofrangeerr);
362
+ return;
363
+ }
364
+ dst = c->db;
365
+ selectDb(c,srcid); /* Back to the source DB */
366
+
367
+ /* If the user is moving using as target the same
368
+ * DB as the source DB it is probably an error. */
369
+ if (src == dst) {
370
+ addReply(c,shared.sameobjecterr);
371
+ return;
372
+ }
373
+
374
+ /* Check if the element exists and get a reference */
375
+ o = lookupKeyWrite(c->db,c->argv[1]);
376
+ if (!o) {
377
+ addReply(c,shared.czero);
378
+ return;
379
+ }
380
+
381
+ /* Try to add the element to the target DB */
382
+ if (dbAdd(dst,c->argv[1],o) == REDIS_ERR) {
383
+ addReply(c,shared.czero);
384
+ return;
385
+ }
386
+ incrRefCount(o);
387
+
388
+ /* OK! key moved, free the entry in the source DB */
389
+ dbDelete(src,c->argv[1]);
390
+ server.dirty++;
391
+ addReply(c,shared.cone);
392
+ }
393
+
394
+ /*-----------------------------------------------------------------------------
395
+ * Expires API
396
+ *----------------------------------------------------------------------------*/
397
+
398
+ int removeExpire(redisDb *db, robj *key) {
399
+ /* An expire may only be removed if there is a corresponding entry in the
400
+ * main dict. Otherwise, the key will never be freed. */
401
+ redisAssert(dictFind(db->dict,key->ptr) != NULL);
402
+ return dictDelete(db->expires,key->ptr) == DICT_OK;
403
+ }
404
+
405
+ void setExpire(redisDb *db, robj *key, time_t when) {
406
+ dictEntry *de;
407
+
408
+ /* Reuse the sds from the main dict in the expire dict */
409
+ de = dictFind(db->dict,key->ptr);
410
+ redisAssert(de != NULL);
411
+ dictReplace(db->expires,dictGetEntryKey(de),(void*)when);
412
+ }
413
+
414
+ /* Return the expire time of the specified key, or -1 if no expire
415
+ * is associated with this key (i.e. the key is non volatile) */
416
+ time_t getExpire(redisDb *db, robj *key) {
417
+ dictEntry *de;
418
+
419
+ /* No expire? return ASAP */
420
+ if (dictSize(db->expires) == 0 ||
421
+ (de = dictFind(db->expires,key->ptr)) == NULL) return -1;
422
+
423
+ /* The entry was found in the expire dict, this means it should also
424
+ * be present in the main dict (safety check). */
425
+ redisAssert(dictFind(db->dict,key->ptr) != NULL);
426
+ return (time_t) dictGetEntryVal(de);
427
+ }
428
+
429
+ /* Propagate expires into slaves and the AOF file.
430
+ * When a key expires in the master, a DEL operation for this key is sent
431
+ * to all the slaves and the AOF file if enabled.
432
+ *
433
+ * This way the key expiry is centralized in one place, and since both
434
+ * AOF and the master->slave link guarantee operation ordering, everything
435
+ * will be consistent even if we allow write operations against expiring
436
+ * keys. */
437
+ void propagateExpire(redisDb *db, robj *key) {
438
+ robj *argv[2];
439
+
440
+ argv[0] = createStringObject("DEL",3);
441
+ argv[1] = key;
442
+ incrRefCount(key);
443
+
444
+ if (server.appendonly)
445
+ feedAppendOnlyFile(server.delCommand,db->id,argv,2);
446
+ if (listLength(server.slaves))
447
+ replicationFeedSlaves(server.slaves,db->id,argv,2);
448
+
449
+ decrRefCount(argv[0]);
450
+ decrRefCount(argv[1]);
451
+ }
452
+
453
+ int expireIfNeeded(redisDb *db, robj *key) {
454
+ time_t when = getExpire(db,key);
455
+
456
+ if (when < 0) return 0; /* No expire for this key */
457
+
458
+ /* If we are running in the context of a slave, return ASAP:
459
+ * the slave key expiration is controlled by the master that will
460
+ * send us synthesized DEL operations for expired keys.
461
+ *
462
+ * Still we try to return the right information to the caller,
463
+ * that is, 0 if we think the key should be still valid, 1 if
464
+ * we think the key is expired at this time. */
465
+ if (server.masterhost != NULL) {
466
+ return time(NULL) > when;
467
+ }
468
+
469
+ /* Return when this key has not expired */
470
+ if (time(NULL) <= when) return 0;
471
+
472
+ /* Delete the key */
473
+ server.stat_expiredkeys++;
474
+ propagateExpire(db,key);
475
+ return dbDelete(db,key);
476
+ }
477
+
478
+ /*-----------------------------------------------------------------------------
479
+ * Expires Commands
480
+ *----------------------------------------------------------------------------*/
481
+
482
+ void expireGenericCommand(redisClient *c, robj *key, robj *param, long offset) {
483
+ dictEntry *de;
484
+ long seconds;
485
+
486
+ if (getLongFromObjectOrReply(c, param, &seconds, NULL) != REDIS_OK) return;
487
+
488
+ seconds -= offset;
489
+
490
+ de = dictFind(c->db->dict,key->ptr);
491
+ if (de == NULL) {
492
+ addReply(c,shared.czero);
493
+ return;
494
+ }
495
+ if (seconds <= 0) {
496
+ if (dbDelete(c->db,key)) server.dirty++;
497
+ addReply(c, shared.cone);
498
+ touchWatchedKey(c->db,key);
499
+ return;
500
+ } else {
501
+ time_t when = time(NULL)+seconds;
502
+ setExpire(c->db,key,when);
503
+ addReply(c,shared.cone);
504
+ touchWatchedKey(c->db,key);
505
+ server.dirty++;
506
+ return;
507
+ }
508
+ }
509
+
510
+ void expireCommand(redisClient *c) {
511
+ expireGenericCommand(c,c->argv[1],c->argv[2],0);
512
+ }
513
+
514
+ void expireatCommand(redisClient *c) {
515
+ expireGenericCommand(c,c->argv[1],c->argv[2],time(NULL));
516
+ }
517
+
518
+ void ttlCommand(redisClient *c) {
519
+ time_t expire, ttl = -1;
520
+
521
+ expire = getExpire(c->db,c->argv[1]);
522
+ if (expire != -1) {
523
+ ttl = (expire-time(NULL));
524
+ if (ttl < 0) ttl = -1;
525
+ }
526
+ addReplyLongLong(c,(long long)ttl);
527
+ }
528
+
529
+ void persistCommand(redisClient *c) {
530
+ dictEntry *de;
531
+
532
+ de = dictFind(c->db->dict,c->argv[1]->ptr);
533
+ if (de == NULL) {
534
+ addReply(c,shared.czero);
535
+ } else {
536
+ if (removeExpire(c->db,c->argv[1])) {
537
+ addReply(c,shared.cone);
538
+ server.dirty++;
539
+ } else {
540
+ addReply(c,shared.czero);
541
+ }
542
+ }
543
+ }