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,15 @@
1
+ #define ZIPLIST_HEAD 0
2
+ #define ZIPLIST_TAIL 1
3
+
4
+ unsigned char *ziplistNew(void);
5
+ unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where);
6
+ unsigned char *ziplistIndex(unsigned char *zl, int index);
7
+ unsigned char *ziplistNext(unsigned char *zl, unsigned char *p);
8
+ unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p);
9
+ unsigned int ziplistGet(unsigned char *p, unsigned char **sval, unsigned int *slen, long long *lval);
10
+ unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen);
11
+ unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p);
12
+ unsigned char *ziplistDeleteRange(unsigned char *zl, unsigned int index, unsigned int num);
13
+ unsigned int ziplistCompare(unsigned char *p, unsigned char *s, unsigned int slen);
14
+ unsigned int ziplistLen(unsigned char *zl);
15
+ unsigned int ziplistSize(unsigned char *zl);
@@ -0,0 +1,455 @@
1
+ /* String -> String Map data structure optimized for size.
2
+ * This file implements a data structure mapping strings to other strings
3
+ * implementing an O(n) lookup data structure designed to be very memory
4
+ * efficient.
5
+ *
6
+ * The Redis Hash type uses this data structure for hashes composed of a small
7
+ * number of elements, to switch to an hash table once a given number of
8
+ * elements is reached.
9
+ *
10
+ * Given that many times Redis Hashes are used to represent objects composed
11
+ * of few fields, this is a very big win in terms of used memory.
12
+ *
13
+ * --------------------------------------------------------------------------
14
+ *
15
+ * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
16
+ * All rights reserved.
17
+ *
18
+ * Redistribution and use in source and binary forms, with or without
19
+ * modification, are permitted provided that the following conditions are met:
20
+ *
21
+ * * Redistributions of source code must retain the above copyright notice,
22
+ * this list of conditions and the following disclaimer.
23
+ * * Redistributions in binary form must reproduce the above copyright
24
+ * notice, this list of conditions and the following disclaimer in the
25
+ * documentation and/or other materials provided with the distribution.
26
+ * * Neither the name of Redis nor the names of its contributors may be used
27
+ * to endorse or promote products derived from this software without
28
+ * specific prior written permission.
29
+ *
30
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40
+ * POSSIBILITY OF SUCH DAMAGE.
41
+ */
42
+
43
+ /* Memory layout of a zipmap, for the map "foo" => "bar", "hello" => "world":
44
+ *
45
+ * <zmlen><len>"foo"<len><free>"bar"<len>"hello"<len><free>"world"
46
+ *
47
+ * <zmlen> is 1 byte length that holds the current size of the zipmap.
48
+ * When the zipmap length is greater than or equal to 254, this value
49
+ * is not used and the zipmap needs to be traversed to find out the length.
50
+ *
51
+ * <len> is the length of the following string (key or value).
52
+ * <len> lengths are encoded in a single value or in a 5 bytes value.
53
+ * If the first byte value (as an unsigned 8 bit value) is between 0 and
54
+ * 252, it's a single-byte length. If it is 253 then a four bytes unsigned
55
+ * integer follows (in the host byte ordering). A value fo 255 is used to
56
+ * signal the end of the hash. The special value 254 is used to mark
57
+ * empty space that can be used to add new key/value pairs.
58
+ *
59
+ * <free> is the number of free unused bytes
60
+ * after the string, resulting from modification of values associated to a
61
+ * key (for instance if "foo" is set to "bar', and later "foo" will be se to
62
+ * "hi", I'll have a free byte to use if the value will enlarge again later,
63
+ * or even in order to add a key/value pair if it fits.
64
+ *
65
+ * <free> is always an unsigned 8 bit number, because if after an
66
+ * update operation there are more than a few free bytes, the zipmap will be
67
+ * reallocated to make sure it is as small as possible.
68
+ *
69
+ * The most compact representation of the above two elements hash is actually:
70
+ *
71
+ * "\x02\x03foo\x03\x00bar\x05hello\x05\x00world\xff"
72
+ *
73
+ * Note that because keys and values are prefixed length "objects",
74
+ * the lookup will take O(N) where N is the number of elements
75
+ * in the zipmap and *not* the number of bytes needed to represent the zipmap.
76
+ * This lowers the constant times considerably.
77
+ */
78
+
79
+ #include <stdio.h>
80
+ #include <string.h>
81
+ #include <assert.h>
82
+ #include "zmalloc.h"
83
+
84
+ #define ZIPMAP_BIGLEN 254
85
+ #define ZIPMAP_END 255
86
+
87
+ /* The following defines the max value for the <free> field described in the
88
+ * comments above, that is, the max number of trailing bytes in a value. */
89
+ #define ZIPMAP_VALUE_MAX_FREE 4
90
+
91
+ /* The following macro returns the number of bytes needed to encode the length
92
+ * for the integer value _l, that is, 1 byte for lengths < ZIPMAP_BIGLEN and
93
+ * 5 bytes for all the other lengths. */
94
+ #define ZIPMAP_LEN_BYTES(_l) (((_l) < ZIPMAP_BIGLEN) ? 1 : sizeof(unsigned int)+1)
95
+
96
+ /* Create a new empty zipmap. */
97
+ unsigned char *zipmapNew(void) {
98
+ unsigned char *zm = zmalloc(2);
99
+
100
+ zm[0] = 0; /* Length */
101
+ zm[1] = ZIPMAP_END;
102
+ return zm;
103
+ }
104
+
105
+ /* Decode the encoded length pointed by 'p' */
106
+ static unsigned int zipmapDecodeLength(unsigned char *p) {
107
+ unsigned int len = *p;
108
+
109
+ if (len < ZIPMAP_BIGLEN) return len;
110
+ memcpy(&len,p+1,sizeof(unsigned int));
111
+ return len;
112
+ }
113
+
114
+ /* Encode the length 'l' writing it in 'p'. If p is NULL it just returns
115
+ * the amount of bytes required to encode such a length. */
116
+ static unsigned int zipmapEncodeLength(unsigned char *p, unsigned int len) {
117
+ if (p == NULL) {
118
+ return ZIPMAP_LEN_BYTES(len);
119
+ } else {
120
+ if (len < ZIPMAP_BIGLEN) {
121
+ p[0] = len;
122
+ return 1;
123
+ } else {
124
+ p[0] = ZIPMAP_BIGLEN;
125
+ memcpy(p+1,&len,sizeof(len));
126
+ return 1+sizeof(len);
127
+ }
128
+ }
129
+ }
130
+
131
+ /* Search for a matching key, returning a pointer to the entry inside the
132
+ * zipmap. Returns NULL if the key is not found.
133
+ *
134
+ * If NULL is returned, and totlen is not NULL, it is set to the entire
135
+ * size of the zimap, so that the calling function will be able to
136
+ * reallocate the original zipmap to make room for more entries. */
137
+ static unsigned char *zipmapLookupRaw(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned int *totlen) {
138
+ unsigned char *p = zm+1, *k = NULL;
139
+ unsigned int l,llen;
140
+
141
+ while(*p != ZIPMAP_END) {
142
+ unsigned char free;
143
+
144
+ /* Match or skip the key */
145
+ l = zipmapDecodeLength(p);
146
+ llen = zipmapEncodeLength(NULL,l);
147
+ if (k == NULL && l == klen && !memcmp(p+llen,key,l)) {
148
+ /* Only return when the user doesn't care
149
+ * for the total length of the zipmap. */
150
+ if (totlen != NULL) {
151
+ k = p;
152
+ } else {
153
+ return p;
154
+ }
155
+ }
156
+ p += llen+l;
157
+ /* Skip the value as well */
158
+ l = zipmapDecodeLength(p);
159
+ p += zipmapEncodeLength(NULL,l);
160
+ free = p[0];
161
+ p += l+1+free; /* +1 to skip the free byte */
162
+ }
163
+ if (totlen != NULL) *totlen = (unsigned int)(p-zm)+1;
164
+ return k;
165
+ }
166
+
167
+ static unsigned long zipmapRequiredLength(unsigned int klen, unsigned int vlen) {
168
+ unsigned int l;
169
+
170
+ l = klen+vlen+3;
171
+ if (klen >= ZIPMAP_BIGLEN) l += 4;
172
+ if (vlen >= ZIPMAP_BIGLEN) l += 4;
173
+ return l;
174
+ }
175
+
176
+ /* Return the total amount used by a key (encoded length + payload) */
177
+ static unsigned int zipmapRawKeyLength(unsigned char *p) {
178
+ unsigned int l = zipmapDecodeLength(p);
179
+ return zipmapEncodeLength(NULL,l) + l;
180
+ }
181
+
182
+ /* Return the total amount used by a value
183
+ * (encoded length + single byte free count + payload) */
184
+ static unsigned int zipmapRawValueLength(unsigned char *p) {
185
+ unsigned int l = zipmapDecodeLength(p);
186
+ unsigned int used;
187
+
188
+ used = zipmapEncodeLength(NULL,l);
189
+ used += p[used] + 1 + l;
190
+ return used;
191
+ }
192
+
193
+ /* If 'p' points to a key, this function returns the total amount of
194
+ * bytes used to store this entry (entry = key + associated value + trailing
195
+ * free space if any). */
196
+ static unsigned int zipmapRawEntryLength(unsigned char *p) {
197
+ unsigned int l = zipmapRawKeyLength(p);
198
+ return l + zipmapRawValueLength(p+l);
199
+ }
200
+
201
+ static inline unsigned char *zipmapResize(unsigned char *zm, unsigned int len) {
202
+ zm = zrealloc(zm, len);
203
+ zm[len-1] = ZIPMAP_END;
204
+ return zm;
205
+ }
206
+
207
+ /* Set key to value, creating the key if it does not already exist.
208
+ * If 'update' is not NULL, *update is set to 1 if the key was
209
+ * already preset, otherwise to 0. */
210
+ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update) {
211
+ unsigned int zmlen, offset;
212
+ unsigned int freelen, reqlen = zipmapRequiredLength(klen,vlen);
213
+ unsigned int empty, vempty;
214
+ unsigned char *p;
215
+
216
+ freelen = reqlen;
217
+ if (update) *update = 0;
218
+ p = zipmapLookupRaw(zm,key,klen,&zmlen);
219
+ if (p == NULL) {
220
+ /* Key not found: enlarge */
221
+ zm = zipmapResize(zm, zmlen+reqlen);
222
+ p = zm+zmlen-1;
223
+ zmlen = zmlen+reqlen;
224
+
225
+ /* Increase zipmap length (this is an insert) */
226
+ if (zm[0] < ZIPMAP_BIGLEN) zm[0]++;
227
+ } else {
228
+ /* Key found. Is there enough space for the new value? */
229
+ /* Compute the total length: */
230
+ if (update) *update = 1;
231
+ freelen = zipmapRawEntryLength(p);
232
+ if (freelen < reqlen) {
233
+ /* Store the offset of this key within the current zipmap, so
234
+ * it can be resized. Then, move the tail backwards so this
235
+ * pair fits at the current position. */
236
+ offset = p-zm;
237
+ zm = zipmapResize(zm, zmlen-freelen+reqlen);
238
+ p = zm+offset;
239
+
240
+ /* The +1 in the number of bytes to be moved is caused by the
241
+ * end-of-zipmap byte. Note: the *original* zmlen is used. */
242
+ memmove(p+reqlen, p+freelen, zmlen-(offset+freelen+1));
243
+ zmlen = zmlen-freelen+reqlen;
244
+ freelen = reqlen;
245
+ }
246
+ }
247
+
248
+ /* We now have a suitable block where the key/value entry can
249
+ * be written. If there is too much free space, move the tail
250
+ * of the zipmap a few bytes to the front and shrink the zipmap,
251
+ * as we want zipmaps to be very space efficient. */
252
+ empty = freelen-reqlen;
253
+ if (empty >= ZIPMAP_VALUE_MAX_FREE) {
254
+ /* First, move the tail <empty> bytes to the front, then resize
255
+ * the zipmap to be <empty> bytes smaller. */
256
+ offset = p-zm;
257
+ memmove(p+reqlen, p+freelen, zmlen-(offset+freelen+1));
258
+ zmlen -= empty;
259
+ zm = zipmapResize(zm, zmlen);
260
+ p = zm+offset;
261
+ vempty = 0;
262
+ } else {
263
+ vempty = empty;
264
+ }
265
+
266
+ /* Just write the key + value and we are done. */
267
+ /* Key: */
268
+ p += zipmapEncodeLength(p,klen);
269
+ memcpy(p,key,klen);
270
+ p += klen;
271
+ /* Value: */
272
+ p += zipmapEncodeLength(p,vlen);
273
+ *p++ = vempty;
274
+ memcpy(p,val,vlen);
275
+ return zm;
276
+ }
277
+
278
+ /* Remove the specified key. If 'deleted' is not NULL the pointed integer is
279
+ * set to 0 if the key was not found, to 1 if it was found and deleted. */
280
+ unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int klen, int *deleted) {
281
+ unsigned int zmlen, freelen;
282
+ unsigned char *p = zipmapLookupRaw(zm,key,klen,&zmlen);
283
+ if (p) {
284
+ freelen = zipmapRawEntryLength(p);
285
+ memmove(p, p+freelen, zmlen-((p-zm)+freelen+1));
286
+ zm = zipmapResize(zm, zmlen-freelen);
287
+
288
+ /* Decrease zipmap length */
289
+ if (zm[0] < ZIPMAP_BIGLEN) zm[0]--;
290
+
291
+ if (deleted) *deleted = 1;
292
+ } else {
293
+ if (deleted) *deleted = 0;
294
+ }
295
+ return zm;
296
+ }
297
+
298
+ /* Call it before to iterate trought elements via zipmapNext() */
299
+ unsigned char *zipmapRewind(unsigned char *zm) {
300
+ return zm+1;
301
+ }
302
+
303
+ /* This function is used to iterate through all the zipmap elements.
304
+ * In the first call the first argument is the pointer to the zipmap + 1.
305
+ * In the next calls what zipmapNext returns is used as first argument.
306
+ * Example:
307
+ *
308
+ * unsigned char *i = zipmapRewind(my_zipmap);
309
+ * while((i = zipmapNext(i,&key,&klen,&value,&vlen)) != NULL) {
310
+ * printf("%d bytes key at $p\n", klen, key);
311
+ * printf("%d bytes value at $p\n", vlen, value);
312
+ * }
313
+ */
314
+ unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *klen, unsigned char **value, unsigned int *vlen) {
315
+ if (zm[0] == ZIPMAP_END) return NULL;
316
+ if (key) {
317
+ *key = zm;
318
+ *klen = zipmapDecodeLength(zm);
319
+ *key += ZIPMAP_LEN_BYTES(*klen);
320
+ }
321
+ zm += zipmapRawKeyLength(zm);
322
+ if (value) {
323
+ *value = zm+1;
324
+ *vlen = zipmapDecodeLength(zm);
325
+ *value += ZIPMAP_LEN_BYTES(*vlen);
326
+ }
327
+ zm += zipmapRawValueLength(zm);
328
+ return zm;
329
+ }
330
+
331
+ /* Search a key and retrieve the pointer and len of the associated value.
332
+ * If the key is found the function returns 1, otherwise 0. */
333
+ int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen) {
334
+ unsigned char *p;
335
+
336
+ if ((p = zipmapLookupRaw(zm,key,klen,NULL)) == NULL) return 0;
337
+ p += zipmapRawKeyLength(p);
338
+ *vlen = zipmapDecodeLength(p);
339
+ *value = p + ZIPMAP_LEN_BYTES(*vlen) + 1;
340
+ return 1;
341
+ }
342
+
343
+ /* Return 1 if the key exists, otherwise 0 is returned. */
344
+ int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen) {
345
+ return zipmapLookupRaw(zm,key,klen,NULL) != NULL;
346
+ }
347
+
348
+ /* Return the number of entries inside a zipmap */
349
+ unsigned int zipmapLen(unsigned char *zm) {
350
+ unsigned int len = 0;
351
+ if (zm[0] < ZIPMAP_BIGLEN) {
352
+ len = zm[0];
353
+ } else {
354
+ unsigned char *p = zipmapRewind(zm);
355
+ while((p = zipmapNext(p,NULL,NULL,NULL,NULL)) != NULL) len++;
356
+
357
+ /* Re-store length if small enough */
358
+ if (len < ZIPMAP_BIGLEN) zm[0] = len;
359
+ }
360
+ return len;
361
+ }
362
+
363
+ void zipmapRepr(unsigned char *p) {
364
+ unsigned int l;
365
+
366
+ printf("{status %u}",*p++);
367
+ while(1) {
368
+ if (p[0] == ZIPMAP_END) {
369
+ printf("{end}");
370
+ break;
371
+ } else {
372
+ unsigned char e;
373
+
374
+ l = zipmapDecodeLength(p);
375
+ printf("{key %u}",l);
376
+ p += zipmapEncodeLength(NULL,l);
377
+ if (l != 0 && fwrite(p,l,1,stdout) == 0) perror("fwrite");
378
+ p += l;
379
+
380
+ l = zipmapDecodeLength(p);
381
+ printf("{value %u}",l);
382
+ p += zipmapEncodeLength(NULL,l);
383
+ e = *p++;
384
+ if (l != 0 && fwrite(p,l,1,stdout) == 0) perror("fwrite");
385
+ p += l+e;
386
+ if (e) {
387
+ printf("[");
388
+ while(e--) printf(".");
389
+ printf("]");
390
+ }
391
+ }
392
+ }
393
+ printf("\n");
394
+ }
395
+
396
+ #ifdef ZIPMAP_TEST_MAIN
397
+ int main(void) {
398
+ unsigned char *zm;
399
+
400
+ zm = zipmapNew();
401
+
402
+ zm = zipmapSet(zm,(unsigned char*) "name",4, (unsigned char*) "foo",3,NULL);
403
+ zm = zipmapSet(zm,(unsigned char*) "surname",7, (unsigned char*) "foo",3,NULL);
404
+ zm = zipmapSet(zm,(unsigned char*) "age",3, (unsigned char*) "foo",3,NULL);
405
+ zipmapRepr(zm);
406
+
407
+ zm = zipmapSet(zm,(unsigned char*) "hello",5, (unsigned char*) "world!",6,NULL);
408
+ zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "bar",3,NULL);
409
+ zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "!",1,NULL);
410
+ zipmapRepr(zm);
411
+ zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "12345",5,NULL);
412
+ zipmapRepr(zm);
413
+ zm = zipmapSet(zm,(unsigned char*) "new",3, (unsigned char*) "xx",2,NULL);
414
+ zm = zipmapSet(zm,(unsigned char*) "noval",5, (unsigned char*) "",0,NULL);
415
+ zipmapRepr(zm);
416
+ zm = zipmapDel(zm,(unsigned char*) "new",3,NULL);
417
+ zipmapRepr(zm);
418
+
419
+ printf("\nLook up large key:\n");
420
+ {
421
+ unsigned char buf[512];
422
+ unsigned char *value;
423
+ unsigned int vlen, i;
424
+ for (i = 0; i < 512; i++) buf[i] = 'a';
425
+
426
+ zm = zipmapSet(zm,buf,512,(unsigned char*) "long",4,NULL);
427
+ if (zipmapGet(zm,buf,512,&value,&vlen)) {
428
+ printf(" <long key> is associated to the %d bytes value: %.*s\n",
429
+ vlen, vlen, value);
430
+ }
431
+ }
432
+
433
+ printf("\nPerform a direct lookup:\n");
434
+ {
435
+ unsigned char *value;
436
+ unsigned int vlen;
437
+
438
+ if (zipmapGet(zm,(unsigned char*) "foo",3,&value,&vlen)) {
439
+ printf(" foo is associated to the %d bytes value: %.*s\n",
440
+ vlen, vlen, value);
441
+ }
442
+ }
443
+ printf("\nIterate trought elements:\n");
444
+ {
445
+ unsigned char *i = zipmapRewind(zm);
446
+ unsigned char *key, *value;
447
+ unsigned int klen, vlen;
448
+
449
+ while((i = zipmapNext(i,&key,&klen,&value,&vlen)) != NULL) {
450
+ printf(" %d:%.*s => %d:%.*s\n", klen, klen, key, vlen, vlen, value);
451
+ }
452
+ }
453
+ return 0;
454
+ }
455
+ #endif