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,484 @@
1
+ #include "redis.h"
2
+ #include <pthread.h>
3
+ #include <math.h>
4
+
5
+ robj *createObject(int type, void *ptr) {
6
+ robj *o = zmalloc(sizeof(*o));
7
+ o->type = type;
8
+ o->encoding = REDIS_ENCODING_RAW;
9
+ o->ptr = ptr;
10
+ o->refcount = 1;
11
+
12
+ /* Set the LRU to the current lruclock (minutes resolution).
13
+ * We do this regardless of the fact VM is active as LRU is also
14
+ * used for the maxmemory directive when Redis is used as cache.
15
+ *
16
+ * Note that this code may run in the context of an I/O thread
17
+ * and accessing server.lruclock in theory is an error
18
+ * (no locks). But in practice this is safe, and even if we read
19
+ * garbage Redis will not fail. */
20
+ o->lru = server.lruclock;
21
+ /* The following is only needed if VM is active, but since the conditional
22
+ * is probably more costly than initializing the field it's better to
23
+ * have every field properly initialized anyway. */
24
+ o->storage = REDIS_VM_MEMORY;
25
+ return o;
26
+ }
27
+
28
+ robj *createStringObject(char *ptr, size_t len) {
29
+ return createObject(REDIS_STRING,sdsnewlen(ptr,len));
30
+ }
31
+
32
+ robj *createStringObjectFromLongLong(long long value) {
33
+ robj *o;
34
+ if (value >= 0 && value < REDIS_SHARED_INTEGERS &&
35
+ pthread_equal(pthread_self(),server.mainthread)) {
36
+ incrRefCount(shared.integers[value]);
37
+ o = shared.integers[value];
38
+ } else {
39
+ if (value >= LONG_MIN && value <= LONG_MAX) {
40
+ o = createObject(REDIS_STRING, NULL);
41
+ o->encoding = REDIS_ENCODING_INT;
42
+ o->ptr = (void*)((long)value);
43
+ } else {
44
+ o = createObject(REDIS_STRING,sdsfromlonglong(value));
45
+ }
46
+ }
47
+ return o;
48
+ }
49
+
50
+ robj *dupStringObject(robj *o) {
51
+ redisAssert(o->encoding == REDIS_ENCODING_RAW);
52
+ return createStringObject(o->ptr,sdslen(o->ptr));
53
+ }
54
+
55
+ robj *createListObject(void) {
56
+ list *l = listCreate();
57
+ robj *o = createObject(REDIS_LIST,l);
58
+ listSetFreeMethod(l,decrRefCount);
59
+ o->encoding = REDIS_ENCODING_LINKEDLIST;
60
+ return o;
61
+ }
62
+
63
+ robj *createZiplistObject(void) {
64
+ unsigned char *zl = ziplistNew();
65
+ robj *o = createObject(REDIS_LIST,zl);
66
+ o->encoding = REDIS_ENCODING_ZIPLIST;
67
+ return o;
68
+ }
69
+
70
+ robj *createSetObject(void) {
71
+ dict *d = dictCreate(&setDictType,NULL);
72
+ robj *o = createObject(REDIS_SET,d);
73
+ o->encoding = REDIS_ENCODING_HT;
74
+ return o;
75
+ }
76
+
77
+ robj *createIntsetObject(void) {
78
+ intset *is = intsetNew();
79
+ robj *o = createObject(REDIS_SET,is);
80
+ o->encoding = REDIS_ENCODING_INTSET;
81
+ return o;
82
+ }
83
+
84
+ robj *createHashObject(void) {
85
+ /* All the Hashes start as zipmaps. Will be automatically converted
86
+ * into hash tables if there are enough elements or big elements
87
+ * inside. */
88
+ unsigned char *zm = zipmapNew();
89
+ robj *o = createObject(REDIS_HASH,zm);
90
+ o->encoding = REDIS_ENCODING_ZIPMAP;
91
+ return o;
92
+ }
93
+
94
+ robj *createZsetObject(void) {
95
+ zset *zs = zmalloc(sizeof(*zs));
96
+ robj *o;
97
+
98
+ zs->dict = dictCreate(&zsetDictType,NULL);
99
+ zs->zsl = zslCreate();
100
+ o = createObject(REDIS_ZSET,zs);
101
+ o->encoding = REDIS_ENCODING_SKIPLIST;
102
+ return o;
103
+ }
104
+
105
+ void freeStringObject(robj *o) {
106
+ if (o->encoding == REDIS_ENCODING_RAW) {
107
+ sdsfree(o->ptr);
108
+ }
109
+ }
110
+
111
+ void freeListObject(robj *o) {
112
+ switch (o->encoding) {
113
+ case REDIS_ENCODING_LINKEDLIST:
114
+ listRelease((list*) o->ptr);
115
+ break;
116
+ case REDIS_ENCODING_ZIPLIST:
117
+ zfree(o->ptr);
118
+ break;
119
+ default:
120
+ redisPanic("Unknown list encoding type");
121
+ }
122
+ }
123
+
124
+ void freeSetObject(robj *o) {
125
+ switch (o->encoding) {
126
+ case REDIS_ENCODING_HT:
127
+ dictRelease((dict*) o->ptr);
128
+ break;
129
+ case REDIS_ENCODING_INTSET:
130
+ zfree(o->ptr);
131
+ break;
132
+ default:
133
+ redisPanic("Unknown set encoding type");
134
+ }
135
+ }
136
+
137
+ void freeZsetObject(robj *o) {
138
+ zset *zs = o->ptr;
139
+
140
+ dictRelease(zs->dict);
141
+ zslFree(zs->zsl);
142
+ zfree(zs);
143
+ }
144
+
145
+ void freeHashObject(robj *o) {
146
+ switch (o->encoding) {
147
+ case REDIS_ENCODING_HT:
148
+ dictRelease((dict*) o->ptr);
149
+ break;
150
+ case REDIS_ENCODING_ZIPMAP:
151
+ zfree(o->ptr);
152
+ break;
153
+ default:
154
+ redisPanic("Unknown hash encoding type");
155
+ break;
156
+ }
157
+ }
158
+
159
+ void incrRefCount(robj *o) {
160
+ o->refcount++;
161
+ }
162
+
163
+ void decrRefCount(void *obj) {
164
+ robj *o = obj;
165
+
166
+ /* Object is a swapped out value, or in the process of being loaded. */
167
+ if (server.vm_enabled &&
168
+ (o->storage == REDIS_VM_SWAPPED || o->storage == REDIS_VM_LOADING))
169
+ {
170
+ vmpointer *vp = obj;
171
+ if (o->storage == REDIS_VM_LOADING) vmCancelThreadedIOJob(o);
172
+ vmMarkPagesFree(vp->page,vp->usedpages);
173
+ server.vm_stats_swapped_objects--;
174
+ zfree(vp);
175
+ return;
176
+ }
177
+
178
+ if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0");
179
+ /* Object is in memory, or in the process of being swapped out.
180
+ *
181
+ * If the object is being swapped out, abort the operation on
182
+ * decrRefCount even if the refcount does not drop to 0: the object
183
+ * is referenced at least two times, as value of the key AND as
184
+ * job->val in the iojob. So if we don't invalidate the iojob, when it is
185
+ * done but the relevant key was removed in the meantime, the
186
+ * complete jobs handler will not find the key about the job and the
187
+ * assert will fail. */
188
+ if (server.vm_enabled && o->storage == REDIS_VM_SWAPPING)
189
+ vmCancelThreadedIOJob(o);
190
+ if (--(o->refcount) == 0) {
191
+ switch(o->type) {
192
+ case REDIS_STRING: freeStringObject(o); break;
193
+ case REDIS_LIST: freeListObject(o); break;
194
+ case REDIS_SET: freeSetObject(o); break;
195
+ case REDIS_ZSET: freeZsetObject(o); break;
196
+ case REDIS_HASH: freeHashObject(o); break;
197
+ default: redisPanic("Unknown object type"); break;
198
+ }
199
+ o->ptr = NULL; /* defensive programming. We'll see NULL in traces. */
200
+ zfree(o);
201
+ }
202
+ }
203
+
204
+ int checkType(redisClient *c, robj *o, int type) {
205
+ if (o->type != type) {
206
+ addReply(c,shared.wrongtypeerr);
207
+ return 1;
208
+ }
209
+ return 0;
210
+ }
211
+
212
+ /* Try to encode a string object in order to save space */
213
+ robj *tryObjectEncoding(robj *o) {
214
+ long value;
215
+ sds s = o->ptr;
216
+
217
+ if (o->encoding != REDIS_ENCODING_RAW)
218
+ return o; /* Already encoded */
219
+
220
+ /* It's not safe to encode shared objects: shared objects can be shared
221
+ * everywhere in the "object space" of Redis. Encoded objects can only
222
+ * appear as "values" (and not, for instance, as keys) */
223
+ if (o->refcount > 1) return o;
224
+
225
+ /* Currently we try to encode only strings */
226
+ redisAssert(o->type == REDIS_STRING);
227
+
228
+ /* Check if we can represent this string as a long integer */
229
+ if (isStringRepresentableAsLong(s,&value) == REDIS_ERR) return o;
230
+
231
+ /* Ok, this object can be encoded...
232
+ *
233
+ * Can I use a shared object? Only if the object is inside a given
234
+ * range and if this is the main thread, since when VM is enabled we
235
+ * have the constraint that I/O thread should only handle non-shared
236
+ * objects, in order to avoid race conditions (we don't have per-object
237
+ * locking).
238
+ *
239
+ * Note that we also avoid using shared integers when maxmemory is used
240
+ * because very object needs to have a private LRU field for the LRU
241
+ * algorithm to work well. */
242
+ if (server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS &&
243
+ pthread_equal(pthread_self(),server.mainthread)) {
244
+ decrRefCount(o);
245
+ incrRefCount(shared.integers[value]);
246
+ return shared.integers[value];
247
+ } else {
248
+ o->encoding = REDIS_ENCODING_INT;
249
+ sdsfree(o->ptr);
250
+ o->ptr = (void*) value;
251
+ return o;
252
+ }
253
+ }
254
+
255
+ /* Get a decoded version of an encoded object (returned as a new object).
256
+ * If the object is already raw-encoded just increment the ref count. */
257
+ robj *getDecodedObject(robj *o) {
258
+ robj *dec;
259
+
260
+ if (o->encoding == REDIS_ENCODING_RAW) {
261
+ incrRefCount(o);
262
+ return o;
263
+ }
264
+ if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) {
265
+ char buf[32];
266
+
267
+ ll2string(buf,32,(long)o->ptr);
268
+ dec = createStringObject(buf,strlen(buf));
269
+ return dec;
270
+ } else {
271
+ redisPanic("Unknown encoding type");
272
+ }
273
+ }
274
+
275
+ /* Compare two string objects via strcmp() or alike.
276
+ * Note that the objects may be integer-encoded. In such a case we
277
+ * use ll2string() to get a string representation of the numbers on the stack
278
+ * and compare the strings, it's much faster than calling getDecodedObject().
279
+ *
280
+ * Important note: if objects are not integer encoded, but binary-safe strings,
281
+ * sdscmp() from sds.c will apply memcmp() so this function ca be considered
282
+ * binary safe. */
283
+ int compareStringObjects(robj *a, robj *b) {
284
+ redisAssert(a->type == REDIS_STRING && b->type == REDIS_STRING);
285
+ char bufa[128], bufb[128], *astr, *bstr;
286
+ int bothsds = 1;
287
+
288
+ if (a == b) return 0;
289
+ if (a->encoding != REDIS_ENCODING_RAW) {
290
+ ll2string(bufa,sizeof(bufa),(long) a->ptr);
291
+ astr = bufa;
292
+ bothsds = 0;
293
+ } else {
294
+ astr = a->ptr;
295
+ }
296
+ if (b->encoding != REDIS_ENCODING_RAW) {
297
+ ll2string(bufb,sizeof(bufb),(long) b->ptr);
298
+ bstr = bufb;
299
+ bothsds = 0;
300
+ } else {
301
+ bstr = b->ptr;
302
+ }
303
+ return bothsds ? sdscmp(astr,bstr) : strcmp(astr,bstr);
304
+ }
305
+
306
+ /* Equal string objects return 1 if the two objects are the same from the
307
+ * point of view of a string comparison, otherwise 0 is returned. Note that
308
+ * this function is faster then checking for (compareStringObject(a,b) == 0)
309
+ * because it can perform some more optimization. */
310
+ int equalStringObjects(robj *a, robj *b) {
311
+ if (a->encoding != REDIS_ENCODING_RAW && b->encoding != REDIS_ENCODING_RAW){
312
+ return a->ptr == b->ptr;
313
+ } else {
314
+ return compareStringObjects(a,b) == 0;
315
+ }
316
+ }
317
+
318
+ size_t stringObjectLen(robj *o) {
319
+ redisAssert(o->type == REDIS_STRING);
320
+ if (o->encoding == REDIS_ENCODING_RAW) {
321
+ return sdslen(o->ptr);
322
+ } else {
323
+ char buf[32];
324
+
325
+ return ll2string(buf,32,(long)o->ptr);
326
+ }
327
+ }
328
+
329
+ int getDoubleFromObject(robj *o, double *target) {
330
+ double value;
331
+ char *eptr;
332
+
333
+ if (o == NULL) {
334
+ value = 0;
335
+ } else {
336
+ redisAssert(o->type == REDIS_STRING);
337
+ if (o->encoding == REDIS_ENCODING_RAW) {
338
+ value = strtod(o->ptr, &eptr);
339
+ if (eptr[0] != '\0' || isnan(value)) return REDIS_ERR;
340
+ } else if (o->encoding == REDIS_ENCODING_INT) {
341
+ value = (long)o->ptr;
342
+ } else {
343
+ redisPanic("Unknown string encoding");
344
+ }
345
+ }
346
+
347
+ *target = value;
348
+ return REDIS_OK;
349
+ }
350
+
351
+ int getDoubleFromObjectOrReply(redisClient *c, robj *o, double *target, const char *msg) {
352
+ double value;
353
+ if (getDoubleFromObject(o, &value) != REDIS_OK) {
354
+ if (msg != NULL) {
355
+ addReplyError(c,(char*)msg);
356
+ } else {
357
+ addReplyError(c,"value is not a double");
358
+ }
359
+ return REDIS_ERR;
360
+ }
361
+
362
+ *target = value;
363
+ return REDIS_OK;
364
+ }
365
+
366
+ int getLongLongFromObject(robj *o, long long *target) {
367
+ long long value;
368
+ char *eptr;
369
+
370
+ if (o == NULL) {
371
+ value = 0;
372
+ } else {
373
+ redisAssert(o->type == REDIS_STRING);
374
+ if (o->encoding == REDIS_ENCODING_RAW) {
375
+ value = strtoll(o->ptr, &eptr, 10);
376
+ if (eptr[0] != '\0') return REDIS_ERR;
377
+ if (errno == ERANGE && (value == LLONG_MIN || value == LLONG_MAX))
378
+ return REDIS_ERR;
379
+ } else if (o->encoding == REDIS_ENCODING_INT) {
380
+ value = (long)o->ptr;
381
+ } else {
382
+ redisPanic("Unknown string encoding");
383
+ }
384
+ }
385
+
386
+ if (target) *target = value;
387
+ return REDIS_OK;
388
+ }
389
+
390
+ int getLongLongFromObjectOrReply(redisClient *c, robj *o, long long *target, const char *msg) {
391
+ long long value;
392
+ if (getLongLongFromObject(o, &value) != REDIS_OK) {
393
+ if (msg != NULL) {
394
+ addReplyError(c,(char*)msg);
395
+ } else {
396
+ addReplyError(c,"value is not an integer or out of range");
397
+ }
398
+ return REDIS_ERR;
399
+ }
400
+
401
+ *target = value;
402
+ return REDIS_OK;
403
+ }
404
+
405
+ int getLongFromObjectOrReply(redisClient *c, robj *o, long *target, const char *msg) {
406
+ long long value;
407
+
408
+ if (getLongLongFromObjectOrReply(c, o, &value, msg) != REDIS_OK) return REDIS_ERR;
409
+ if (value < LONG_MIN || value > LONG_MAX) {
410
+ if (msg != NULL) {
411
+ addReplyError(c,(char*)msg);
412
+ } else {
413
+ addReplyError(c,"value is out of range");
414
+ }
415
+ return REDIS_ERR;
416
+ }
417
+
418
+ *target = value;
419
+ return REDIS_OK;
420
+ }
421
+
422
+ char *strEncoding(int encoding) {
423
+ switch(encoding) {
424
+ case REDIS_ENCODING_RAW: return "raw";
425
+ case REDIS_ENCODING_INT: return "int";
426
+ case REDIS_ENCODING_HT: return "hashtable";
427
+ case REDIS_ENCODING_ZIPMAP: return "zipmap";
428
+ case REDIS_ENCODING_LINKEDLIST: return "linkedlist";
429
+ case REDIS_ENCODING_ZIPLIST: return "ziplist";
430
+ case REDIS_ENCODING_INTSET: return "intset";
431
+ case REDIS_ENCODING_SKIPLIST: return "skiplist";
432
+ default: return "unknown";
433
+ }
434
+ }
435
+
436
+ /* Given an object returns the min number of seconds the object was never
437
+ * requested, using an approximated LRU algorithm. */
438
+ unsigned long estimateObjectIdleTime(robj *o) {
439
+ if (server.lruclock >= o->lru) {
440
+ return (server.lruclock - o->lru) * REDIS_LRU_CLOCK_RESOLUTION;
441
+ } else {
442
+ return ((REDIS_LRU_CLOCK_MAX - o->lru) + server.lruclock) *
443
+ REDIS_LRU_CLOCK_RESOLUTION;
444
+ }
445
+ }
446
+
447
+ /* This is an helper function for the DEBUG command. We need to lookup keys
448
+ * without any modification of LRU or other parameters. */
449
+ robj *objectCommandLookup(redisClient *c, robj *key) {
450
+ dictEntry *de;
451
+
452
+ if ((de = dictFind(c->db->dict,key->ptr)) == NULL) return NULL;
453
+ return (robj*) dictGetEntryVal(de);
454
+ }
455
+
456
+ robj *objectCommandLookupOrReply(redisClient *c, robj *key, robj *reply) {
457
+ robj *o = objectCommandLookup(c,key);
458
+
459
+ if (!o) addReply(c, reply);
460
+ return o;
461
+ }
462
+
463
+ /* Object command allows to inspect the internals of an Redis Object.
464
+ * Usage: OBJECT <verb> ... arguments ... */
465
+ void objectCommand(redisClient *c) {
466
+ robj *o;
467
+
468
+ if (!strcasecmp(c->argv[1]->ptr,"refcount") && c->argc == 3) {
469
+ if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
470
+ == NULL) return;
471
+ addReplyLongLong(c,o->refcount);
472
+ } else if (!strcasecmp(c->argv[1]->ptr,"encoding") && c->argc == 3) {
473
+ if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
474
+ == NULL) return;
475
+ addReplyBulkCString(c,strEncoding(o->encoding));
476
+ } else if (!strcasecmp(c->argv[1]->ptr,"idletime") && c->argc == 3) {
477
+ if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
478
+ == NULL) return;
479
+ addReplyLongLong(c,estimateObjectIdleTime(o));
480
+ } else {
481
+ addReplyError(c,"Syntax error. Try OBJECT (refcount|encoding|idletime)");
482
+ }
483
+ }
484
+