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.

SetTemplate.c 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*****************************************************************************
  2. Copyright (c) 2001, 2002 Zope Foundation and Contributors.
  3. All Rights Reserved.
  4. This software is subject to the provisions of the Zope Public License,
  5. Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  6. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  7. WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  8. WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  9. FOR A PARTICULAR PURPOSE
  10. ****************************************************************************/
  11. #include "_compat.h"
  12. #define SETTEMPLATE_C "$Id$\n"
  13. static PyObject *
  14. Set_insert(Bucket *self, PyObject *args)
  15. {
  16. PyObject *key;
  17. int i;
  18. UNLESS (PyArg_ParseTuple(args, "O", &key))
  19. return NULL;
  20. if ( (i=_bucket_set(self, key, Py_None, 1, 1, 0)) < 0)
  21. return NULL;
  22. return INT_FROM_LONG(i);
  23. }
  24. /* _Set_update and _TreeSet_update are identical except for the
  25. function they call to add the element to the set.
  26. */
  27. static int
  28. _Set_update(Bucket *self, PyObject *seq)
  29. {
  30. int n=0, ind=0;
  31. PyObject *iter, *v;
  32. iter = PyObject_GetIter(seq);
  33. if (iter == NULL)
  34. return -1;
  35. while (1) {
  36. v = PyIter_Next(iter);
  37. if (v == NULL) {
  38. if (PyErr_Occurred())
  39. goto err;
  40. else
  41. break;
  42. }
  43. ind = _bucket_set(self, v, Py_None, 1, 1, 0);
  44. Py_DECREF(v);
  45. if (ind < 0)
  46. goto err;
  47. else
  48. n += ind;
  49. }
  50. err:
  51. Py_DECREF(iter);
  52. if (ind < 0)
  53. return -1;
  54. return n;
  55. }
  56. static PyObject *
  57. Set_update(Bucket *self, PyObject *args)
  58. {
  59. PyObject *seq = NULL;
  60. int n = 0;
  61. if (!PyArg_ParseTuple(args, "|O:update", &seq))
  62. return NULL;
  63. if (seq) {
  64. n = _Set_update(self, seq);
  65. if (n < 0)
  66. return NULL;
  67. }
  68. return INT_FROM_LONG(n);
  69. }
  70. static PyObject *
  71. Set_remove(Bucket *self, PyObject *args)
  72. {
  73. PyObject *key;
  74. UNLESS (PyArg_ParseTuple(args, "O", &key))
  75. return NULL;
  76. if (_bucket_set(self, key, NULL, 0, 1, 0) < 0)
  77. return NULL;
  78. Py_INCREF(Py_None);
  79. return Py_None;
  80. }
  81. static int
  82. _set_setstate(Bucket *self, PyObject *args)
  83. {
  84. PyObject *k, *items;
  85. Bucket *next=0;
  86. int i, l, copied=1;
  87. KEY_TYPE *keys;
  88. UNLESS (PyArg_ParseTuple(args, "O|O", &items, &next))
  89. return -1;
  90. if (!PyTuple_Check(items)) {
  91. PyErr_SetString(PyExc_TypeError,
  92. "tuple required for first state element");
  93. return -1;
  94. }
  95. if ((l=PyTuple_Size(items)) < 0)
  96. return -1;
  97. for (i=self->len; --i >= 0; )
  98. {
  99. DECREF_KEY(self->keys[i]);
  100. }
  101. self->len=0;
  102. if (self->next)
  103. {
  104. Py_DECREF(self->next);
  105. self->next=0;
  106. }
  107. if (l > self->size)
  108. {
  109. UNLESS (keys=BTree_Realloc(self->keys, sizeof(KEY_TYPE)*l))
  110. return -1;
  111. self->keys=keys;
  112. self->size=l;
  113. }
  114. for (i=0; i<l; i++)
  115. {
  116. k=PyTuple_GET_ITEM(items, i);
  117. COPY_KEY_FROM_ARG(self->keys[i], k, copied);
  118. UNLESS (copied)
  119. return -1;
  120. INCREF_KEY(self->keys[i]);
  121. }
  122. self->len=l;
  123. if (next)
  124. {
  125. self->next=next;
  126. Py_INCREF(next);
  127. }
  128. return 0;
  129. }
  130. static PyObject *
  131. set_setstate(Bucket *self, PyObject *args)
  132. {
  133. int r;
  134. UNLESS (PyArg_ParseTuple(args, "O", &args))
  135. return NULL;
  136. PER_PREVENT_DEACTIVATION(self);
  137. r=_set_setstate(self, args);
  138. PER_UNUSE(self);
  139. if (r < 0)
  140. return NULL;
  141. Py_INCREF(Py_None);
  142. return Py_None;
  143. }
  144. static struct PyMethodDef Set_methods[] = {
  145. {"__getstate__", (PyCFunction) bucket_getstate, METH_VARARGS,
  146. "__getstate__() -- Return the picklable state of the object"},
  147. {"__setstate__", (PyCFunction) set_setstate, METH_VARARGS,
  148. "__setstate__() -- Set the state of the object"},
  149. {"keys", (PyCFunction) bucket_keys, METH_VARARGS | METH_KEYWORDS,
  150. "keys() -- Return the keys"},
  151. {"has_key", (PyCFunction) bucket_has_key, METH_O,
  152. "has_key(key) -- Test whether the bucket contains the given key"},
  153. {"clear", (PyCFunction) bucket_clear, METH_VARARGS,
  154. "clear() -- Remove all of the items from the bucket"},
  155. {"maxKey", (PyCFunction) Bucket_maxKey, METH_VARARGS,
  156. "maxKey([key]) -- Find the maximum key\n\n"
  157. "If an argument is given, find the maximum <= the argument"},
  158. {"minKey", (PyCFunction) Bucket_minKey, METH_VARARGS,
  159. "minKey([key]) -- Find the minimum key\n\n"
  160. "If an argument is given, find the minimum >= the argument"},
  161. #ifdef PERSISTENT
  162. {"_p_resolveConflict",
  163. (PyCFunction) bucket__p_resolveConflict, METH_VARARGS,
  164. "_p_resolveConflict() -- Reinitialize from a newly created copy"},
  165. {"_p_deactivate",
  166. (PyCFunction) bucket__p_deactivate, METH_VARARGS | METH_KEYWORDS,
  167. "_p_deactivate() -- Reinitialize from a newly created copy"},
  168. #endif
  169. {"add", (PyCFunction)Set_insert, METH_VARARGS,
  170. "add(id) -- Add a key to the set"},
  171. {"insert", (PyCFunction)Set_insert, METH_VARARGS,
  172. "insert(id) -- Add a key to the set"},
  173. {"update", (PyCFunction)Set_update, METH_VARARGS,
  174. "update(seq) -- Add the items from the given sequence to the set"},
  175. {"remove", (PyCFunction)Set_remove, METH_VARARGS,
  176. "remove(id) -- Remove an id from the set"},
  177. {NULL, NULL} /* sentinel */
  178. };
  179. static int
  180. Set_init(PyObject *self, PyObject *args, PyObject *kwds)
  181. {
  182. PyObject *v = NULL;
  183. if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "Set", &v))
  184. return -1;
  185. if (v)
  186. return _Set_update((Bucket *)self, v);
  187. else
  188. return 0;
  189. }
  190. static PyObject *
  191. set_repr(Bucket *self)
  192. {
  193. static PyObject *format;
  194. PyObject *r, *t;
  195. if (!format)
  196. format = TEXT_FROM_STRING(MOD_NAME_PREFIX "Set(%s)");
  197. UNLESS (t = PyTuple_New(1))
  198. return NULL;
  199. UNLESS (r = bucket_keys(self, NULL, NULL))
  200. goto err;
  201. PyTuple_SET_ITEM(t, 0, r);
  202. r = t;
  203. ASSIGN(r, TEXT_FORMAT(format, r));
  204. return r;
  205. err:
  206. Py_DECREF(t);
  207. return NULL;
  208. }
  209. static Py_ssize_t
  210. set_length(Bucket *self)
  211. {
  212. int r;
  213. PER_USE_OR_RETURN(self, -1);
  214. r = self->len;
  215. PER_UNUSE(self);
  216. return r;
  217. }
  218. static PyObject *
  219. set_item(Bucket *self, Py_ssize_t index)
  220. {
  221. PyObject *r=0;
  222. PER_USE_OR_RETURN(self, NULL);
  223. if (index >= 0 && index < self->len)
  224. {
  225. COPY_KEY_TO_OBJECT(r, self->keys[index]);
  226. }
  227. else
  228. IndexError(index);
  229. PER_UNUSE(self);
  230. return r;
  231. }
  232. static PySequenceMethods set_as_sequence = {
  233. (lenfunc)set_length, /* sq_length */
  234. (binaryfunc)0, /* sq_concat */
  235. (ssizeargfunc)0, /* sq_repeat */
  236. (ssizeargfunc)set_item, /* sq_item */
  237. (ssizessizeargfunc)0, /* sq_slice */
  238. (ssizeobjargproc)0, /* sq_ass_item */
  239. (ssizessizeobjargproc)0, /* sq_ass_slice */
  240. (objobjproc)bucket_contains, /* sq_contains */
  241. 0, /* sq_inplace_concat */
  242. 0, /* sq_inplace_repeat */
  243. };
  244. static PyTypeObject SetType = {
  245. PyVarObject_HEAD_INIT(NULL, 0) /* PyPersist_Type */
  246. MODULE_NAME MOD_NAME_PREFIX "Set", /* tp_name */
  247. sizeof(Bucket), /* tp_basicsize */
  248. 0, /* tp_itemsize */
  249. (destructor)bucket_dealloc, /* tp_dealloc */
  250. 0, /* tp_print */
  251. 0, /* tp_getattr */
  252. 0, /* tp_setattr */
  253. 0, /* tp_compare */
  254. (reprfunc)set_repr, /* tp_repr */
  255. 0, /* tp_as_number */
  256. &set_as_sequence, /* tp_as_sequence */
  257. 0, /* tp_as_mapping */
  258. 0, /* tp_hash */
  259. 0, /* tp_call */
  260. 0, /* tp_str */
  261. 0, /* tp_getattro */
  262. 0, /* tp_setattro */
  263. 0, /* tp_as_buffer */
  264. Py_TPFLAGS_DEFAULT |
  265. Py_TPFLAGS_HAVE_GC |
  266. Py_TPFLAGS_BASETYPE, /* tp_flags */
  267. 0, /* tp_doc */
  268. (traverseproc)bucket_traverse, /* tp_traverse */
  269. (inquiry)bucket_tp_clear, /* tp_clear */
  270. 0, /* tp_richcompare */
  271. 0, /* tp_weaklistoffset */
  272. (getiterfunc)Bucket_getiter, /* tp_iter */
  273. 0, /* tp_iternext */
  274. Set_methods, /* tp_methods */
  275. Bucket_members, /* tp_members */
  276. 0, /* tp_getset */
  277. 0, /* tp_base */
  278. 0, /* tp_dict */
  279. 0, /* tp_descr_get */
  280. 0, /* tp_descr_set */
  281. 0, /* tp_dictoffset */
  282. Set_init, /* tp_init */
  283. 0, /* tp_alloc */
  284. 0, /*PyType_GenericNew,*/ /* tp_new */
  285. };
  286. static int
  287. nextSet(SetIteration *i)
  288. {
  289. if (i->position >= 0)
  290. {
  291. UNLESS(PER_USE(BUCKET(i->set)))
  292. return -1;
  293. if (i->position)
  294. {
  295. DECREF_KEY(i->key);
  296. }
  297. if (i->position < BUCKET(i->set)->len)
  298. {
  299. COPY_KEY(i->key, BUCKET(i->set)->keys[i->position]);
  300. INCREF_KEY(i->key);
  301. i->position ++;
  302. }
  303. else
  304. {
  305. i->position = -1;
  306. PER_ACCESSED(BUCKET(i->set));
  307. }
  308. PER_ALLOW_DEACTIVATION(BUCKET(i->set));
  309. }
  310. return 0;
  311. }