Development of an internal social media platform with personalised dashboards for students
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.

_fsBTree.c 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*############################################################################
  2. #
  3. # Copyright (c) 2004 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ############################################################################*/
  14. #define MASTER_ID "$Id$\n"
  15. /* fsBTree - FileStorage index BTree
  16. This BTree implements a mapping from 2-character strings
  17. to six-character strings. This allows us to efficiently store
  18. a FileStorage index as a nested mapping of 6-character oid prefix
  19. to mapping of 2-character oid suffix to 6-character (byte) file
  20. positions.
  21. */
  22. typedef unsigned char char2[2];
  23. typedef unsigned char char6[6];
  24. /* Setup template macros */
  25. #define PERSISTENT
  26. #define MOD_NAME_PREFIX "fs"
  27. #define DEFAULT_MAX_BUCKET_SIZE 500
  28. #define DEFAULT_MAX_BTREE_SIZE 500
  29. #include "_compat.h"
  30. /*#include "intkeymacros.h"*/
  31. #define KEYMACROS_H "$Id$\n"
  32. #define KEY_TYPE char2
  33. #undef KEY_TYPE_IS_PYOBJECT
  34. #define KEY_CHECK(K) (PyBytes_Check(K) && PyBytes_GET_SIZE(K)==2)
  35. #define TEST_KEY_SET_OR(V, K, T) if ( ( (V) = ((*(K) < *(T) || (*(K) == *(T) && (K)[1] < (T)[1])) ? -1 : ((*(K) == *(T) && (K)[1] == (T)[1]) ? 0 : 1)) ), 0 )
  36. #define DECREF_KEY(KEY)
  37. #define INCREF_KEY(k)
  38. #define COPY_KEY(KEY, E) (*(KEY)=*(E), (KEY)[1]=(E)[1])
  39. #define COPY_KEY_TO_OBJECT(O, K) O=PyBytes_FromStringAndSize((const char*)K,2)
  40. #define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) \
  41. if (KEY_CHECK(ARG)) memcpy(TARGET, PyBytes_AS_STRING(ARG), 2); else { \
  42. PyErr_SetString(PyExc_TypeError, "expected two-character string key"); \
  43. (STATUS)=0; }
  44. /*#include "intvaluemacros.h"*/
  45. #define VALUEMACROS_H "$Id$\n"
  46. #define VALUE_TYPE char6
  47. #undef VALUE_TYPE_IS_PYOBJECT
  48. #define TEST_VALUE(K, T) memcmp(K,T,6)
  49. #define DECREF_VALUE(k)
  50. #define INCREF_VALUE(k)
  51. #define COPY_VALUE(V, E) (memcpy(V, E, 6))
  52. #define COPY_VALUE_TO_OBJECT(O, K) O=PyBytes_FromStringAndSize((const char*)K,6)
  53. #define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
  54. if ((PyBytes_Check(ARG) && PyBytes_GET_SIZE(ARG)==6)) \
  55. memcpy(TARGET, PyBytes_AS_STRING(ARG), 6); else { \
  56. PyErr_SetString(PyExc_TypeError, "expected six-character string key"); \
  57. (STATUS)=0; }
  58. #define NORMALIZE_VALUE(V, MIN)
  59. #include "Python.h"
  60. static PyObject *bucket_toBytes(PyObject *self);
  61. static PyObject *bucket_fromBytes(PyObject *self, PyObject *state);
  62. #define EXTRA_BUCKET_METHODS \
  63. {"toBytes", (PyCFunction) bucket_toBytes, METH_NOARGS, \
  64. "toBytes() -- Return the state as a bytes array"}, \
  65. {"fromBytes", (PyCFunction) bucket_fromBytes, METH_O, \
  66. "fromSBytes(s) -- Set the state of the object from a bytes array"}, \
  67. {"toString", (PyCFunction) bucket_toBytes, METH_NOARGS, \
  68. "toString() -- Deprecated alias for 'toBytes'"}, \
  69. {"fromString", (PyCFunction) bucket_fromBytes, METH_O, \
  70. "fromString(s) -- Deprecated alias for 'fromBytes'"}, \
  71. #ifdef PY3K
  72. #define INITMODULE PyInit__fsBTree
  73. #else
  74. #define INITMODULE init_fsBTree
  75. #endif
  76. #include "BTreeModuleTemplate.c"
  77. static PyObject *
  78. bucket_toBytes(PyObject *oself)
  79. {
  80. Bucket *self = (Bucket *)oself;
  81. PyObject *items = NULL;
  82. int len;
  83. PER_USE_OR_RETURN(self, NULL);
  84. len = self->len;
  85. items = PyBytes_FromStringAndSize(NULL, len*8);
  86. if (items == NULL)
  87. goto err;
  88. memcpy(PyBytes_AS_STRING(items), self->keys, len*2);
  89. memcpy(PyBytes_AS_STRING(items)+len*2, self->values, len*6);
  90. PER_UNUSE(self);
  91. return items;
  92. err:
  93. PER_UNUSE(self);
  94. Py_XDECREF(items);
  95. return NULL;
  96. }
  97. static PyObject *
  98. bucket_fromBytes(PyObject *oself, PyObject *state)
  99. {
  100. Bucket *self = (Bucket *)oself;
  101. int len;
  102. KEY_TYPE *keys;
  103. VALUE_TYPE *values;
  104. len = PyBytes_Size(state);
  105. if (len < 0)
  106. return NULL;
  107. if (len%8)
  108. {
  109. PyErr_SetString(PyExc_ValueError, "state string of wrong size");
  110. return NULL;
  111. }
  112. len /= 8;
  113. if (self->next) {
  114. Py_DECREF(self->next);
  115. self->next = NULL;
  116. }
  117. if (len > self->size) {
  118. keys = BTree_Realloc(self->keys, sizeof(KEY_TYPE)*len);
  119. if (keys == NULL)
  120. return NULL;
  121. values = BTree_Realloc(self->values, sizeof(VALUE_TYPE)*len);
  122. if (values == NULL)
  123. return NULL;
  124. self->keys = keys;
  125. self->values = values;
  126. self->size = len;
  127. }
  128. memcpy(self->keys, PyBytes_AS_STRING(state), len*2);
  129. memcpy(self->values, PyBytes_AS_STRING(state)+len*2, len*6);
  130. self->len = len;
  131. Py_INCREF(self);
  132. return (PyObject *)self;
  133. }