You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

429 lines
16 KiB

  1. #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
  2. #include "brttypes.h"
  3. #include "leafentry.h"
  4. #include "memory.h"
  5. #include "toku_assert.h"
  6. #include "log.h"
  7. #include "wbuf.h"
  8. #include <arpa/inet.h>
  9. #include <inttypes.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. u_int32_t toku_le_crc(LEAFENTRY v) {
  13. return x1764_memory(v, leafentry_memsize(v));
  14. }
  15. int le_committed (u_int32_t klen, void* kval, u_int32_t dlen, void* dval, u_int32_t *resultsize, u_int32_t *disksize, LEAFENTRY *result) {
  16. size_t size = 9+klen+dlen;
  17. unsigned char *lec=toku_malloc(size);
  18. assert(lec);
  19. lec[0] = LE_COMMITTED;
  20. putint(lec+1, klen);
  21. memcpy(lec+1+4, kval, klen);
  22. putint(lec+1+4+klen, dlen);
  23. memcpy(lec+1+4+klen+4, dval, dlen);
  24. *resultsize=size;
  25. *disksize = 1 + 4 + 4 + klen + dlen;
  26. *result=(LEAFENTRY)lec;
  27. return 0;
  28. }
  29. int le_both (TXNID xid, u_int32_t klen, void* kval, u_int32_t clen, void* cval, u_int32_t plen, void* pval,
  30. u_int32_t *resultsize, u_int32_t *disksize, LEAFENTRY *result) {
  31. size_t size = 1+8+4*3+klen+clen+plen;
  32. unsigned char *lec=toku_malloc(size);
  33. assert(lec);
  34. lec[0] = LE_BOTH;
  35. putint64(lec+1, xid);
  36. putint (lec+1+8, klen);
  37. memcpy (lec+1+8+4, kval, klen);
  38. putint (lec+1+8+4+klen, clen);
  39. memcpy (lec+1+8+4+klen+4, cval, clen);
  40. putint (lec+1+8+4+klen+4+clen, plen);
  41. memcpy (lec+1+8+4+klen+4+clen+4, pval, plen);
  42. *resultsize=size;
  43. *disksize = 1 + 8 + 4*3 + klen + clen + plen;
  44. *result=(LEAFENTRY)lec;
  45. return 0;
  46. }
  47. int le_provdel (TXNID xid, u_int32_t klen, void* kval, u_int32_t dlen, void* dval,
  48. u_int32_t *memsize, u_int32_t *disksize, LEAFENTRY *result) {
  49. size_t size = 1 + 8 + 2*4 + klen + dlen;
  50. unsigned char *lec=toku_malloc(size);
  51. assert(lec);
  52. lec[0] = LE_PROVDEL;
  53. putint64(lec+1, xid);
  54. putint (lec+1+8, klen);
  55. memcpy (lec+1+8+4, kval, klen);
  56. putint (lec+1+8+4+klen, dlen);
  57. memcpy (lec+1+8+4+klen+4, dval, dlen);
  58. *memsize=size;
  59. *disksize = 1 + 4 + 4 + 8 + klen + dlen;
  60. *result=(LEAFENTRY)lec;
  61. return 0;
  62. }
  63. int le_provpair (TXNID xid, u_int32_t klen, void* kval, u_int32_t plen, void* pval, u_int32_t *memsize, u_int32_t *disksize, LEAFENTRY *result) {
  64. size_t size = 1 + 8 + 2*4 + klen + plen;
  65. unsigned char *lec=toku_malloc(size);
  66. assert(lec);
  67. lec[0] = LE_PROVPAIR;
  68. putint64(lec+1, xid);
  69. putint (lec+1+8, klen);
  70. memcpy (lec+1+8+4, kval, klen);
  71. putint (lec+1+8+4+klen, plen);
  72. memcpy (lec+1+8+4+klen+4, pval, plen);
  73. *memsize=size;
  74. *disksize = 1 + 4 + 4 + 8 + klen + plen;
  75. *result=(LEAFENTRY)lec;
  76. return 0;
  77. }
  78. static u_int32_t memsize_le_committed (u_int32_t keylen, void *key __attribute__((__unused__)),
  79. u_int32_t vallen, void *val __attribute__((__unused__))) {
  80. return 1+ 2*4 + keylen + vallen;
  81. }
  82. static u_int32_t memsize_le_both (TXNID txnid __attribute__((__unused__)),
  83. u_int32_t klen, void *kval __attribute__((__unused__)),
  84. u_int32_t clen, void *cval __attribute__((__unused__)),
  85. u_int32_t plen, void *pval __attribute__((__unused__))) {
  86. return 1 + 8 + 4*3 + klen + clen + plen;
  87. }
  88. static u_int32_t memsize_le_provdel (TXNID txnid __attribute__((__unused__)),
  89. u_int32_t klen, void *kval __attribute__((__unused__)),
  90. u_int32_t clen, void *cval __attribute__((__unused__))) {
  91. return 1 + 8 + 4*2 + klen + clen;
  92. }
  93. static u_int32_t memsize_le_provpair (TXNID txnid __attribute__((__unused__)),
  94. u_int32_t klen, void *kval __attribute__((__unused__)),
  95. u_int32_t plen, void *pval __attribute__((__unused__))) {
  96. return 1 + 8 + 4*2 + klen + plen;
  97. }
  98. u_int32_t leafentry_memsize (LEAFENTRY le) {
  99. LESWITCHCALL(le, memsize);
  100. }
  101. static u_int32_t disksize_le_committed (u_int32_t keylen, void *key __attribute__((__unused__)),
  102. u_int32_t vallen, void *val __attribute__((__unused__))) {
  103. return 1 + 4 + 4 + keylen + vallen;
  104. }
  105. static u_int32_t disksize_le_both (TXNID txnid __attribute__((__unused__)),
  106. u_int32_t klen, void *kval __attribute__((__unused__)),
  107. u_int32_t clen, void *cval __attribute__((__unused__)),
  108. u_int32_t plen, void *pval __attribute__((__unused__))) {
  109. return 1 + 8 + 4*3 + klen + clen + plen;
  110. }
  111. static u_int32_t disksize_le_provdel (TXNID txnid __attribute__((__unused__)),
  112. u_int32_t klen, void *kval __attribute__((__unused__)),
  113. u_int32_t clen, void *cval __attribute__((__unused__))) {
  114. return 1 + 8 + 4 + 4 + klen + clen;
  115. }
  116. static u_int32_t disksize_le_provpair (TXNID txnid __attribute__((__unused__)),
  117. u_int32_t klen, void *kval __attribute__((__unused__)),
  118. u_int32_t plen, void *pval __attribute__((__unused__))) {
  119. return 1 + 8 + 4 + 4 + klen + plen;
  120. }
  121. u_int32_t leafentry_disksize_internal (LEAFENTRY le) {
  122. LESWITCHCALL(le, disksize);
  123. }
  124. u_int32_t leafentry_disksize (LEAFENTRY le) {
  125. u_int32_t m = leafentry_memsize(le);
  126. u_int32_t d = leafentry_disksize_internal(le);
  127. assert(m==d);
  128. return d;
  129. }
  130. u_int32_t toku_logsizeof_LEAFENTRY (LEAFENTRY le) {
  131. return leafentry_disksize(le);
  132. }
  133. int toku_fread_LEAFENTRY(FILE *f, LEAFENTRY *le, struct x1764 *checksum, u_int32_t *len) {
  134. assert(0);
  135. u_int8_t state;
  136. int r = toku_fread_u_int8_t (f, &state, checksum, len); if (r!=0) return r;
  137. TXNID xid;
  138. BYTESTRING a,b,c;
  139. u_int32_t memsize, disksize;
  140. switch ((enum le_state)state) {
  141. case LE_COMMITTED:
  142. r = toku_fread_BYTESTRING(f, &a, checksum, len); if (r!=0) return r;
  143. r = toku_fread_BYTESTRING(f, &b, checksum, len); if (r!=0) return r;
  144. r = le_committed(a.len, a.data, b.len, b.data,
  145. &memsize, &disksize, le);
  146. toku_free_BYTESTRING(a);
  147. toku_free_BYTESTRING(b);
  148. return r;
  149. case LE_BOTH:
  150. r = toku_fread_TXNID(f, &xid, checksum, len); if (r!=0) return r;
  151. r = toku_fread_BYTESTRING(f, &a, checksum, len); if (r!=0) return r;
  152. r = toku_fread_BYTESTRING(f, &b, checksum, len); if (r!=0) return r;
  153. r = toku_fread_BYTESTRING(f, &c, checksum, len); if (r!=0) return r;
  154. r = le_both(xid, a.len, a.data, b.len, b.data, c.len, c.data,
  155. &memsize, &disksize, le);
  156. toku_free_BYTESTRING(a);
  157. toku_free_BYTESTRING(b);
  158. toku_free_BYTESTRING(c);
  159. return r;
  160. case LE_PROVDEL:
  161. r = toku_fread_TXNID(f, &xid, checksum, len); if (r!=0) return r;
  162. r = toku_fread_BYTESTRING(f, &a, checksum, len); if (r!=0) return r;
  163. r = toku_fread_BYTESTRING(f, &b, checksum, len); if (r!=0) return r;
  164. r = le_provdel(xid, a.len, a.data, b.len, b.data,
  165. &memsize, &disksize, le);
  166. toku_free_BYTESTRING(a);
  167. toku_free_BYTESTRING(b);
  168. return r;
  169. case LE_PROVPAIR:
  170. r = toku_fread_TXNID(f, &xid, checksum, len); if (r!=0) return r;
  171. r = toku_fread_BYTESTRING(f, &a, checksum, len); if (r!=0) return r;
  172. r = toku_fread_BYTESTRING(f, &b, checksum, len); if (r!=0) return r;
  173. r = le_provpair(xid, a.len, a.data, b.len, b.data,
  174. &memsize, &disksize, le);
  175. toku_free_BYTESTRING(a);
  176. toku_free_BYTESTRING(b);
  177. return r;
  178. }
  179. return DB_BADFORMAT;
  180. }
  181. static int print_le_committed (u_int32_t keylen, void *key, u_int32_t vallen, void *val, FILE *outf) {
  182. fprintf(outf, "{C: ");
  183. toku_print_BYTESTRING(outf, keylen, key);
  184. toku_print_BYTESTRING(outf, vallen, val);
  185. fprintf(outf, "}");
  186. return 0;
  187. }
  188. static int print_le_both (TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, u_int32_t plen, void *pval, FILE *outf) {
  189. fprintf(outf, "{B: ");
  190. fprintf(outf, " xid=%" PRId64, xid);
  191. fprintf(outf, " key=");
  192. toku_print_BYTESTRING(outf, klen, kval);
  193. toku_print_BYTESTRING(outf, clen, cval);
  194. fprintf(outf, " provisional=");
  195. toku_print_BYTESTRING(outf, plen, pval);
  196. fprintf(outf, "}");
  197. return 0;
  198. }
  199. static int print_le_provdel (TXNID xid, u_int32_t klen, void *kval, u_int32_t clen, void *cval, FILE *outf) {
  200. fprintf(outf, "{D: ");
  201. fprintf(outf, " xid=%" PRId64, xid);
  202. fprintf(outf, " key=");
  203. toku_print_BYTESTRING(outf, klen, kval);
  204. fprintf(outf, " committed=");
  205. toku_print_BYTESTRING(outf, clen, cval);
  206. fprintf(outf, "}");
  207. return 0;
  208. }
  209. static int print_le_provpair (TXNID xid, u_int32_t klen, void *kval, u_int32_t plen, void *pval, FILE *outf) {
  210. fprintf(outf, "{P: ");
  211. fprintf(outf, " xid=%" PRId64, xid);
  212. fprintf(outf, " key=");
  213. toku_print_BYTESTRING(outf, klen, kval);
  214. fprintf(outf, " provisional=");
  215. toku_print_BYTESTRING(outf, plen, pval);
  216. fprintf(outf, "}");
  217. return 0;
  218. }
  219. int print_leafentry (FILE *outf, LEAFENTRY v) {
  220. if (!v) { printf("NULL"); return 0; }
  221. LESWITCHCALL(v, print, outf);
  222. }
  223. int toku_logprint_LEAFENTRY (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, u_int32_t *len, const char *format __attribute__((__unused__))) {
  224. LEAFENTRY v;
  225. int r = toku_fread_LEAFENTRY(inf, &v, checksum, len);
  226. if (r!=0) return r;
  227. fprintf(outf, " %s=", fieldname);
  228. print_leafentry(outf, v);
  229. toku_free(v);
  230. return 0;
  231. }
  232. void wbuf_LEAFENTRY(struct wbuf *w, LEAFENTRY le) {
  233. wbuf_literal_bytes(w, le, leafentry_disksize(le));
  234. }
  235. void rbuf_LEAFENTRY(struct rbuf *r, u_int32_t *resultsize, u_int32_t *disksize, LEAFENTRY *lep) {
  236. LEAFENTRY le = (LEAFENTRY)(&r->buf[r->ndone]);
  237. u_int32_t siz = leafentry_disksize(le);
  238. bytevec bytes;
  239. rbuf_literal_bytes(r, &bytes, siz);
  240. *lep = toku_memdup(le, siz);
  241. assert(*lep);
  242. *resultsize = siz;
  243. *disksize = siz;
  244. return;
  245. }
  246. // LEAFENTRUse toku_free()
  247. void toku_free_LEAFENTRY(LEAFENTRY le) {
  248. toku_free(le);
  249. }
  250. inline int le_is_provdel(LEAFENTRY le) {
  251. return get_le_state(le)==LE_PROVDEL;
  252. }
  253. inline void* latest_key_le_committed (u_int32_t UU(keylen), void *key, u_int32_t UU(vallen), void *UU(val)) {
  254. return key;
  255. }
  256. inline void* latest_key_le_both (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
  257. return kval;
  258. }
  259. inline void* latest_key_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
  260. return 0; // for provisional delete, there is no *latest* key, so return NULL
  261. }
  262. inline void* latest_key_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(plen), void *UU(pval)) {
  263. return kval;
  264. }
  265. inline void* le_latest_key (LEAFENTRY le) {
  266. LESWITCHCALL(le, latest_key);
  267. }
  268. inline u_int32_t latest_keylen_le_committed (u_int32_t keylen, void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
  269. return keylen;
  270. }
  271. inline u_int32_t latest_keylen_le_both (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
  272. return klen;
  273. }
  274. inline u_int32_t latest_keylen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
  275. return 0; // for provisional delete, there is no *latest* key, so return 0. What else can we do?
  276. }
  277. inline u_int32_t latest_keylen_le_provpair (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
  278. return klen;
  279. }
  280. inline u_int32_t le_latest_keylen (LEAFENTRY le) {
  281. LESWITCHCALL(le, latest_keylen);
  282. }
  283. inline void* latest_val_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
  284. return val;
  285. }
  286. inline void* latest_val_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *pval) {
  287. return pval;
  288. }
  289. inline void* latest_val_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
  290. return 0; // for provisional delete, there is no *latest* key, so return NULL
  291. }
  292. inline void* latest_val_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *pval) {
  293. return pval;
  294. }
  295. inline void* le_latest_val (LEAFENTRY le) {
  296. LESWITCHCALL(le, latest_val);
  297. }
  298. inline u_int32_t latest_vallen_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t vallen, void *UU(val)) {
  299. return vallen;
  300. }
  301. inline u_int32_t latest_vallen_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t plen, void *UU(pval)) {
  302. return plen;
  303. }
  304. inline u_int32_t latest_vallen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
  305. return 0; // for provisional delete, there is no *latest* key, so return 0. What else can we do?
  306. }
  307. inline u_int32_t latest_vallen_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t plen, void *UU(pval)) {
  308. return plen;
  309. }
  310. inline u_int32_t le_latest_vallen (LEAFENTRY le) {
  311. LESWITCHCALL(le, latest_vallen);
  312. }
  313. inline void* any_key_le_committed (u_int32_t UU(keylen), void *key, u_int32_t UU(vallen), void *UU(val)) {
  314. return key;
  315. }
  316. inline void* any_key_le_both (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
  317. return kval;
  318. }
  319. inline void* any_key_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(clen), void *UU(cval)) {
  320. return kval;
  321. }
  322. inline void* any_key_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *kval, u_int32_t UU(plen), void *UU(pval)) {
  323. return kval;
  324. }
  325. inline void* le_any_key (LEAFENTRY le) {
  326. LESWITCHCALL(le, any_key);
  327. }
  328. inline u_int32_t any_keylen_le_committed (u_int32_t keylen, void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
  329. return keylen;
  330. }
  331. inline u_int32_t any_keylen_le_both (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
  332. return klen;
  333. }
  334. inline u_int32_t any_keylen_le_provdel (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
  335. return klen;
  336. }
  337. inline u_int32_t any_keylen_le_provpair (TXNID UU(xid), u_int32_t klen, void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
  338. return klen;
  339. }
  340. inline u_int32_t le_any_keylen (LEAFENTRY le) {
  341. LESWITCHCALL(le, any_keylen);
  342. }
  343. inline void* any_val_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
  344. return val;
  345. }
  346. inline void* any_val_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *cval, u_int32_t UU(plen), void *UU(pval)) {
  347. return cval;
  348. }
  349. inline void* any_val_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *cval) {
  350. return cval;
  351. }
  352. inline void* any_val_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *pval) {
  353. return pval;
  354. }
  355. inline void* le_any_val (LEAFENTRY le) {
  356. LESWITCHCALL(le, any_val);
  357. }
  358. inline u_int32_t any_vallen_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t vallen, void *UU(val)) {
  359. return vallen;
  360. }
  361. inline u_int32_t any_vallen_le_both (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t plen, void *UU(pval)) {
  362. return plen;
  363. }
  364. inline u_int32_t any_vallen_le_provdel (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t clen, void *UU(cval)) {
  365. return clen; // for provisional delete, there is no *any* key, so return 0. What else can we do?
  366. }
  367. inline u_int32_t any_vallen_le_provpair (TXNID UU(xid), u_int32_t UU(klen), void *UU(kval), u_int32_t plen, void *UU(pval)) {
  368. return plen;
  369. }
  370. inline u_int32_t le_any_vallen (LEAFENTRY le) {
  371. LESWITCHCALL(le, any_vallen);
  372. }
  373. inline u_int64_t any_xid_le_committed (u_int32_t UU(keylen), void *UU(key), u_int32_t UU(vallen), void *UU(val)) {
  374. return 0;
  375. }
  376. inline u_int64_t any_xid_le_both (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval), u_int32_t UU(plen), void *UU(pval)) {
  377. return xid;
  378. }
  379. inline u_int64_t any_xid_le_provdel (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(clen), void *UU(cval)) {
  380. return xid;
  381. }
  382. inline u_int64_t any_xid_le_provpair (TXNID xid, u_int32_t UU(klen), void *UU(kval), u_int32_t UU(plen), void *UU(pval)) {
  383. return xid;
  384. }
  385. inline u_int64_t le_any_xid (LEAFENTRY le) {
  386. LESWITCHCALL(le, any_xid);
  387. }