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.

BTreeTemplate.c 70KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474
  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 BTREETEMPLATE_C "$Id$\n"
  13. static long
  14. _get_max_size(BTree *self, PyObject *name, long default_max)
  15. {
  16. PyObject *size;
  17. long isize;
  18. size = PyObject_GetAttr(OBJECT(OBJECT(self)->ob_type), name);
  19. if (size == NULL) {
  20. PyErr_Clear();
  21. return default_max;
  22. }
  23. #ifdef PY3K
  24. isize = PyLong_AsLong(size);
  25. #else
  26. isize = PyInt_AsLong(size);
  27. #endif
  28. Py_DECREF(size);
  29. if (isize <= 0 && ! PyErr_Occurred()) {
  30. PyErr_SetString(PyExc_ValueError,
  31. "non-positive max size in BTree subclass");
  32. return -1;
  33. }
  34. return isize;
  35. }
  36. static int
  37. _max_internal_size(BTree *self)
  38. {
  39. long isize;
  40. if (self->max_internal_size > 0) return self->max_internal_size;
  41. isize = _get_max_size(self, max_internal_size_str, DEFAULT_MAX_BTREE_SIZE);
  42. self->max_internal_size = isize;
  43. return isize;
  44. }
  45. static int
  46. _max_leaf_size(BTree *self)
  47. {
  48. long isize;
  49. if (self->max_leaf_size > 0) return self->max_leaf_size;
  50. isize = _get_max_size(self, max_leaf_size_str, DEFAULT_MAX_BUCKET_SIZE);
  51. self->max_leaf_size = isize;
  52. return isize;
  53. }
  54. /* Sanity-check a BTree. This is a private helper for BTree_check. Return:
  55. * -1 Error. If it's an internal inconsistency in the BTree,
  56. * AssertionError is set.
  57. * 0 No problem found.
  58. *
  59. * nextbucket is the bucket "one beyond the end" of the BTree; the last bucket
  60. * directly reachable from following right child pointers *should* be linked
  61. * to nextbucket (and this is checked).
  62. */
  63. static int
  64. BTree_check_inner(BTree *self, Bucket *nextbucket)
  65. {
  66. int i;
  67. Bucket *bucketafter;
  68. Sized *child;
  69. char *errormsg = "internal error"; /* someone should have overriden */
  70. Sized *activated_child = NULL;
  71. int result = -1; /* until proved innocent */
  72. #define CHECK(CONDITION, ERRORMSG) \
  73. if (!(CONDITION)) { \
  74. errormsg = (ERRORMSG); \
  75. goto Error; \
  76. }
  77. PER_USE_OR_RETURN(self, -1);
  78. CHECK(self->len >= 0, "BTree len < 0");
  79. CHECK(self->len <= self->size, "BTree len > size");
  80. if (self->len == 0) /* Empty BTree. */
  81. {
  82. CHECK(self->firstbucket == NULL,
  83. "Empty BTree has non-NULL firstbucket");
  84. result = 0;
  85. goto Done;
  86. }
  87. /* Non-empty BTree. */
  88. CHECK(self->firstbucket != NULL, "Non-empty BTree has NULL firstbucket");
  89. /* Obscure: The first bucket is pointed to at least by self->firstbucket
  90. * and data[0].child of whichever BTree node it's a child of. However,
  91. * if persistence is enabled then the latter BTree node may be a ghost
  92. * at this point, and so its pointers "don't count": we can only rely
  93. * on self's pointers being intact.
  94. */
  95. #ifdef PERSISTENT
  96. CHECK(Py_REFCNT(self->firstbucket) >= 1,
  97. "Non-empty BTree firstbucket has refcount < 1");
  98. #else
  99. CHECK(Py_REFCNT(self->firstbucket) >= 2,
  100. "Non-empty BTree firstbucket has refcount < 2");
  101. #endif
  102. for (i = 0; i < self->len; ++i)
  103. {
  104. CHECK(self->data[i].child != NULL, "BTree has NULL child");
  105. }
  106. if (SameType_Check(self, self->data[0].child))
  107. {
  108. /* Our children are also BTrees. */
  109. child = self->data[0].child;
  110. UNLESS (PER_USE(child))
  111. goto Done;
  112. activated_child = child;
  113. CHECK(self->firstbucket == BTREE(child)->firstbucket,
  114. "BTree has firstbucket different than "
  115. "its first child's firstbucket");
  116. PER_ALLOW_DEACTIVATION(child);
  117. activated_child = NULL;
  118. for (i = 0; i < self->len; ++i)
  119. {
  120. child = self->data[i].child;
  121. CHECK(SameType_Check(self, child),
  122. "BTree children have different types");
  123. if (i == self->len - 1)
  124. bucketafter = nextbucket;
  125. else
  126. {
  127. BTree *child2 = BTREE(self->data[i+1].child);
  128. UNLESS (PER_USE(child2))
  129. goto Done;
  130. bucketafter = child2->firstbucket;
  131. PER_ALLOW_DEACTIVATION(child2);
  132. }
  133. if (BTree_check_inner(BTREE(child), bucketafter) < 0)
  134. goto Done;
  135. }
  136. }
  137. else /* Our children are buckets. */
  138. {
  139. CHECK(self->firstbucket == BUCKET(self->data[0].child),
  140. "Bottom-level BTree node has inconsistent firstbucket belief");
  141. for (i = 0; i < self->len; ++i)
  142. {
  143. child = self->data[i].child;
  144. UNLESS (PER_USE(child))
  145. goto Done;
  146. activated_child = child;
  147. CHECK(!SameType_Check(self, child),
  148. "BTree children have different types");
  149. CHECK(child->len >= 1, "Bucket length < 1");/* no empty buckets! */
  150. CHECK(child->len <= child->size, "Bucket len > size");
  151. #ifdef PERSISTENT
  152. CHECK(Py_REFCNT(child) >= 1, "Bucket has refcount < 1");
  153. #else
  154. CHECK(Py_REFCNT(child) >= 2, "Bucket has refcount < 2");
  155. #endif
  156. if (i == self->len - 1)
  157. bucketafter = nextbucket;
  158. else
  159. bucketafter = BUCKET(self->data[i+1].child);
  160. CHECK(BUCKET(child)->next == bucketafter,
  161. "Bucket next pointer is damaged");
  162. PER_ALLOW_DEACTIVATION(child);
  163. activated_child = NULL;
  164. }
  165. }
  166. result = 0;
  167. goto Done;
  168. Error:
  169. PyErr_SetString(PyExc_AssertionError, errormsg);
  170. result = -1;
  171. Done:
  172. /* No point updating access time -- this isn't a "real" use. */
  173. PER_ALLOW_DEACTIVATION(self);
  174. if (activated_child)
  175. {
  176. PER_ALLOW_DEACTIVATION(activated_child);
  177. }
  178. return result;
  179. #undef CHECK
  180. }
  181. /* Sanity-check a BTree. This is the ._check() method. Return:
  182. * NULL Error. If it's an internal inconsistency in the BTree,
  183. * AssertionError is set.
  184. * Py_None No problem found.
  185. */
  186. static PyObject*
  187. BTree_check(BTree *self)
  188. {
  189. PyObject *result = NULL;
  190. int i = BTree_check_inner(self, NULL);
  191. if (i >= 0)
  192. {
  193. result = Py_None;
  194. Py_INCREF(result);
  195. }
  196. return result;
  197. }
  198. #define _BGET_REPLACE_TYPE_ERROR 1
  199. #define _BGET_ALLOW_TYPE_ERROR 0
  200. /*
  201. ** _BTree_get
  202. **
  203. ** Search a BTree.
  204. **
  205. ** Arguments
  206. ** self a pointer to a BTree
  207. ** keyarg the key to search for, as a Python object
  208. ** has_key true/false; when false, try to return the associated
  209. ** value; when true, return a boolean
  210. ** replace_type_err true/false: When true, ignore the TypeError from
  211. ** a key conversion issue, instead
  212. ** transforming it into a KeyError set. If
  213. ** you are just reading/searching, set to
  214. ** true. If you will be adding/updating,
  215. ** however, set to false. Or use
  216. ** _BGET_REPLACE_TYPE_ERROR
  217. ** and _BGET_ALLOW_TYPE_ERROR, respectively.
  218. ** Return
  219. ** When has_key false:
  220. ** If key exists, its associated value.
  221. ** If key doesn't exist, NULL and KeyError is set.
  222. ** When has_key true:
  223. ** A Python int is returned in any case.
  224. ** If key exists, the depth of the bucket in which it was found.
  225. ** If key doesn't exist, 0.
  226. */
  227. static PyObject *
  228. _BTree_get(BTree *self, PyObject *keyarg, int has_key, int replace_type_err)
  229. {
  230. KEY_TYPE key;
  231. PyObject *result = NULL; /* guilty until proved innocent */
  232. int copied = 1;
  233. COPY_KEY_FROM_ARG(key, keyarg, copied);
  234. UNLESS (copied)
  235. {
  236. if (replace_type_err && PyErr_ExceptionMatches(PyExc_TypeError))
  237. {
  238. PyErr_Clear();
  239. PyErr_SetObject(PyExc_KeyError, keyarg);
  240. }
  241. return NULL;
  242. }
  243. PER_USE_OR_RETURN(self, NULL);
  244. if (self->len == 0)
  245. {
  246. /* empty BTree */
  247. if (has_key)
  248. result = INT_FROM_LONG(0);
  249. else
  250. PyErr_SetObject(PyExc_KeyError, keyarg);
  251. }
  252. else
  253. {
  254. for (;;)
  255. {
  256. int i;
  257. Sized *child;
  258. BTREE_SEARCH(i, self, key, goto Done);
  259. child = self->data[i].child;
  260. has_key += has_key != 0; /* bump depth counter, maybe */
  261. if (SameType_Check(self, child))
  262. {
  263. PER_UNUSE(self);
  264. self = BTREE(child);
  265. PER_USE_OR_RETURN(self, NULL);
  266. }
  267. else
  268. {
  269. result = _bucket_get(BUCKET(child), keyarg, has_key);
  270. break;
  271. }
  272. }
  273. }
  274. Done:
  275. PER_UNUSE(self);
  276. return result;
  277. }
  278. static PyObject *
  279. BTree_get(BTree *self, PyObject *key)
  280. {
  281. return _BTree_get(self, key, 0, _BGET_REPLACE_TYPE_ERROR);
  282. }
  283. /* Create a new bucket for the BTree or TreeSet using the class attribute
  284. _bucket_type, which is normally initialized to BucketType or SetType
  285. as appropriate.
  286. */
  287. static Sized *
  288. BTree_newBucket(BTree *self)
  289. {
  290. PyObject *factory;
  291. Sized *result;
  292. /* _bucket_type_str defined in BTreeModuleTemplate.c */
  293. factory = PyObject_GetAttr((PyObject *)Py_TYPE(self), _bucket_type_str);
  294. if (factory == NULL)
  295. return NULL;
  296. /* TODO: Should we check that the factory actually returns something
  297. of the appropriate type? How? The C code here is going to
  298. depend on any custom bucket type having the same layout at the
  299. C level.
  300. */
  301. result = SIZED(PyObject_CallObject(factory, NULL));
  302. Py_DECREF(factory);
  303. return result;
  304. }
  305. /*
  306. * Move data from the current BTree, from index onward, to the newly created
  307. * BTree 'next'. self and next must both be activated. If index is OOB (< 0
  308. * or >= self->len), use self->len / 2 as the index (i.e., split at the
  309. * midpoint). self must have at least 2 children on entry, and index must
  310. * be such that self and next each have at least one child at exit. self's
  311. * accessed time is updated.
  312. *
  313. * Return:
  314. * -1 error
  315. * 0 OK
  316. */
  317. static int
  318. BTree_split(BTree *self, int index, BTree *next)
  319. {
  320. int next_size;
  321. Sized *child;
  322. if (index < 0 || index >= self->len)
  323. index = self->len / 2;
  324. next_size = self->len - index;
  325. ASSERT(index > 0, "split creates empty tree", -1);
  326. ASSERT(next_size > 0, "split creates empty tree", -1);
  327. next->data = BTree_Malloc(sizeof(BTreeItem) * next_size);
  328. if (!next->data)
  329. return -1;
  330. memcpy(next->data, self->data + index, sizeof(BTreeItem) * next_size);
  331. next->size = next_size; /* but don't set len until we succeed */
  332. /* Set next's firstbucket. self->firstbucket is still correct. */
  333. child = next->data[0].child;
  334. if (SameType_Check(self, child))
  335. {
  336. PER_USE_OR_RETURN(child, -1);
  337. next->firstbucket = BTREE(child)->firstbucket;
  338. PER_UNUSE(child);
  339. }
  340. else
  341. next->firstbucket = BUCKET(child);
  342. Py_INCREF(next->firstbucket);
  343. next->len = next_size;
  344. self->len = index;
  345. return PER_CHANGED(self) >= 0 ? 0 : -1;
  346. }
  347. /* Fwd decl -- BTree_grow and BTree_split_root reference each other. */
  348. static int BTree_grow(BTree *self, int index, int noval);
  349. /* Split the root. This is a little special because the root isn't a child
  350. * of anything else, and the root needs to retain its object identity. So
  351. * this routine moves the root's data into a new child, and splits the
  352. * latter. This leaves the root with two children.
  353. *
  354. * Return:
  355. * 0 OK
  356. * -1 error
  357. *
  358. * CAUTION: The caller must call PER_CHANGED on self.
  359. */
  360. static int
  361. BTree_split_root(BTree *self, int noval)
  362. {
  363. BTree *child;
  364. BTreeItem *d;
  365. /* Create a child BTree, and a new data vector for self. */
  366. child = BTREE(PyObject_CallObject(OBJECT(Py_TYPE(self)), NULL));
  367. if (!child)
  368. return -1;
  369. d = BTree_Malloc(sizeof(BTreeItem) * 2);
  370. if (!d) {
  371. Py_DECREF(child);
  372. return -1;
  373. }
  374. /* Move our data to new BTree. */
  375. child->size = self->size;
  376. child->len = self->len;
  377. child->data = self->data;
  378. child->firstbucket = self->firstbucket;
  379. Py_INCREF(child->firstbucket);
  380. /* Point self to child and split the child. */
  381. self->data = d;
  382. self->len = 1;
  383. self->size = 2;
  384. self->data[0].child = SIZED(child); /* transfers reference ownership */
  385. return BTree_grow(self, 0, noval);
  386. }
  387. /*
  388. ** BTree_grow
  389. **
  390. ** Grow a BTree
  391. **
  392. ** Arguments: self The BTree
  393. ** index self->data[index].child needs to be split. index
  394. ** must be 0 if self is empty (len == 0), and a new
  395. ** empty bucket is created then.
  396. ** noval Boolean; is this a set (true) or mapping (false)?
  397. **
  398. ** Returns: 0 on success
  399. ** -1 on failure
  400. **
  401. ** CAUTION: If self is empty on entry, this routine adds an empty bucket.
  402. ** That isn't a legitimate BTree; if the caller doesn't put something in
  403. ** in the bucket (say, because of a later error), the BTree must be cleared
  404. ** to get rid of the empty bucket.
  405. */
  406. static int
  407. BTree_grow(BTree *self, int index, int noval)
  408. {
  409. int i;
  410. Sized *v, *e = 0;
  411. BTreeItem *d;
  412. if (self->len == self->size)
  413. {
  414. if (self->size)
  415. {
  416. d = BTree_Realloc(self->data, sizeof(BTreeItem) * self->size * 2);
  417. if (d == NULL)
  418. return -1;
  419. self->data = d;
  420. self->size *= 2;
  421. }
  422. else
  423. {
  424. d = BTree_Malloc(sizeof(BTreeItem) * 2);
  425. if (d == NULL)
  426. return -1;
  427. self->data = d;
  428. self->size = 2;
  429. }
  430. }
  431. if (self->len)
  432. {
  433. long max_size = _max_internal_size(self);
  434. if (max_size < 0) return -1;
  435. d = self->data + index;
  436. v = d->child;
  437. /* Create a new object of the same type as the target value */
  438. e = (Sized *)PyObject_CallObject((PyObject *)Py_TYPE(v), NULL);
  439. if (e == NULL)
  440. return -1;
  441. UNLESS(PER_USE(v))
  442. {
  443. Py_DECREF(e);
  444. return -1;
  445. }
  446. /* Now split between the original (v) and the new (e) at the midpoint*/
  447. if (SameType_Check(self, v))
  448. i = BTree_split((BTree *)v, -1, (BTree *)e);
  449. else
  450. i = bucket_split((Bucket *)v, -1, (Bucket *)e);
  451. PER_ALLOW_DEACTIVATION(v);
  452. if (i < 0)
  453. {
  454. Py_DECREF(e);
  455. assert(PyErr_Occurred());
  456. return -1;
  457. }
  458. index++;
  459. d++;
  460. if (self->len > index) /* Shift up the old values one array slot */
  461. memmove(d+1, d, sizeof(BTreeItem)*(self->len-index));
  462. if (SameType_Check(self, v))
  463. {
  464. COPY_KEY(d->key, BTREE(e)->data->key);
  465. /* We take the unused reference from e, so there's no
  466. reason to INCREF!
  467. */
  468. /* INCREF_KEY(self->data[1].key); */
  469. }
  470. else
  471. {
  472. COPY_KEY(d->key, BUCKET(e)->keys[0]);
  473. INCREF_KEY(d->key);
  474. }
  475. d->child = e;
  476. self->len++;
  477. if (self->len >= max_size * 2) /* the root is huge */
  478. return BTree_split_root(self, noval);
  479. }
  480. else
  481. {
  482. /* The BTree is empty. Create an empty bucket. See CAUTION in
  483. * the comments preceding.
  484. */
  485. assert(index == 0);
  486. d = self->data;
  487. d->child = BTree_newBucket(self);
  488. if (d->child == NULL)
  489. return -1;
  490. self->len = 1;
  491. Py_INCREF(d->child);
  492. self->firstbucket = (Bucket *)d->child;
  493. }
  494. return 0;
  495. }
  496. /* Return the rightmost bucket reachable from following child pointers
  497. * from self. The caller gets a new reference to this bucket. Note that
  498. * bucket 'next' pointers are not followed: if self is an interior node
  499. * of a BTree, this returns the rightmost bucket in that node's subtree.
  500. * In case of error, returns NULL.
  501. *
  502. * self must not be a ghost; this isn't checked. The result may be a ghost.
  503. *
  504. * Pragmatics: Note that the rightmost bucket's last key is the largest
  505. * key in self's subtree.
  506. */
  507. static Bucket *
  508. BTree_lastBucket(BTree *self)
  509. {
  510. Sized *pchild;
  511. Bucket *result;
  512. UNLESS (self->data && self->len)
  513. {
  514. IndexError(-1); /* is this the best action to take? */
  515. return NULL;
  516. }
  517. pchild = self->data[self->len - 1].child;
  518. if (SameType_Check(self, pchild))
  519. {
  520. self = BTREE(pchild);
  521. PER_USE_OR_RETURN(self, NULL);
  522. result = BTree_lastBucket(self);
  523. PER_UNUSE(self);
  524. }
  525. else
  526. {
  527. Py_INCREF(pchild);
  528. result = BUCKET(pchild);
  529. }
  530. return result;
  531. }
  532. static int
  533. BTree_deleteNextBucket(BTree *self)
  534. {
  535. Bucket *b;
  536. UNLESS (PER_USE(self))
  537. return -1;
  538. b = BTree_lastBucket(self);
  539. if (b == NULL)
  540. goto err;
  541. if (Bucket_deleteNextBucket(b) < 0)
  542. goto err;
  543. Py_DECREF(b);
  544. PER_UNUSE(self);
  545. return 0;
  546. err:
  547. Py_XDECREF(b);
  548. PER_ALLOW_DEACTIVATION(self);
  549. return -1;
  550. }
  551. /*
  552. ** _BTree_clear
  553. **
  554. ** Clears out all of the values in the BTree (firstbucket, keys, and children);
  555. ** leaving self an empty BTree.
  556. **
  557. ** Arguments: self The BTree
  558. **
  559. ** Returns: 0 on success
  560. ** -1 on failure
  561. **
  562. ** Internal: Deallocation order is important. The danger is that a long
  563. ** list of buckets may get freed "at once" via decref'ing the first bucket,
  564. ** in which case a chain of consequenct Py_DECREF calls may blow the stack.
  565. ** Luckily, every bucket has a refcount of at least two, one due to being a
  566. ** BTree node's child, and another either because it's not the first bucket in
  567. ** the chain (so the preceding bucket points to it), or because firstbucket
  568. ** points to it. By clearing in the natural depth-first, left-to-right
  569. ** order, the BTree->bucket child pointers prevent Py_DECREF(bucket->next)
  570. ** calls from freeing bucket->next, and the maximum stack depth is equal
  571. ** to the height of the tree.
  572. **/
  573. static int
  574. _BTree_clear(BTree *self)
  575. {
  576. const int len = self->len;
  577. if (self->firstbucket)
  578. {
  579. /* Obscure: The first bucket is pointed to at least by
  580. * self->firstbucket and data[0].child of whichever BTree node it's
  581. * a child of. However, if persistence is enabled then the latter
  582. * BTree node may be a ghost at this point, and so its pointers "don't
  583. * count": we can only rely on self's pointers being intact.
  584. */
  585. #ifdef PERSISTENT
  586. ASSERT(Py_REFCNT(self->firstbucket) > 0,
  587. "Invalid firstbucket pointer", -1);
  588. #else
  589. ASSERT(Py_REFCNT(self->firstbucket) > 1,
  590. "Invalid firstbucket pointer", -1);
  591. #endif
  592. Py_DECREF(self->firstbucket);
  593. self->firstbucket = NULL;
  594. }
  595. if (self->data)
  596. {
  597. int i;
  598. if (len > 0) /* 0 is special because key 0 is trash */
  599. {
  600. Py_DECREF(self->data[0].child);
  601. }
  602. for (i = 1; i < len; i++)
  603. {
  604. #ifdef KEY_TYPE_IS_PYOBJECT
  605. DECREF_KEY(self->data[i].key);
  606. #endif
  607. Py_DECREF(self->data[i].child);
  608. }
  609. free(self->data);
  610. self->data = NULL;
  611. }
  612. self->len = self->size = 0;
  613. return 0;
  614. }
  615. /*
  616. Set (value != 0) or delete (value=0) a tree item.
  617. If unique is non-zero, then only change if the key is
  618. new.
  619. If noval is non-zero, then don't set a value (the tree
  620. is a set).
  621. Return:
  622. -1 error
  623. 0 successful, and number of entries didn't change
  624. >0 successful, and number of entries did change
  625. Internal
  626. There are two distinct return values > 0:
  627. 1 Successful, number of entries changed, but firstbucket did not go away.
  628. 2 Successful, number of entries changed, firstbucket did go away.
  629. This can only happen on a delete (value == NULL). The caller may
  630. need to change its own firstbucket pointer, and in any case *someone*
  631. needs to adjust the 'next' pointer of the bucket immediately preceding
  632. the bucket that went away (it needs to point to the bucket immediately
  633. following the bucket that went away).
  634. */
  635. static int
  636. _BTree_set(BTree *self, PyObject *keyarg, PyObject *value,
  637. int unique, int noval)
  638. {
  639. int changed = 0; /* did I mutate? */
  640. int min; /* index of child I searched */
  641. BTreeItem *d; /* self->data[min] */
  642. int childlength; /* len(self->data[min].child) */
  643. int status; /* our return value; and return value from callee */
  644. int self_was_empty; /* was self empty at entry? */
  645. KEY_TYPE key;
  646. int copied = 1;
  647. COPY_KEY_FROM_ARG(key, keyarg, copied);
  648. if (!copied)
  649. return -1;
  650. #ifdef KEY_CHECK_ON_SET
  651. if (value && !KEY_CHECK_ON_SET(keyarg))
  652. return -1;
  653. #endif
  654. PER_USE_OR_RETURN(self, -1);
  655. self_was_empty = self->len == 0;
  656. if (self_was_empty)
  657. {
  658. /* We're empty. Make room. */
  659. if (value)
  660. {
  661. if (BTree_grow(self, 0, noval) < 0)
  662. goto Error;
  663. }
  664. else
  665. {
  666. /* Can't delete a key from an empty BTree. */
  667. PyErr_SetObject(PyExc_KeyError, keyarg);
  668. goto Error;
  669. }
  670. }
  671. /* Find the right child to search, and hand the work off to it. */
  672. BTREE_SEARCH(min, self, key, goto Error);
  673. d = self->data + min;
  674. #ifdef PERSISTENT
  675. PER_READCURRENT(self, goto Error);
  676. #endif
  677. if (SameType_Check(self, d->child))
  678. status = _BTree_set(BTREE(d->child), keyarg, value, unique, noval);
  679. else
  680. {
  681. int bucket_changed = 0;
  682. status = _bucket_set(BUCKET(d->child), keyarg,
  683. value, unique, noval, &bucket_changed);
  684. #ifdef PERSISTENT
  685. /* If a BTree contains only a single bucket, BTree.__getstate__()
  686. * includes the bucket's entire state, and the bucket doesn't get
  687. * an oid of its own. So if we have a single oid-less bucket that
  688. * changed, it's *our* oid that should be marked as changed -- the
  689. * bucket doesn't have one.
  690. */
  691. if (bucket_changed
  692. && self->len == 1
  693. && self->data[0].child->oid == NULL)
  694. {
  695. changed = 1;
  696. }
  697. #endif
  698. }
  699. if (status == 0)
  700. goto Done;
  701. if (status < 0)
  702. goto Error;
  703. assert(status == 1 || status == 2);
  704. /* The child changed size. Get its new size. Note that since the tree
  705. * rooted at the child changed size, so did the tree rooted at self:
  706. * our status must be >= 1 too.
  707. */
  708. UNLESS(PER_USE(d->child))
  709. goto Error;
  710. childlength = d->child->len;
  711. PER_UNUSE(d->child);
  712. if (value)
  713. {
  714. /* A bucket got bigger -- if it's "too big", split it. */
  715. int toobig;
  716. assert(status == 1); /* can be 2 only on deletes */
  717. if (SameType_Check(self, d->child)) {
  718. long max_size = _max_internal_size(self);
  719. if (max_size < 0) return -1;
  720. toobig = childlength > max_size;
  721. }
  722. else {
  723. long max_size = _max_leaf_size(self);
  724. if (max_size < 0) return -1;
  725. toobig = childlength > max_size;
  726. }
  727. if (toobig) {
  728. if (BTree_grow(self, min, noval) < 0)
  729. goto Error;
  730. changed = 1; /* BTree_grow mutated self */
  731. }
  732. goto Done; /* and status still == 1 */
  733. }
  734. /* A bucket got smaller. This is much harder, and despite that we
  735. * don't try to rebalance the tree.
  736. */
  737. if (min && childlength)
  738. { /* We removed a key. but the node child is non-empty. If the
  739. deleted key is the node key, then update the node key using
  740. the smallest key of the node child.
  741. This doesn't apply to the 0th node, whos key is unused.
  742. */
  743. int _cmp = 1;
  744. TEST_KEY_SET_OR(_cmp, key, d->key) goto Error;
  745. if (_cmp == 0) /* Need to replace key with first key from child */
  746. {
  747. Bucket *bucket;
  748. if (SameType_Check(self, d->child))
  749. {
  750. UNLESS(PER_USE(d->child))
  751. goto Error;
  752. bucket = BTREE(d->child)->firstbucket;
  753. PER_UNUSE(d->child);
  754. }
  755. else
  756. bucket = BUCKET(d->child);
  757. UNLESS(PER_USE(bucket))
  758. goto Error;
  759. DECREF_KEY(d->key);
  760. COPY_KEY(d->key, bucket->keys[0]);
  761. INCREF_KEY(d->key);
  762. PER_UNUSE(bucket);
  763. if (PER_CHANGED(self) < 0)
  764. goto Error;
  765. }
  766. }
  767. if (status == 2)
  768. {
  769. /* The child must be a BTree because bucket.set never returns 2 */
  770. /* Two problems to solve: May have to adjust our own firstbucket,
  771. * and the bucket that went away needs to get unlinked.
  772. */
  773. if (min)
  774. {
  775. /* This wasn't our firstbucket, so no need to adjust ours (note
  776. * that it can't be the firstbucket of any node above us either).
  777. * Tell "the tree to the left" to do the unlinking.
  778. */
  779. if (BTree_deleteNextBucket(BTREE(d[-1].child)) < 0)
  780. goto Error;
  781. status = 1; /* we solved the child's firstbucket problem */
  782. }
  783. else
  784. {
  785. /* This was our firstbucket. Update to new firstbucket value. */
  786. Bucket *nextbucket;
  787. UNLESS(PER_USE(d->child))
  788. goto Error;
  789. nextbucket = BTREE(d->child)->firstbucket;
  790. PER_UNUSE(d->child);
  791. Py_XINCREF(nextbucket);
  792. Py_DECREF(self->firstbucket);
  793. self->firstbucket = nextbucket;
  794. changed = 1;
  795. /* The caller has to do the unlinking -- we can't. Also, since
  796. * it was our firstbucket, it may also be theirs.
  797. */
  798. assert(status == 2);
  799. }
  800. }
  801. /* If the child isn't empty, we're done! We did all that was possible for
  802. * us to do with the firstbucket problems the child gave us, and since the
  803. * child isn't empty don't create any new firstbucket problems of our own.
  804. */
  805. if (childlength)
  806. goto Done;
  807. /* The child became empty: we need to remove it from self->data.
  808. * But first, if we're a bottom-level node, we've got more bucket-fiddling
  809. * to set up.
  810. */
  811. if (! SameType_Check(self, d->child))
  812. {
  813. /* We're about to delete a bucket, so need to adjust bucket pointers. */
  814. if (min)
  815. {
  816. /* It's not our first bucket, so we can tell the previous
  817. * bucket to adjust its reference to it. It can't be anyone
  818. * else's first bucket either, so the caller needn't do anything.
  819. */
  820. if (Bucket_deleteNextBucket(BUCKET(d[-1].child)) < 0)
  821. goto Error;
  822. /* status should be 1, and already is: if it were 2, the
  823. * block above would have set it to 1 in its min != 0 branch.
  824. */
  825. assert(status == 1);
  826. }
  827. else
  828. {
  829. Bucket *nextbucket;
  830. /* It's our first bucket. We can't unlink it directly. */
  831. /* 'changed' will be set true by the deletion code following. */
  832. UNLESS(PER_USE(d->child))
  833. goto Error;
  834. nextbucket = BUCKET(d->child)->next;
  835. PER_UNUSE(d->child);
  836. Py_XINCREF(nextbucket);
  837. Py_DECREF(self->firstbucket);
  838. self->firstbucket = nextbucket;
  839. status = 2; /* we're giving our caller a new firstbucket problem */
  840. }
  841. }
  842. /* Remove the child from self->data. */
  843. Py_DECREF(d->child);
  844. #ifdef KEY_TYPE_IS_PYOBJECT
  845. if (min)
  846. {
  847. DECREF_KEY(d->key);
  848. }
  849. else if (self->len > 1)
  850. {
  851. /* We're deleting the first child of a BTree with more than one
  852. * child. The key at d+1 is about to be shifted into slot 0,
  853. * and hence never to be referenced again (the key in slot 0 is
  854. * trash).
  855. */
  856. DECREF_KEY((d+1)->key);
  857. }
  858. /* Else min==0 and len==1: we're emptying the BTree entirely, and
  859. * there is no key in need of decrefing.
  860. */
  861. #endif
  862. --self->len;
  863. if (min < self->len)
  864. memmove(d, d+1, (self->len - min) * sizeof(BTreeItem));
  865. changed = 1;
  866. Done:
  867. #ifdef PERSISTENT
  868. if (changed)
  869. {
  870. if (PER_CHANGED(self) < 0)
  871. goto Error;
  872. }
  873. #endif
  874. PER_UNUSE(self);
  875. return status;
  876. Error:
  877. assert(PyErr_Occurred());
  878. if (self_was_empty)
  879. {
  880. /* BTree_grow may have left the BTree in an invalid state. Make
  881. * sure the tree is a legitimate empty tree.
  882. */
  883. _BTree_clear(self);
  884. }
  885. PER_UNUSE(self);
  886. return -1;
  887. }
  888. /*
  889. ** BTree_setitem
  890. **
  891. ** wrapper for _BTree_set
  892. **
  893. ** Arguments: self The BTree
  894. ** key The key to insert
  895. ** v The value to insert
  896. **
  897. ** Returns -1 on failure
  898. ** 0 on success
  899. */
  900. static int
  901. BTree_setitem(BTree *self, PyObject *key, PyObject *v)
  902. {
  903. if (_BTree_set(self, key, v, 0, 0) < 0)
  904. return -1;
  905. return 0;
  906. }
  907. #ifdef PERSISTENT
  908. static PyObject *
  909. BTree__p_deactivate(BTree *self, PyObject *args, PyObject *keywords)
  910. {
  911. int ghostify = 1;
  912. PyObject *force = NULL;
  913. if (args && PyTuple_GET_SIZE(args) > 0)
  914. {
  915. PyErr_SetString(PyExc_TypeError,
  916. "_p_deactivate takes not positional arguments");
  917. return NULL;
  918. }
  919. if (keywords)
  920. {
  921. int size = PyDict_Size(keywords);
  922. force = PyDict_GetItemString(keywords, "force");
  923. if (force)
  924. size--;
  925. if (size)
  926. {
  927. PyErr_SetString(PyExc_TypeError,
  928. "_p_deactivate only accepts keyword arg force");
  929. return NULL;
  930. }
  931. }
  932. if (self->jar && self->oid)
  933. {
  934. ghostify = self->state == cPersistent_UPTODATE_STATE;
  935. if (!ghostify && force)
  936. {
  937. if (PyObject_IsTrue(force))
  938. ghostify = 1;
  939. if (PyErr_Occurred())
  940. return NULL;
  941. }
  942. if (ghostify)
  943. {
  944. if (_BTree_clear(self) < 0)
  945. return NULL;
  946. PER_GHOSTIFY(self);
  947. }
  948. }
  949. Py_INCREF(Py_None);
  950. return Py_None;
  951. }
  952. #endif
  953. static PyObject *
  954. BTree_clear(BTree *self)
  955. {
  956. UNLESS (PER_USE(self)) return NULL;
  957. if (self->len)
  958. {
  959. if (_BTree_clear(self) < 0)
  960. goto err;
  961. if (PER_CHANGED(self) < 0)
  962. goto err;
  963. }
  964. PER_UNUSE(self);
  965. Py_INCREF(Py_None);
  966. return Py_None;
  967. err:
  968. PER_UNUSE(self);
  969. return NULL;
  970. }
  971. /*
  972. * Return:
  973. *
  974. * For an empty BTree (self->len == 0), None.
  975. *
  976. * For a BTree with one child (self->len == 1), and that child is a bucket,
  977. * and that bucket has a NULL oid, a one-tuple containing a one-tuple
  978. * containing the bucket's state:
  979. *
  980. * (
  981. * (
  982. * child[0].__getstate__(),
  983. * ),
  984. * )
  985. *
  986. * Else a two-tuple. The first element is a tuple interleaving the BTree's
  987. * keys and direct children, of size 2*self->len - 1 (key[0] is unused and
  988. * is not saved). The second element is the firstbucket:
  989. *
  990. * (
  991. * (child[0], key[1], child[1], key[2], child[2], ...,
  992. * key[len-1], child[len-1]),
  993. * self->firstbucket
  994. * )
  995. *
  996. * In the above, key[i] means self->data[i].key, and similarly for child[i].
  997. */
  998. static PyObject *
  999. BTree_getstate(BTree *self)
  1000. {
  1001. PyObject *r = NULL;
  1002. PyObject *o;
  1003. int i, l;
  1004. UNLESS (PER_USE(self))
  1005. return NULL;
  1006. if (self->len)
  1007. {
  1008. r = PyTuple_New(self->len * 2 - 1);
  1009. if (r == NULL)
  1010. goto err;
  1011. if (self->len == 1
  1012. && Py_TYPE(self->data->child) != Py_TYPE(self)
  1013. #ifdef PERSISTENT
  1014. && BUCKET(self->data->child)->oid == NULL
  1015. #endif
  1016. )
  1017. {
  1018. /* We have just one bucket. Save its data directly. */
  1019. o = bucket_getstate((Bucket *)self->data->child);
  1020. if (o == NULL)
  1021. goto err;
  1022. PyTuple_SET_ITEM(r, 0, o);
  1023. ASSIGN(r, Py_BuildValue("(O)", r));
  1024. }
  1025. else
  1026. {
  1027. for (i=0, l=0; i < self->len; i++)
  1028. {
  1029. if (i)
  1030. {
  1031. COPY_KEY_TO_OBJECT(o, self->data[i].key);
  1032. PyTuple_SET_ITEM(r, l, o);
  1033. l++;
  1034. }
  1035. o = (PyObject *)self->data[i].child;
  1036. Py_INCREF(o);
  1037. PyTuple_SET_ITEM(r,l,o);
  1038. l++;
  1039. }
  1040. ASSIGN(r, Py_BuildValue("OO", r, self->firstbucket));
  1041. }
  1042. }
  1043. else
  1044. {
  1045. r = Py_None;
  1046. Py_INCREF(r);
  1047. }
  1048. PER_UNUSE(self);
  1049. return r;
  1050. err:
  1051. PER_UNUSE(self);
  1052. Py_XDECREF(r);
  1053. return NULL;
  1054. }
  1055. static int
  1056. _BTree_setstate(BTree *self, PyObject *state, int noval)
  1057. {
  1058. PyObject *items, *firstbucket = NULL;
  1059. BTreeItem *d;
  1060. int len, l, i, copied=1;
  1061. if (_BTree_clear(self) < 0)
  1062. return -1;
  1063. /* The state of a BTree can be one of the following:
  1064. None -- an empty BTree
  1065. A one-tuple -- a single bucket btree
  1066. A two-tuple -- a BTree with more than one bucket
  1067. See comments for BTree_getstate() for the details.
  1068. */
  1069. if (state == Py_None)
  1070. return 0;
  1071. if (!PyArg_ParseTuple(state, "O|O:__setstate__", &items, &firstbucket))
  1072. return -1;
  1073. if (!PyTuple_Check(items))
  1074. {
  1075. PyErr_SetString(PyExc_TypeError,
  1076. "tuple required for first state element");
  1077. return -1;
  1078. }
  1079. len = PyTuple_Size(items);
  1080. if (len < 0)
  1081. return -1;
  1082. len = (len + 1) / 2;
  1083. assert(len > 0); /* If the BTree is empty, it's state is None. */
  1084. assert(self->size == 0); /* We called _BTree_clear(). */
  1085. self->data = BTree_Malloc(sizeof(BTreeItem) * len);
  1086. if (self->data == NULL)
  1087. return -1;
  1088. self->size = len;
  1089. for (i = 0, d = self->data, l = 0; i < len; i++, d++)
  1090. {
  1091. PyObject *v;
  1092. if (i)
  1093. { /* skip the first key slot */
  1094. COPY_KEY_FROM_ARG(d->key, PyTuple_GET_ITEM(items, l), copied);
  1095. l++;
  1096. if (!copied)
  1097. return -1;
  1098. INCREF_KEY(d->key);
  1099. }
  1100. v = PyTuple_GET_ITEM(items, l);
  1101. if (PyTuple_Check(v))
  1102. {
  1103. /* Handle the special case in __getstate__() for a BTree
  1104. with a single bucket. */
  1105. d->child = BTree_newBucket(self);
  1106. if (!d->child)
  1107. return -1;
  1108. if (noval)
  1109. {
  1110. if (_set_setstate(BUCKET(d->child), v) < 0)
  1111. return -1;
  1112. }
  1113. else
  1114. {
  1115. if (_bucket_setstate(BUCKET(d->child), v) < 0)
  1116. return -1;
  1117. }
  1118. }
  1119. else
  1120. {
  1121. d->child = (Sized *)v;
  1122. Py_INCREF(v);
  1123. }
  1124. l++;
  1125. }
  1126. if (!firstbucket)
  1127. firstbucket = (PyObject *)self->data->child;
  1128. if (!PyObject_IsInstance(firstbucket, (PyObject *)
  1129. (noval ? &SetType : &BucketType)))
  1130. {
  1131. PyErr_SetString(PyExc_TypeError,
  1132. "No firstbucket in non-empty BTree");
  1133. return -1;
  1134. }
  1135. self->firstbucket = BUCKET(firstbucket);
  1136. Py_INCREF(firstbucket);
  1137. #ifndef PERSISTENT
  1138. /* firstbucket is also the child of some BTree node, but that node may
  1139. * be a ghost if persistence is enabled.
  1140. */
  1141. assert(Py_REFCNT(self->firstbucket) > 1);
  1142. #endif
  1143. self->len = len;
  1144. return 0;
  1145. }
  1146. static PyObject *
  1147. BTree_setstate(BTree *self, PyObject *arg)
  1148. {
  1149. int r;
  1150. PER_PREVENT_DEACTIVATION(self);
  1151. r = _BTree_setstate(self, arg, 0);
  1152. PER_UNUSE(self);
  1153. if (r < 0)
  1154. return NULL;
  1155. Py_INCREF(Py_None);
  1156. return Py_None;
  1157. }
  1158. #ifdef PERSISTENT
  1159. /* Recognize the special cases of a BTree that's empty or contains a single
  1160. * bucket. In the former case, return a borrowed reference to Py_None.
  1161. * In this single-bucket case, the bucket state is embedded directly in the
  1162. * BTree state, like so:
  1163. *
  1164. * (
  1165. * (
  1166. * thebucket.__getstate__(),
  1167. * ),
  1168. * )
  1169. *
  1170. * When this obtains, return a borrowed reference to thebucket.__getstate__().
  1171. * Else return NULL with an exception set. The exception should always be
  1172. * ConflictError then, but may be TypeError if the state makes no sense at all
  1173. * for a BTree (corrupted or hostile state).
  1174. */
  1175. PyObject *
  1176. get_bucket_state(PyObject *t)
  1177. {
  1178. if (t == Py_None)
  1179. return Py_None; /* an empty BTree */
  1180. if (! PyTuple_Check(t))
  1181. {
  1182. PyErr_SetString(PyExc_TypeError,
  1183. "_p_resolveConflict: expected tuple or None for state");
  1184. return NULL;
  1185. }
  1186. if (PyTuple_GET_SIZE(t) == 2)
  1187. {
  1188. /* A non-degenerate BTree. */
  1189. return merge_error(-1, -1, -1, 11);
  1190. }
  1191. /* We're in the one-bucket case. */
  1192. if (PyTuple_GET_SIZE(t) != 1)
  1193. {
  1194. PyErr_SetString(PyExc_TypeError,
  1195. "_p_resolveConflict: expected 1- or 2-tuple for state");
  1196. return NULL;
  1197. }
  1198. t = PyTuple_GET_ITEM(t, 0);
  1199. if (! PyTuple_Check(t) || PyTuple_GET_SIZE(t) != 1)
  1200. {
  1201. PyErr_SetString(PyExc_TypeError,
  1202. "_p_resolveConflict: expected 1-tuple containing "
  1203. "bucket state");
  1204. return NULL;
  1205. }
  1206. t = PyTuple_GET_ITEM(t, 0);
  1207. if (! PyTuple_Check(t))
  1208. {
  1209. PyErr_SetString(PyExc_TypeError,
  1210. "_p_resolveConflict: expected tuple for bucket state");
  1211. return NULL;
  1212. }
  1213. return t;
  1214. }
  1215. /* Tricky. The only kind of BTree conflict we can actually potentially
  1216. * resolve is the special case of a BTree containing a single bucket,
  1217. * in which case this becomes a fancy way of calling the bucket conflict
  1218. * resolution code.
  1219. */
  1220. static PyObject *
  1221. BTree__p_resolveConflict(BTree *self, PyObject *args)
  1222. {
  1223. PyObject *s[3];
  1224. PyObject *x, *y, *z;
  1225. if (!PyArg_ParseTuple(args, "OOO", &x, &y, &z))
  1226. return NULL;
  1227. s[0] = get_bucket_state(x);
  1228. if (s[0] == NULL)
  1229. return NULL;
  1230. s[1] = get_bucket_state(y);
  1231. if (s[1] == NULL)
  1232. return NULL;
  1233. s[2] = get_bucket_state(z);
  1234. if (s[2] == NULL)
  1235. return NULL;
  1236. if (PyObject_IsInstance((PyObject *)self, (PyObject *)&BTreeType))
  1237. x = _bucket__p_resolveConflict(OBJECT(&BucketType), s);
  1238. else
  1239. x = _bucket__p_resolveConflict(OBJECT(&SetType), s);
  1240. if (x == NULL)
  1241. return NULL;
  1242. return Py_BuildValue("((N))", x);
  1243. }
  1244. #endif
  1245. /*
  1246. BTree_findRangeEnd -- Find one end, expressed as a bucket and
  1247. position, for a range search.
  1248. If low, return bucket and index of the smallest item >= key,
  1249. otherwise return bucket and index of the largest item <= key.
  1250. If exclude_equal, exact matches aren't acceptable; if one is found,
  1251. move right if low, or left if !low (this is for range searches exclusive
  1252. of an endpoint).
  1253. Return:
  1254. -1 Error; offset and bucket unchanged
  1255. 0 Not found; offset and bucket unchanged
  1256. 1 Correct bucket and offset stored; the caller owns a new reference
  1257. to the bucket.
  1258. Internal:
  1259. We do binary searches in BTree nodes downward, at each step following
  1260. C(i) where K(i) <= key < K(i+1). As always, K(i) <= C(i) < K(i+1) too.
  1261. (See Maintainer.txt for the meaning of that notation.) That eventually
  1262. leads to a bucket where we do Bucket_findRangeEnd. That usually works,
  1263. but there are two cases where it can fail to find the correct answer:
  1264. 1. On a low search, we find a bucket with keys >= K(i), but that doesn't
  1265. imply there are keys in the bucket >= key. For example, suppose
  1266. a bucket has keys in 1..100, its successor's keys are in 200..300, and
  1267. we're doing a low search on 150. We'll end up in the first bucket,
  1268. but there are no keys >= 150 in it. K(i+1) > key, though, and all
  1269. the keys in C(i+1) >= K(i+1) > key, so the first key in the next
  1270. bucket (if any) is the correct result. This is easy to find by
  1271. following the bucket 'next' pointer.
  1272. 2. On a high search, again that the keys in the bucket are >= K(i)
  1273. doesn't imply that any key in the bucket is <= key, but it's harder
  1274. for this to fail (and an earlier version of this routine didn't
  1275. catch it): if K(i) itself is in the bucket, it works (then
  1276. K(i) <= key is *a* key in the bucket that's in the desired range).
  1277. But when keys get deleted from buckets, they aren't also deleted from
  1278. BTree nodes, so there's no guarantee that K(i) is in the bucket.
  1279. For example, delete the smallest key S from some bucket, and S
  1280. remains in the interior BTree nodes. Do a high search for S, and
  1281. the BTree nodes direct the search to the bucket S used to be in,
  1282. but all keys remaining in that bucket are > S. The largest key in
  1283. the *preceding* bucket (if any) is < K(i), though, and K(i) <= key,
  1284. so the largest key in the preceding bucket is < key and so is the
  1285. proper result.
  1286. This is harder to get at efficiently, as buckets are linked only in
  1287. the increasing direction. While we're searching downward,
  1288. deepest_smaller is set to the node deepest in the tree where
  1289. we *could* have gone to the left of C(i). The rightmost bucket in
  1290. deepest_smaller's subtree is the bucket preceding the bucket we find
  1291. at first. This is clumsy to get at, but efficient.
  1292. */
  1293. static int
  1294. BTree_findRangeEnd(BTree *self, PyObject *keyarg, int low, int exclude_equal,
  1295. Bucket **bucket, int *offset)
  1296. {
  1297. Sized *deepest_smaller = NULL; /* last possibility to move left */
  1298. int deepest_smaller_is_btree = 0; /* Boolean; if false, it's a bucket */
  1299. Bucket *pbucket;
  1300. int self_got_rebound = 0; /* Boolean; when true, deactivate self */
  1301. int result = -1; /* Until proven innocent */
  1302. int i;
  1303. KEY_TYPE key;
  1304. int copied = 1;
  1305. COPY_KEY_FROM_ARG(key, keyarg, copied);
  1306. UNLESS (copied)
  1307. return -1;
  1308. /* We don't need to: PER_USE_OR_RETURN(self, -1);
  1309. because the caller does. */
  1310. UNLESS (self->data && self->len)
  1311. return 0;
  1312. /* Search downward until hitting a bucket, stored in pbucket. */
  1313. for (;;)
  1314. {
  1315. Sized *pchild;
  1316. int pchild_is_btree;
  1317. BTREE_SEARCH(i, self, key, goto Done);
  1318. pchild = self->data[i].child;
  1319. pchild_is_btree = SameType_Check(self, pchild);
  1320. if (i)
  1321. {
  1322. deepest_smaller = self->data[i-1].child;
  1323. deepest_smaller_is_btree = pchild_is_btree;
  1324. }
  1325. if (pchild_is_btree)
  1326. {
  1327. if (self_got_rebound)
  1328. {
  1329. PER_UNUSE(self);
  1330. }
  1331. self = BTREE(pchild);
  1332. self_got_rebound = 1;
  1333. PER_USE_OR_RETURN(self, -1);
  1334. }
  1335. else
  1336. {
  1337. pbucket = BUCKET(pchild);
  1338. break;
  1339. }
  1340. }
  1341. /* Search the bucket for a suitable key. */
  1342. i = Bucket_findRangeEnd(pbucket, keyarg, low, exclude_equal, offset);
  1343. if (i < 0)
  1344. goto Done;
  1345. if (i > 0)
  1346. {
  1347. Py_INCREF(pbucket);
  1348. *bucket = pbucket;
  1349. result = 1;
  1350. goto Done;
  1351. }
  1352. /* This may be one of the two difficult cases detailed in the comments. */
  1353. if (low)
  1354. {
  1355. Bucket *next;
  1356. UNLESS(PER_USE(pbucket)) goto Done;
  1357. next = pbucket->next;
  1358. if (next) {
  1359. result = 1;
  1360. Py_INCREF(next);
  1361. *bucket = next;
  1362. *offset = 0;
  1363. }
  1364. else
  1365. result = 0;
  1366. PER_UNUSE(pbucket);
  1367. }
  1368. /* High-end search: if it's possible to go left, do so. */
  1369. else if (deepest_smaller)
  1370. {
  1371. if (deepest_smaller_is_btree)
  1372. {
  1373. UNLESS(PER_USE(deepest_smaller))
  1374. goto Done;
  1375. /* We own the reference this returns. */
  1376. pbucket = BTree_lastBucket(BTREE(deepest_smaller));
  1377. PER_UNUSE(deepest_smaller);
  1378. if (pbucket == NULL)
  1379. goto Done; /* error */
  1380. }
  1381. else
  1382. {
  1383. pbucket = BUCKET(deepest_smaller);
  1384. Py_INCREF(pbucket);
  1385. }
  1386. UNLESS(PER_USE(pbucket))
  1387. goto Done;
  1388. result = 1;
  1389. *bucket = pbucket; /* transfer ownership to caller */
  1390. *offset = pbucket->len - 1;
  1391. PER_UNUSE(pbucket);
  1392. }
  1393. else
  1394. result = 0; /* simply not found */
  1395. Done:
  1396. if (self_got_rebound)
  1397. {
  1398. PER_UNUSE(self);
  1399. }
  1400. return result;
  1401. }
  1402. static PyObject *
  1403. BTree_maxminKey(BTree *self, PyObject *args, int min)
  1404. {
  1405. PyObject *key=0;
  1406. Bucket *bucket = NULL;
  1407. int offset, rc;
  1408. int empty_tree = 1;
  1409. UNLESS (PyArg_ParseTuple(args, "|O", &key))
  1410. return NULL;
  1411. UNLESS (PER_USE(self))
  1412. return NULL;
  1413. UNLESS (self->data && self->len)
  1414. goto empty;
  1415. /* Find the range */
  1416. if (key && key != Py_None)
  1417. {
  1418. if ((rc = BTree_findRangeEnd(self, key, min, 0, &bucket, &offset)) <= 0)
  1419. {
  1420. if (rc < 0)
  1421. goto err;
  1422. empty_tree = 0;
  1423. goto empty;
  1424. }
  1425. PER_UNUSE(self);
  1426. UNLESS (PER_USE(bucket))
  1427. {
  1428. Py_DECREF(bucket);
  1429. return NULL;
  1430. }
  1431. }
  1432. else if (min)
  1433. {
  1434. bucket = self->firstbucket;
  1435. PER_UNUSE(self);
  1436. PER_USE_OR_RETURN(bucket, NULL);
  1437. Py_INCREF(bucket);
  1438. offset = 0;
  1439. }
  1440. else
  1441. {
  1442. bucket = BTree_lastBucket(self);
  1443. PER_UNUSE(self);
  1444. UNLESS (PER_USE(bucket))
  1445. {
  1446. Py_DECREF(bucket);
  1447. return NULL;
  1448. }
  1449. assert(bucket->len);
  1450. offset = bucket->len - 1;
  1451. }
  1452. COPY_KEY_TO_OBJECT(key, bucket->keys[offset]);
  1453. PER_UNUSE(bucket);
  1454. Py_DECREF(bucket);
  1455. return key;
  1456. empty:
  1457. PyErr_SetString(PyExc_ValueError,
  1458. empty_tree ? "empty tree" :
  1459. "no key satisfies the conditions");
  1460. err:
  1461. PER_UNUSE(self);
  1462. if (bucket)
  1463. {
  1464. PER_UNUSE(bucket);
  1465. Py_DECREF(bucket);
  1466. }
  1467. return NULL;
  1468. }
  1469. static PyObject *
  1470. BTree_minKey(BTree *self, PyObject *args)
  1471. {
  1472. return BTree_maxminKey(self, args, 1);
  1473. }
  1474. static PyObject *
  1475. BTree_maxKey(BTree *self, PyObject *args)
  1476. {
  1477. return BTree_maxminKey(self, args, 0);
  1478. }
  1479. /*
  1480. ** BTree_rangeSearch
  1481. **
  1482. ** Generates a BTreeItems object based on the two indexes passed in,
  1483. ** being the range between them.
  1484. **
  1485. */
  1486. static PyObject *
  1487. BTree_rangeSearch(BTree *self, PyObject *args, PyObject *kw, char type)
  1488. {
  1489. PyObject *min = Py_None;
  1490. PyObject *max = Py_None;
  1491. int excludemin = 0;
  1492. int excludemax = 0;
  1493. int rc;
  1494. Bucket *lowbucket = NULL;
  1495. Bucket *highbucket = NULL;
  1496. int lowoffset;
  1497. int highoffset;
  1498. PyObject *result;
  1499. if (args)
  1500. {
  1501. if (! PyArg_ParseTupleAndKeywords(args, kw, "|OOii", search_keywords,
  1502. &min,
  1503. &max,
  1504. &excludemin,
  1505. &excludemax))
  1506. return NULL;
  1507. }
  1508. UNLESS (PER_USE(self))
  1509. return NULL;
  1510. UNLESS (self->data && self->len)
  1511. goto empty;
  1512. /* Find the low range */
  1513. if (min != Py_None)
  1514. {
  1515. if ((rc = BTree_findRangeEnd(self, min, 1, excludemin,
  1516. &lowbucket, &lowoffset)) <= 0)
  1517. {
  1518. if (rc < 0)
  1519. goto err;
  1520. goto empty;
  1521. }
  1522. }
  1523. else
  1524. {
  1525. lowbucket = self->firstbucket;
  1526. lowoffset = 0;
  1527. if (excludemin)
  1528. {
  1529. int bucketlen;
  1530. UNLESS (PER_USE(lowbucket))
  1531. goto err;
  1532. bucketlen = lowbucket->len;
  1533. PER_UNUSE(lowbucket);
  1534. if (bucketlen > 1)
  1535. lowoffset = 1;
  1536. else if (self->len < 2)
  1537. goto empty;
  1538. else
  1539. { /* move to first item in next bucket */
  1540. Bucket *next;
  1541. UNLESS (PER_USE(lowbucket))
  1542. goto err;
  1543. next = lowbucket->next;
  1544. PER_UNUSE(lowbucket);
  1545. assert(next != NULL);
  1546. lowbucket = next;
  1547. /* and lowoffset is still 0 */
  1548. assert(lowoffset == 0);
  1549. }
  1550. }
  1551. Py_INCREF(lowbucket);
  1552. }
  1553. /* Find the high range */
  1554. if (max != Py_None)
  1555. {
  1556. if ((rc = BTree_findRangeEnd(self, max, 0, excludemax,
  1557. &highbucket, &highoffset)) <= 0)
  1558. {
  1559. Py_DECREF(lowbucket);
  1560. if (rc < 0)
  1561. goto err;
  1562. goto empty;
  1563. }
  1564. }
  1565. else
  1566. {
  1567. int bucketlen;
  1568. highbucket = BTree_lastBucket(self);
  1569. assert(highbucket != NULL); /* we know self isn't empty */
  1570. UNLESS (PER_USE(highbucket))
  1571. goto err_and_decref_buckets;
  1572. bucketlen = highbucket->len;
  1573. PER_UNUSE(highbucket);
  1574. highoffset = bucketlen - 1;
  1575. if (excludemax)
  1576. {
  1577. if (highoffset > 0)
  1578. --highoffset;
  1579. else if (self->len < 2)
  1580. goto empty_and_decref_buckets;
  1581. else /* move to last item of preceding bucket */
  1582. {
  1583. int status;
  1584. assert(highbucket != self->firstbucket);
  1585. Py_DECREF(highbucket);
  1586. status = PreviousBucket(&highbucket, self->firstbucket);
  1587. if (status < 0)
  1588. {
  1589. Py_DECREF(lowbucket);
  1590. goto err;
  1591. }
  1592. assert(status > 0);
  1593. Py_INCREF(highbucket);
  1594. UNLESS (PER_USE(highbucket))
  1595. goto err_and_decref_buckets;
  1596. highoffset = highbucket->len - 1;
  1597. PER_UNUSE(highbucket);
  1598. }
  1599. }
  1600. assert(highoffset >= 0);
  1601. }
  1602. /* It's still possible that the range is empty, even if min < max. For
  1603. * example, if min=3 and max=4, and 3 and 4 aren't in the BTree, but 2 and
  1604. * 5 are, then the low position points to the 5 now and the high position
  1605. * points to the 2 now. They're not necessarily even in the same bucket,
  1606. * so there's no trick we can play with pointer compares to get out
  1607. * cheap in general.
  1608. */
  1609. if (lowbucket == highbucket && lowoffset > highoffset)
  1610. goto empty_and_decref_buckets; /* definitely empty */
  1611. /* The buckets differ, or they're the same and the offsets show a non-
  1612. * empty range.
  1613. */
  1614. if (min != Py_None && max != Py_None && /* both args user-supplied */
  1615. lowbucket != highbucket) /* and different buckets */
  1616. {
  1617. KEY_TYPE first;
  1618. KEY_TYPE last;
  1619. int cmp;
  1620. /* Have to check the hard way: see how the endpoints compare. */
  1621. UNLESS (PER_USE(lowbucket))
  1622. goto err_and_decref_buckets;
  1623. COPY_KEY(first, lowbucket->keys[lowoffset]);
  1624. PER_UNUSE(lowbucket);
  1625. UNLESS (PER_USE(highbucket))
  1626. goto err_and_decref_buckets;
  1627. COPY_KEY(last, highbucket->keys[highoffset]);
  1628. PER_UNUSE(highbucket);
  1629. TEST_KEY_SET_OR(cmp, first, last)
  1630. goto err_and_decref_buckets;
  1631. if (cmp > 0)
  1632. goto empty_and_decref_buckets;
  1633. }
  1634. PER_UNUSE(self);
  1635. result = newBTreeItems(type, lowbucket, lowoffset, highbucket, highoffset);
  1636. Py_DECREF(lowbucket);
  1637. Py_DECREF(highbucket);
  1638. return result;
  1639. err_and_decref_buckets:
  1640. Py_DECREF(lowbucket);
  1641. Py_DECREF(highbucket);
  1642. err:
  1643. PER_UNUSE(self);
  1644. return NULL;
  1645. empty_and_decref_buckets:
  1646. Py_DECREF(lowbucket);
  1647. Py_DECREF(highbucket);
  1648. empty:
  1649. PER_UNUSE(self);
  1650. return newBTreeItems(type, 0, 0, 0, 0);
  1651. }
  1652. /*
  1653. ** BTree_keys
  1654. */
  1655. static PyObject *
  1656. BTree_keys(BTree *self, PyObject *args, PyObject *kw)
  1657. {
  1658. return BTree_rangeSearch(self, args, kw, 'k');
  1659. }
  1660. /*
  1661. ** BTree_values
  1662. */
  1663. static PyObject *
  1664. BTree_values(BTree *self, PyObject *args, PyObject *kw)
  1665. {
  1666. return BTree_rangeSearch(self, args, kw, 'v');
  1667. }
  1668. /*
  1669. ** BTree_items
  1670. */
  1671. static PyObject *
  1672. BTree_items(BTree *self, PyObject *args, PyObject *kw)
  1673. {
  1674. return BTree_rangeSearch(self, args, kw, 'i');
  1675. }
  1676. static PyObject *
  1677. BTree_byValue(BTree *self, PyObject *omin)
  1678. {
  1679. PyObject *r=0, *o=0, *item=0;
  1680. VALUE_TYPE min;
  1681. VALUE_TYPE v;
  1682. int copied=1;
  1683. SetIteration it = {0, 0, 1};
  1684. UNLESS (PER_USE(self))
  1685. return NULL;
  1686. COPY_VALUE_FROM_ARG(min, omin, copied);
  1687. UNLESS(copied)
  1688. return NULL;
  1689. UNLESS (r=PyList_New(0))
  1690. goto err;
  1691. it.set=BTree_rangeSearch(self, NULL, NULL, 'i');
  1692. UNLESS(it.set)
  1693. goto err;
  1694. if (nextBTreeItems(&it) < 0)
  1695. goto err;
  1696. while (it.position >= 0)
  1697. {
  1698. if (TEST_VALUE(it.value, min) >= 0)
  1699. {
  1700. UNLESS (item = PyTuple_New(2))
  1701. goto err;
  1702. COPY_KEY_TO_OBJECT(o, it.key);
  1703. UNLESS (o)
  1704. goto err;
  1705. PyTuple_SET_ITEM(item, 1, o);
  1706. COPY_VALUE(v, it.value);
  1707. NORMALIZE_VALUE(v, min);
  1708. COPY_VALUE_TO_OBJECT(o, v);
  1709. DECREF_VALUE(v);
  1710. UNLESS (o)
  1711. goto err;
  1712. PyTuple_SET_ITEM(item, 0, o);
  1713. if (PyList_Append(r, item) < 0)
  1714. goto err;
  1715. Py_DECREF(item);
  1716. item = 0;
  1717. }
  1718. if (nextBTreeItems(&it) < 0)
  1719. goto err;
  1720. }
  1721. item=PyObject_GetAttr(r,sort_str);
  1722. UNLESS (item)
  1723. goto err;
  1724. ASSIGN(item, PyObject_CallObject(item, NULL));
  1725. UNLESS (item)
  1726. goto err;
  1727. ASSIGN(item, PyObject_GetAttr(r, reverse_str));
  1728. UNLESS (item)
  1729. goto err;
  1730. ASSIGN(item, PyObject_CallObject(item, NULL));
  1731. UNLESS (item)
  1732. goto err;
  1733. Py_DECREF(item);
  1734. finiSetIteration(&it);
  1735. PER_UNUSE(self);
  1736. return r;
  1737. err:
  1738. PER_UNUSE(self);
  1739. Py_XDECREF(r);
  1740. finiSetIteration(&it);
  1741. Py_XDECREF(item);
  1742. return NULL;
  1743. }
  1744. /*
  1745. ** BTree_getm
  1746. */
  1747. static PyObject *
  1748. BTree_getm(BTree *self, PyObject *args)
  1749. {
  1750. PyObject *key, *d=Py_None, *r;
  1751. UNLESS (PyArg_ParseTuple(args, "O|O", &key, &d))
  1752. return NULL;
  1753. if ((r=_BTree_get(self, key, 0, _BGET_REPLACE_TYPE_ERROR)))
  1754. return r;
  1755. UNLESS (PyErr_ExceptionMatches(PyExc_KeyError))
  1756. return NULL;
  1757. PyErr_Clear();
  1758. Py_INCREF(d);
  1759. return d;
  1760. }
  1761. static PyObject *
  1762. BTree_has_key(BTree *self, PyObject *key)
  1763. {
  1764. return _BTree_get(self, key, 1, _BGET_REPLACE_TYPE_ERROR);
  1765. }
  1766. static PyObject *
  1767. BTree_setdefault(BTree *self, PyObject *args)
  1768. {
  1769. PyObject *key;
  1770. PyObject *failobj; /* default */
  1771. PyObject *value; /* return value */
  1772. if (! PyArg_UnpackTuple(args, "setdefault", 2, 2, &key, &failobj))
  1773. return NULL;
  1774. value = _BTree_get(self, key, 0, _BGET_ALLOW_TYPE_ERROR);
  1775. if (value != NULL)
  1776. return value;
  1777. /* The key isn't in the tree. If that's not due to a KeyError exception,
  1778. * pass back the unexpected exception.
  1779. */
  1780. if (! PyErr_ExceptionMatches(PyExc_KeyError))
  1781. return NULL;
  1782. PyErr_Clear();
  1783. /* Associate `key` with `failobj` in the tree, and return `failobj`. */
  1784. value = failobj;
  1785. if (_BTree_set(self, key, failobj, 0, 0) < 0)
  1786. value = NULL;
  1787. Py_XINCREF(value);
  1788. return value;
  1789. }
  1790. /* forward declaration */
  1791. static Py_ssize_t
  1792. BTree_length_or_nonzero(BTree *self, int nonzero);
  1793. static PyObject *
  1794. BTree_pop(BTree *self, PyObject *args)
  1795. {
  1796. PyObject *key;
  1797. PyObject *failobj = NULL; /* default */
  1798. PyObject *value; /* return value */
  1799. if (! PyArg_UnpackTuple(args, "pop", 1, 2, &key, &failobj))
  1800. return NULL;
  1801. value = _BTree_get(self, key, 0, _BGET_ALLOW_TYPE_ERROR);
  1802. if (value != NULL)
  1803. {
  1804. /* Delete key and associated value. */
  1805. if (_BTree_set(self, key, NULL, 0, 0) < 0)
  1806. {
  1807. Py_DECREF(value);
  1808. return NULL;;
  1809. }
  1810. return value;
  1811. }
  1812. /* The key isn't in the tree. If that's not due to a KeyError exception,
  1813. * pass back the unexpected exception.
  1814. */
  1815. if (! PyErr_ExceptionMatches(PyExc_KeyError))
  1816. return NULL;
  1817. if (failobj != NULL)
  1818. {
  1819. /* Clear the KeyError and return the explicit default. */
  1820. PyErr_Clear();
  1821. Py_INCREF(failobj);
  1822. return failobj;
  1823. }
  1824. /* No default given. The only difference in this case is the error
  1825. * message, which depends on whether the tree is empty.
  1826. */
  1827. if (BTree_length_or_nonzero(self, 1) == 0) /* tree is empty */
  1828. PyErr_SetString(PyExc_KeyError, "pop(): BTree is empty");
  1829. return NULL;
  1830. }
  1831. /* Search BTree self for key. This is the sq_contains slot of the
  1832. * PySequenceMethods.
  1833. *
  1834. * Return:
  1835. * -1 error
  1836. * 0 not found
  1837. * 1 found
  1838. */
  1839. static int
  1840. BTree_contains(BTree *self, PyObject *key)
  1841. {
  1842. PyObject *asobj = _BTree_get(self, key, 1, _BGET_REPLACE_TYPE_ERROR);
  1843. int result = -1;
  1844. if (asobj != NULL)
  1845. {
  1846. result = INT_AS_LONG(asobj) ? 1 : 0;
  1847. Py_DECREF(asobj);
  1848. }
  1849. else if (PyErr_ExceptionMatches(PyExc_KeyError))
  1850. {
  1851. PyErr_Clear();
  1852. result = 0;
  1853. }
  1854. return result;
  1855. }
  1856. static PyObject *
  1857. BTree_addUnique(BTree *self, PyObject *args)
  1858. {
  1859. int grew;
  1860. PyObject *key, *v;
  1861. UNLESS (PyArg_ParseTuple(args, "OO", &key, &v))
  1862. return NULL;
  1863. if ((grew=_BTree_set(self, key, v, 1, 0)) < 0)
  1864. return NULL;
  1865. return INT_FROM_LONG(grew);
  1866. }
  1867. /**************************************************************************/
  1868. /* Iterator support. */
  1869. /* A helper to build all the iterators for BTrees and TreeSets.
  1870. * If args is NULL, the iterator spans the entire structure. Else it's an
  1871. * argument tuple, with optional low and high arguments.
  1872. * kind is 'k', 'v' or 'i'.
  1873. * Returns a BTreeIter object, or NULL if error.
  1874. */
  1875. static PyObject *
  1876. buildBTreeIter(BTree *self, PyObject *args, PyObject *kw, char kind)
  1877. {
  1878. BTreeIter *result = NULL;
  1879. BTreeItems *items = (BTreeItems *)BTree_rangeSearch(self, args, kw, kind);
  1880. if (items)
  1881. {
  1882. result = BTreeIter_new(items);
  1883. Py_DECREF(items);
  1884. }
  1885. return (PyObject *)result;
  1886. }
  1887. /* The implementation of iter(BTree_or_TreeSet); the BTree tp_iter slot. */
  1888. static PyObject *
  1889. BTree_getiter(BTree *self)
  1890. {
  1891. return buildBTreeIter(self, NULL, NULL, 'k');
  1892. }
  1893. /* The implementation of BTree.iterkeys(). */
  1894. static PyObject *
  1895. BTree_iterkeys(BTree *self, PyObject *args, PyObject *kw)
  1896. {
  1897. return buildBTreeIter(self, args, kw, 'k');
  1898. }
  1899. /* The implementation of BTree.itervalues(). */
  1900. static PyObject *
  1901. BTree_itervalues(BTree *self, PyObject *args, PyObject *kw)
  1902. {
  1903. return buildBTreeIter(self, args, kw, 'v');
  1904. }
  1905. /* The implementation of BTree.iteritems(). */
  1906. static PyObject *
  1907. BTree_iteritems(BTree *self, PyObject *args, PyObject *kw)
  1908. {
  1909. return buildBTreeIter(self, args, kw, 'i');
  1910. }
  1911. /* End of iterator support. */
  1912. /* Caution: Even though the _firstbucket attribute is read-only, a program
  1913. could do arbitrary damage to the btree internals. For example, it could
  1914. call clear() on a bucket inside a BTree.
  1915. We need to decide if the convenience for inspecting BTrees is worth
  1916. the risk.
  1917. */
  1918. static struct PyMemberDef BTree_members[] = {
  1919. {"_firstbucket", T_OBJECT, offsetof(BTree, firstbucket), READONLY},
  1920. {NULL}
  1921. };
  1922. static struct PyMethodDef BTree_methods[] = {
  1923. {"__getstate__", (PyCFunction) BTree_getstate, METH_NOARGS,
  1924. "__getstate__() -> state\n\n"
  1925. "Return the picklable state of the BTree."},
  1926. {"__setstate__", (PyCFunction) BTree_setstate, METH_O,
  1927. "__setstate__(state)\n\n"
  1928. "Set the state of the BTree."},
  1929. {"has_key", (PyCFunction) BTree_has_key, METH_O,
  1930. "has_key(key)\n\n"
  1931. "Return true if the BTree contains the given key."},
  1932. {"keys", (PyCFunction) BTree_keys, METH_VARARGS | METH_KEYWORDS,
  1933. "keys([min, max]) -> list of keys\n\n"
  1934. "Returns the keys of the BTree. If min and max are supplied, only\n"
  1935. "keys greater than min and less than max are returned."},
  1936. {"values", (PyCFunction) BTree_values, METH_VARARGS | METH_KEYWORDS,
  1937. "values([min, max]) -> list of values\n\n"
  1938. "Returns the values of the BTree. If min and max are supplied, only\n"
  1939. "values corresponding to keys greater than min and less than max are\n"
  1940. "returned."},
  1941. {"items", (PyCFunction) BTree_items, METH_VARARGS | METH_KEYWORDS,
  1942. "items([min, max]) -> -- list of key, value pairs\n\n"
  1943. "Returns the items of the BTree. If min and max are supplied, only\n"
  1944. "items with keys greater than min and less than max are returned."},
  1945. {"byValue", (PyCFunction) BTree_byValue, METH_O,
  1946. "byValue(min) -> list of value, key pairs\n\n"
  1947. "Returns list of value, key pairs where the value is >= min. The\n"
  1948. "list is sorted by value. Note that items() returns keys in the\n"
  1949. "opposite order."},
  1950. {"get", (PyCFunction) BTree_getm, METH_VARARGS,
  1951. "get(key[, default=None]) -> Value for key or default\n\n"
  1952. "Return the value or the default if the key is not found."},
  1953. {"setdefault", (PyCFunction) BTree_setdefault, METH_VARARGS,
  1954. "D.setdefault(k, d) -> D.get(k, d), also set D[k]=d if k not in D.\n\n"
  1955. "Return the value like get() except that if key is missing, d is both\n"
  1956. "returned and inserted into the BTree as the value of k."},
  1957. {"pop", (PyCFunction) BTree_pop, METH_VARARGS,
  1958. "D.pop(k[, d]) -> v, remove key and return the corresponding value.\n\n"
  1959. "If key is not found, d is returned if given, otherwise KeyError\n"
  1960. "is raised."},
  1961. {"maxKey", (PyCFunction) BTree_maxKey, METH_VARARGS,
  1962. "maxKey([max]) -> key\n\n"
  1963. "Return the largest key in the BTree. If max is specified, return\n"
  1964. "the largest key <= max."},
  1965. {"minKey", (PyCFunction) BTree_minKey, METH_VARARGS,
  1966. "minKey([mi]) -> key\n\n"
  1967. "Return the smallest key in the BTree. If min is specified, return\n"
  1968. "the smallest key >= min."},
  1969. {"clear", (PyCFunction) BTree_clear, METH_NOARGS,
  1970. "clear()\n\nRemove all of the items from the BTree."},
  1971. {"insert", (PyCFunction)BTree_addUnique, METH_VARARGS,
  1972. "insert(key, value) -> 0 or 1\n\n"
  1973. "Add an item if the key is not already used. Return 1 if the item was\n"
  1974. "added, or 0 otherwise."},
  1975. {"update", (PyCFunction) Mapping_update, METH_O,
  1976. "update(collection)\n\n Add the items from the given collection."},
  1977. {"iterkeys", (PyCFunction) BTree_iterkeys, METH_VARARGS | METH_KEYWORDS,
  1978. "B.iterkeys([min[,max]]) -> an iterator over the keys of B"},
  1979. {"itervalues", (PyCFunction) BTree_itervalues, METH_VARARGS | METH_KEYWORDS,
  1980. "B.itervalues([min[,max]]) -> an iterator over the values of B"},
  1981. {"iteritems", (PyCFunction) BTree_iteritems, METH_VARARGS | METH_KEYWORDS,
  1982. "B.iteritems([min[,max]]) -> an iterator over the (key, value) "
  1983. "items of B"},
  1984. {"_check", (PyCFunction) BTree_check, METH_NOARGS,
  1985. "Perform sanity check on BTree, and raise exception if flawed."},
  1986. #ifdef PERSISTENT
  1987. {"_p_resolveConflict",
  1988. (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
  1989. "_p_resolveConflict() -- Reinitialize from a newly created copy"},
  1990. {"_p_deactivate",
  1991. (PyCFunction) BTree__p_deactivate, METH_VARARGS | METH_KEYWORDS,
  1992. "_p_deactivate()\n\nReinitialize from a newly created copy."},
  1993. #endif
  1994. {NULL, NULL}
  1995. };
  1996. static int
  1997. BTree_init(PyObject *self, PyObject *args, PyObject *kwds)
  1998. {
  1999. PyObject *v = NULL;
  2000. BTREE(self)->max_leaf_size = 0;
  2001. BTREE(self)->max_internal_size = 0;
  2002. if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "BTree", &v))
  2003. return -1;
  2004. if (v)
  2005. return update_from_seq(self, v);
  2006. else
  2007. return 0;
  2008. }
  2009. static void
  2010. BTree_dealloc(BTree *self)
  2011. {
  2012. PyObject_GC_UnTrack((PyObject *)self);
  2013. if (self->state != cPersistent_GHOST_STATE) {
  2014. _BTree_clear(self);
  2015. }
  2016. cPersistenceCAPI->pertype->tp_dealloc((PyObject *)self);
  2017. }
  2018. static int
  2019. BTree_traverse(BTree *self, visitproc visit, void *arg)
  2020. {
  2021. int err = 0;
  2022. int i, len;
  2023. #define VISIT(SLOT) \
  2024. if (SLOT) { \
  2025. err = visit((PyObject *)(SLOT), arg); \
  2026. if (err) \
  2027. goto Done; \
  2028. }
  2029. if (Py_TYPE(self) == &BTreeType)
  2030. assert(Py_TYPE(self)->tp_dictoffset == 0);
  2031. /* Call our base type's traverse function. Because BTrees are
  2032. * subclasses of Peristent, there must be one.
  2033. */
  2034. err = cPersistenceCAPI->pertype->tp_traverse((PyObject *)self, visit, arg);
  2035. if (err)
  2036. goto Done;
  2037. /* If this is registered with the persistence system, cleaning up cycles
  2038. * is the database's problem. It would be horrid to unghostify BTree
  2039. * nodes here just to chase pointers every time gc runs.
  2040. */
  2041. if (self->state == cPersistent_GHOST_STATE)
  2042. goto Done;
  2043. len = self->len;
  2044. #ifdef KEY_TYPE_IS_PYOBJECT
  2045. /* Keys are Python objects so need to be traversed. Note that the
  2046. * key 0 slot is unused and should not be traversed.
  2047. */
  2048. for (i = 1; i < len; i++)
  2049. VISIT(self->data[i].key);
  2050. #endif
  2051. /* Children are always pointers, and child 0 is legit. */
  2052. for (i = 0; i < len; i++)
  2053. VISIT(self->data[i].child);
  2054. VISIT(self->firstbucket);
  2055. Done:
  2056. return err;
  2057. #undef VISIT
  2058. }
  2059. static int
  2060. BTree_tp_clear(BTree *self)
  2061. {
  2062. if (self->state != cPersistent_GHOST_STATE)
  2063. _BTree_clear(self);
  2064. return 0;
  2065. }
  2066. /*
  2067. * Return the number of elements in a BTree. nonzero is a Boolean, and
  2068. * when true requests just a non-empty/empty result. Testing for emptiness
  2069. * is efficient (constant-time). Getting the true length takes time
  2070. * proportional to the number of leaves (buckets).
  2071. *
  2072. * Return:
  2073. * When nonzero true:
  2074. * -1 error
  2075. * 0 empty
  2076. * 1 not empty
  2077. * When nonzero false (possibly expensive!):
  2078. * -1 error
  2079. * >= 0 number of elements.
  2080. */
  2081. static Py_ssize_t
  2082. BTree_length_or_nonzero(BTree *self, int nonzero)
  2083. {
  2084. int result;
  2085. Bucket *b;
  2086. Bucket *next;
  2087. PER_USE_OR_RETURN(self, -1);
  2088. b = self->firstbucket;
  2089. PER_UNUSE(self);
  2090. if (nonzero)
  2091. return b != NULL;
  2092. result = 0;
  2093. while (b)
  2094. {
  2095. PER_USE_OR_RETURN(b, -1);
  2096. result += b->len;
  2097. next = b->next;
  2098. PER_UNUSE(b);
  2099. b = next;
  2100. }
  2101. return result;
  2102. }
  2103. static Py_ssize_t
  2104. BTree_length(BTree *self)
  2105. {
  2106. return BTree_length_or_nonzero(self, 0);
  2107. }
  2108. static PyMappingMethods BTree_as_mapping = {
  2109. (lenfunc)BTree_length, /* mp_length */
  2110. (binaryfunc)BTree_get, /* mp_subscript */
  2111. (objobjargproc)BTree_setitem, /* mp_ass_subscript */
  2112. };
  2113. static PySequenceMethods BTree_as_sequence = {
  2114. (lenfunc)0, /* sq_length */
  2115. (binaryfunc)0, /* sq_concat */
  2116. (ssizeargfunc)0, /* sq_repeat */
  2117. (ssizeargfunc)0, /* sq_item */
  2118. (ssizessizeargfunc)0, /* sq_slice */
  2119. (ssizeobjargproc)0, /* sq_ass_item */
  2120. (ssizessizeobjargproc)0, /* sq_ass_slice */
  2121. (objobjproc)BTree_contains, /* sq_contains */
  2122. 0, /* sq_inplace_concat */
  2123. 0, /* sq_inplace_repeat */
  2124. };
  2125. static Py_ssize_t
  2126. BTree_nonzero(BTree *self)
  2127. {
  2128. return BTree_length_or_nonzero(self, 1);
  2129. }
  2130. static PyNumberMethods BTree_as_number_for_nonzero = {
  2131. 0, /* nb_add */
  2132. 0, /* nb_subtract */
  2133. 0, /* nb_multiply */
  2134. #ifndef PY3K
  2135. 0, /* nb_divide */
  2136. #endif
  2137. 0, /* nb_remainder */
  2138. 0, /* nb_divmod */
  2139. 0, /* nb_power */
  2140. 0, /* nb_negative */
  2141. 0, /* nb_positive */
  2142. 0, /* nb_absolute */
  2143. (inquiry)BTree_nonzero /* nb_nonzero */
  2144. };
  2145. static PyTypeObject BTreeType = {
  2146. PyVarObject_HEAD_INIT(NULL, 0)
  2147. MODULE_NAME MOD_NAME_PREFIX "BTree", /* tp_name */
  2148. sizeof(BTree), /* tp_basicsize */
  2149. 0, /* tp_itemsize */
  2150. (destructor)BTree_dealloc, /* tp_dealloc */
  2151. 0, /* tp_print */
  2152. 0, /* tp_getattr */
  2153. 0, /* tp_setattr */
  2154. 0, /* tp_compare */
  2155. 0, /* tp_repr */
  2156. &BTree_as_number_for_nonzero, /* tp_as_number */
  2157. &BTree_as_sequence, /* tp_as_sequence */
  2158. &BTree_as_mapping, /* tp_as_mapping */
  2159. 0, /* tp_hash */
  2160. 0, /* tp_call */
  2161. 0, /* tp_str */
  2162. 0, /* tp_getattro */
  2163. 0, /* tp_setattro */
  2164. 0, /* tp_as_buffer */
  2165. Py_TPFLAGS_DEFAULT |
  2166. Py_TPFLAGS_HAVE_GC |
  2167. Py_TPFLAGS_BASETYPE, /* tp_flags */
  2168. 0, /* tp_doc */
  2169. (traverseproc)BTree_traverse, /* tp_traverse */
  2170. (inquiry)BTree_tp_clear, /* tp_clear */
  2171. 0, /* tp_richcompare */
  2172. 0, /* tp_weaklistoffset */
  2173. (getiterfunc)BTree_getiter, /* tp_iter */
  2174. 0, /* tp_iternext */
  2175. BTree_methods, /* tp_methods */
  2176. BTree_members, /* tp_members */
  2177. 0, /* tp_getset */
  2178. 0, /* tp_base */
  2179. 0, /* tp_dict */
  2180. 0, /* tp_descr_get */
  2181. 0, /* tp_descr_set */
  2182. 0, /* tp_dictoffset */
  2183. BTree_init, /* tp_init */
  2184. 0, /* tp_alloc */
  2185. 0, /*PyType_GenericNew,*/ /* tp_new */
  2186. };