PageRenderTime 65ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/ImageMagick-6.3.2/magick/splay-tree.c

https://bitbucket.org/sisko/operation-caribou
C | 1265 lines | 762 code | 60 blank | 443 comment | 206 complexity | d1385abd22c323302b2e83a86842c1c3 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1
  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % %
  4. % %
  5. % %
  6. % SSSSS PPPP L AAA Y Y %
  7. % SS P P L A A Y Y %
  8. % SSS PPPP L AAAAA Y %
  9. % SS P L A A Y %
  10. % SSSSS P LLLLL A A Y %
  11. % %
  12. % TTTTT RRRR EEEEE EEEEE %
  13. % T R R E E %
  14. % T RRRR EEE EEE %
  15. % T R R E E %
  16. % T R R EEEEE EEEEE %
  17. % %
  18. % %
  19. % ImageMagick Self-adjusting Binary Search Tree Methods %
  20. % %
  21. % Software Design %
  22. % John Cristy %
  23. % December 2002 %
  24. % %
  25. % %
  26. % Copyright 1999-2006 ImageMagick Studio LLC, a non-profit organization %
  27. % dedicated to making software imaging solutions freely available. %
  28. % %
  29. % You may not use this file except in compliance with the License. You may %
  30. % obtain a copy of the License at %
  31. % %
  32. % http://www.imagemagick.org/script/license.php %
  33. % %
  34. % Unless required by applicable law or agreed to in writing, software %
  35. % distributed under the License is distributed on an "AS IS" BASIS, %
  36. % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
  37. % See the License for the specific language governing permissions and %
  38. % limitations under the License. %
  39. % %
  40. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  41. %
  42. % This module implements the standard handy splay-tree methods for storing and
  43. % retrieving large numbers of data elements. It is loosely based on the Java
  44. % implementation of these algorithms.
  45. %
  46. */
  47. /*
  48. Include declarations.
  49. */
  50. #include "magick/studio.h"
  51. #include "magick/exception.h"
  52. #include "magick/exception-private.h"
  53. #include "magick/log.h"
  54. #include "magick/memory_.h"
  55. #include "magick/splay-tree.h"
  56. #include "magick/semaphore.h"
  57. #include "magick/string_.h"
  58. /*
  59. Define declarations.
  60. */
  61. #define MaxSplayTreeDepth 1024
  62. /*
  63. Typedef declarations.
  64. */
  65. typedef struct _NodeInfo
  66. {
  67. void
  68. *key;
  69. void
  70. *value;
  71. struct _NodeInfo
  72. *left,
  73. *right;
  74. } NodeInfo;
  75. struct _SplayTreeInfo
  76. {
  77. NodeInfo
  78. *root;
  79. int
  80. (*compare)(const void *,const void *);
  81. void
  82. *(*relinquish_key)(void *),
  83. *(*relinquish_value)(void *);
  84. unsigned long
  85. depth;
  86. MagickBooleanType
  87. balance;
  88. void
  89. *key,
  90. *next;
  91. unsigned long
  92. nodes;
  93. MagickBooleanType
  94. debug;
  95. SemaphoreInfo
  96. *semaphore;
  97. unsigned long
  98. signature;
  99. };
  100. /*
  101. Forward declarations.
  102. */
  103. static int
  104. IterateOverSplayTree(SplayTreeInfo *,int (*)(NodeInfo *,const void *),
  105. const void *);
  106. static void
  107. SplaySplayTree(SplayTreeInfo *,const void *);
  108. /*
  109. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  110. % %
  111. % %
  112. % %
  113. % A d d V a l u e T o S p l a y T r e e %
  114. % %
  115. % %
  116. % %
  117. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  118. %
  119. % AddValueToSplayTree() adds a value to the splay-tree.
  120. %
  121. % The format of the AddValueToSplayTree method is:
  122. %
  123. % MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_info,
  124. % const void *key,const void *value)
  125. %
  126. % A description of each parameter follows:
  127. %
  128. % o splay_info: The splay-tree info.
  129. %
  130. % o key: The key.
  131. %
  132. % o value: The value.
  133. %
  134. */
  135. MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_info,
  136. const void *key,const void *value)
  137. {
  138. int
  139. compare;
  140. register NodeInfo
  141. *node;
  142. AcquireSemaphoreInfo(&splay_info->semaphore);
  143. SplaySplayTree(splay_info,key);
  144. compare=0;
  145. if (splay_info->root != (NodeInfo *) NULL)
  146. {
  147. if (splay_info->compare != (int (*)(const void *,const void *)) NULL)
  148. compare=splay_info->compare(splay_info->root->key,key);
  149. else
  150. compare=(splay_info->root->key > key) ? 1 :
  151. ((splay_info->root->key < key) ? -1 : 0);
  152. if (compare == 0)
  153. {
  154. if ((splay_info->relinquish_value != (void *(*)(void *)) NULL) &&
  155. (splay_info->root->value != (void *) NULL))
  156. splay_info->root->value=splay_info->relinquish_value(
  157. splay_info->root->value);
  158. if ((splay_info->relinquish_key != (void *(*)(void *)) NULL) &&
  159. (splay_info->root->key != (void *) NULL))
  160. splay_info->root->key=splay_info->relinquish_key(
  161. splay_info->root->key);
  162. splay_info->root->key=(void *) key;
  163. splay_info->root->value=(void *) value;
  164. RelinquishSemaphoreInfo(splay_info->semaphore);
  165. return(MagickTrue);
  166. }
  167. }
  168. node=(NodeInfo *) AcquireMagickMemory(sizeof(*node));
  169. if (node == (NodeInfo *) NULL)
  170. return(MagickFalse);
  171. node->key=(void *) key;
  172. node->value=(void *) value;
  173. if (splay_info->root == (NodeInfo *) NULL)
  174. {
  175. node->left=(NodeInfo *) NULL;
  176. node->right=(NodeInfo *) NULL;
  177. }
  178. else
  179. if (compare < 0)
  180. {
  181. node->left=splay_info->root;
  182. node->right=node->left->right;
  183. node->left->right=(NodeInfo *) NULL;
  184. }
  185. else
  186. {
  187. node->right=splay_info->root;
  188. node->left=node->right->left;
  189. node->right->left=(NodeInfo *) NULL;
  190. }
  191. splay_info->root=node;
  192. splay_info->key=(void *) NULL;
  193. splay_info->nodes++;
  194. RelinquishSemaphoreInfo(splay_info->semaphore);
  195. return(MagickTrue);
  196. }
  197. /*
  198. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  199. % %
  200. % %
  201. % %
  202. % B a l a n c e S p l a y T r e e %
  203. % %
  204. % %
  205. % %
  206. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  207. %
  208. % BalanceSplayTree() balances the splay-tree.
  209. %
  210. % The format of the BalanceSplayTree method is:
  211. %
  212. % void *BalanceSplayTree(SplayTreeInfo *splay_info,const void *key)
  213. %
  214. % A description of each parameter follows:
  215. %
  216. % o splay_info: The splay-tree info.
  217. %
  218. % o key: The key.
  219. %
  220. */
  221. static NodeInfo *LinkSplayTreeNodes(NodeInfo **nodes,unsigned long low,
  222. unsigned long high)
  223. {
  224. register NodeInfo
  225. *node;
  226. unsigned long
  227. bisect;
  228. bisect=low+(high-low)/2;
  229. node=nodes[bisect];
  230. if ((low+1) > bisect)
  231. node->left=(NodeInfo *) NULL;
  232. else
  233. node->left=LinkSplayTreeNodes(nodes,low,bisect-1);
  234. if ((bisect+1) > high)
  235. node->right=(NodeInfo *) NULL;
  236. else
  237. node->right=LinkSplayTreeNodes(nodes,bisect+1,high);
  238. return(node);
  239. }
  240. static int SplayTreeToNodeArray(NodeInfo *node,const void *nodes)
  241. {
  242. register const NodeInfo
  243. ***p;
  244. p=(const NodeInfo ***) nodes;
  245. *(*p)=node;
  246. (*p)++;
  247. return(0);
  248. }
  249. static void BalanceSplayTree(SplayTreeInfo *splay_info)
  250. {
  251. NodeInfo
  252. **node,
  253. **nodes;
  254. if (splay_info->nodes <= 2)
  255. {
  256. splay_info->balance=MagickFalse;
  257. return;
  258. }
  259. nodes=(NodeInfo **) AcquireMagickMemory((size_t) splay_info->nodes*
  260. sizeof(*nodes));
  261. if (nodes == (NodeInfo **) NULL)
  262. {
  263. char
  264. *message;
  265. message=GetExceptionMessage(errno);
  266. ThrowMagickFatalException(ResourceLimitFatalError,
  267. "MemoryAllocationFailed",message);
  268. message=(char *) RelinquishMagickMemory(message);
  269. }
  270. node=nodes;
  271. (void) IterateOverSplayTree(splay_info,SplayTreeToNodeArray,
  272. (const void *) &node);
  273. splay_info->root=LinkSplayTreeNodes(nodes,0,splay_info->nodes-1);
  274. splay_info->balance=MagickFalse;
  275. nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
  276. }
  277. /*
  278. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  279. % %
  280. % %
  281. % %
  282. % C o m p a r e S p l a y T r e e S t r i n g %
  283. % %
  284. % %
  285. % %
  286. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  287. %
  288. % CompareSplayTreeString() method finds a node in a splay-tree based on the
  289. % contents of a string.
  290. %
  291. % The format of the CompareSplayTreeString method is:
  292. %
  293. % int CompareSplayTreeString(const void *target,const void *source)
  294. %
  295. % A description of each parameter follows:
  296. %
  297. % o target: The target string.
  298. %
  299. % o source: The source string.
  300. %
  301. */
  302. MagickExport int CompareSplayTreeString(const void *target,const void *source)
  303. {
  304. const char
  305. *p,
  306. *q;
  307. p=(const char *) target;
  308. q=(const char *) source;
  309. return(LocaleCompare(p,q));
  310. }
  311. /*
  312. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  313. % %
  314. % %
  315. % %
  316. % C o m p a r e S p l a y T r e e S t r i n g I n f o %
  317. % %
  318. % %
  319. % %
  320. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  321. %
  322. % CompareSplayTreeStringInfo() finds a node in a splay-tree based on the
  323. % contents of a string.
  324. %
  325. % The format of the CompareSplayTreeStringInfo method is:
  326. %
  327. % int CompareSplayTreeStringInfo(const void *target,const void *source)
  328. %
  329. % A description of each parameter follows:
  330. %
  331. % o target: The target string.
  332. %
  333. % o source: The source string.
  334. %
  335. */
  336. MagickExport int CompareSplayTreeStringInfo(const void *target,
  337. const void *source)
  338. {
  339. const StringInfo
  340. *p,
  341. *q;
  342. p=(const StringInfo *) target;
  343. q=(const StringInfo *) source;
  344. return(CompareStringInfo(p,q));
  345. }
  346. /*
  347. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  348. % %
  349. % %
  350. % %
  351. % D e s t r o y S p l a y T r e e %
  352. % %
  353. % %
  354. % %
  355. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  356. %
  357. % DestroySplayTree() destroys the splay-tree.
  358. %
  359. % The format of the DestroySplayTree method is:
  360. %
  361. % SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_info)
  362. %
  363. % A description of each parameter follows:
  364. %
  365. % o splay_info: The splay info.
  366. %
  367. */
  368. MagickExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_info)
  369. {
  370. NodeInfo
  371. *node;
  372. register NodeInfo
  373. *active,
  374. *pend;
  375. AcquireSemaphoreInfo(&splay_info->semaphore);
  376. if (splay_info->root != (NodeInfo *) NULL)
  377. {
  378. if ((splay_info->relinquish_value != (void *(*)(void *)) NULL) &&
  379. (splay_info->root->value != (void *) NULL))
  380. splay_info->root->value=splay_info->relinquish_value(
  381. splay_info->root->value);
  382. if ((splay_info->relinquish_key != (void *(*)(void *)) NULL) &&
  383. (splay_info->root->key != (void *) NULL))
  384. splay_info->root->key=splay_info->relinquish_key(splay_info->root->key);
  385. splay_info->root->key=(void *) NULL;
  386. for (pend=splay_info->root; pend != (NodeInfo *) NULL; )
  387. {
  388. active=pend;
  389. for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
  390. {
  391. if (active->left != (NodeInfo *) NULL)
  392. {
  393. if ((splay_info->relinquish_value != (void *(*)(void *)) NULL) &&
  394. (active->left->value != (void *) NULL))
  395. active->left->value=splay_info->relinquish_value(
  396. active->left->value);
  397. if ((splay_info->relinquish_key != (void *(*)(void *)) NULL) &&
  398. (active->left->key != (void *) NULL))
  399. active->left->key=splay_info->relinquish_key(active->left->key);
  400. active->left->key=(void *) pend;
  401. pend=active->left;
  402. }
  403. if (active->right != (NodeInfo *) NULL)
  404. {
  405. if ((splay_info->relinquish_value != (void *(*)(void *)) NULL) &&
  406. (active->right->value != (void *) NULL))
  407. active->right->value=splay_info->relinquish_value(
  408. active->right->value);
  409. if ((splay_info->relinquish_key != (void *(*)(void *)) NULL) &&
  410. (active->right->key != (void *) NULL))
  411. active->right->key=splay_info->relinquish_key(
  412. active->right->key);
  413. active->right->key=(void *) pend;
  414. pend=active->right;
  415. }
  416. node=active;
  417. active=(NodeInfo *) node->key;
  418. node=(NodeInfo *) RelinquishMagickMemory(node);
  419. }
  420. }
  421. }
  422. splay_info->signature=(~MagickSignature);
  423. RelinquishSemaphoreInfo(splay_info->semaphore);
  424. splay_info->semaphore=DestroySemaphoreInfo(splay_info->semaphore);
  425. splay_info=(SplayTreeInfo *) RelinquishMagickMemory(splay_info);
  426. return(splay_info);
  427. }
  428. /*
  429. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  430. % %
  431. % %
  432. % %
  433. % G e t N e x t K e y I n S p l a y T r e e %
  434. % %
  435. % %
  436. % %
  437. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  438. %
  439. % GetNextKeyInSplayTree() gets the next key in the splay-tree.
  440. %
  441. % The format of the GetNextKeyInSplayTree method is:
  442. %
  443. % void *GetNextKeyInSplayTree(SplayTreeInfo *splay_info)
  444. %
  445. % A description of each parameter follows:
  446. %
  447. % o splay_info: The splay info.
  448. %
  449. % o key: The key.
  450. %
  451. */
  452. MagickExport void *GetNextKeyInSplayTree(SplayTreeInfo *splay_info)
  453. {
  454. register NodeInfo
  455. *node;
  456. void
  457. *key;
  458. assert(splay_info != (SplayTreeInfo *) NULL);
  459. assert(splay_info->signature == MagickSignature);
  460. if (splay_info->debug != MagickFalse)
  461. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  462. if ((splay_info->root == (NodeInfo *) NULL) ||
  463. (splay_info->next == (void *) NULL))
  464. return((void *) NULL);
  465. AcquireSemaphoreInfo(&splay_info->semaphore);
  466. SplaySplayTree(splay_info,splay_info->next);
  467. splay_info->next=(void *) NULL;
  468. node=splay_info->root->right;
  469. if (node != (NodeInfo *) NULL)
  470. {
  471. while (node->left != (NodeInfo *) NULL)
  472. node=node->left;
  473. splay_info->next=node->key;
  474. }
  475. key=splay_info->root->key;
  476. RelinquishSemaphoreInfo(splay_info->semaphore);
  477. return(key);
  478. }
  479. /*
  480. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  481. % %
  482. % %
  483. % %
  484. % G e t N e x t V a l u e I n S p l a y T r e e %
  485. % %
  486. % %
  487. % %
  488. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  489. %
  490. % GetNextValueInSplayTree() gets the next value in the splay-tree.
  491. %
  492. % The format of the GetNextValueInSplayTree method is:
  493. %
  494. % void *GetNextValueInSplayTree(SplayTreeInfo *splay_info)
  495. %
  496. % A description of each parameter follows:
  497. %
  498. % o splay_info: The splay info.
  499. %
  500. % o key: The key.
  501. %
  502. */
  503. MagickExport void *GetNextValueInSplayTree(SplayTreeInfo *splay_info)
  504. {
  505. register NodeInfo
  506. *node;
  507. void
  508. *value;
  509. assert(splay_info != (SplayTreeInfo *) NULL);
  510. assert(splay_info->signature == MagickSignature);
  511. if (splay_info->debug != MagickFalse)
  512. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  513. if ((splay_info->root == (NodeInfo *) NULL) ||
  514. (splay_info->next == (void *) NULL))
  515. return((void *) NULL);
  516. AcquireSemaphoreInfo(&splay_info->semaphore);
  517. SplaySplayTree(splay_info,splay_info->next);
  518. splay_info->next=(void *) NULL;
  519. node=splay_info->root->right;
  520. if (node != (NodeInfo *) NULL)
  521. {
  522. while (node->left != (NodeInfo *) NULL)
  523. node=node->left;
  524. splay_info->next=node->key;
  525. }
  526. value=splay_info->root->value;
  527. RelinquishSemaphoreInfo(splay_info->semaphore);
  528. return(value);
  529. }
  530. /*
  531. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  532. % %
  533. % %
  534. % %
  535. % G e t V a l u e F r o m S p l a y T r e e %
  536. % %
  537. % %
  538. % %
  539. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  540. %
  541. % GetValueFromSplayTree() gets a value from the splay-tree by its key.
  542. %
  543. % The format of the GetValueFromSplayTree method is:
  544. %
  545. % void *GetValueFromSplayTree(SplayTreeInfo *splay_info,const void *key)
  546. %
  547. % A description of each parameter follows:
  548. %
  549. % o splay_info: The splay info.
  550. %
  551. % o key: The key.
  552. %
  553. */
  554. MagickExport void *GetValueFromSplayTree(SplayTreeInfo *splay_info,
  555. const void *key)
  556. {
  557. int
  558. compare;
  559. void
  560. *value;
  561. assert(splay_info != (SplayTreeInfo *) NULL);
  562. assert(splay_info->signature == MagickSignature);
  563. if (splay_info->debug != MagickFalse)
  564. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  565. if (splay_info->root == (NodeInfo *) NULL)
  566. return((void *) NULL);
  567. AcquireSemaphoreInfo(&splay_info->semaphore);
  568. SplaySplayTree(splay_info,key);
  569. if (splay_info->compare != (int (*)(const void *,const void *)) NULL)
  570. compare=splay_info->compare(splay_info->root->key,key);
  571. else
  572. compare=(splay_info->root->key > key) ? 1 :
  573. ((splay_info->root->key < key) ? -1 : 0);
  574. if (compare != 0)
  575. {
  576. RelinquishSemaphoreInfo(splay_info->semaphore);
  577. return((void *) NULL);
  578. }
  579. value=splay_info->root->value;
  580. RelinquishSemaphoreInfo(splay_info->semaphore);
  581. return(value);
  582. }
  583. /*
  584. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  585. % %
  586. % %
  587. % %
  588. % G e t N u m b e r O f N o d e s I n S p l a y T r e e %
  589. % %
  590. % %
  591. % %
  592. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  593. %
  594. % GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree.
  595. %
  596. % The format of the GetNumberOfNodesInSplayTree method is:
  597. %
  598. % unsigned long GetNumberOfNodesInSplayTree(
  599. % const SplayTreeInfo *splay_tree)
  600. %
  601. % A description of each parameter follows:
  602. %
  603. % o splay_info: The splay info.
  604. %
  605. */
  606. MagickExport unsigned long GetNumberOfNodesInSplayTree(
  607. const SplayTreeInfo *splay_info)
  608. {
  609. assert(splay_info != (SplayTreeInfo *) NULL);
  610. assert(splay_info->signature == MagickSignature);
  611. if (splay_info->debug != MagickFalse)
  612. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  613. return(splay_info->nodes);
  614. }
  615. /*
  616. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  617. % %
  618. % %
  619. % %
  620. % I t e r a t e O v e r S p l a y T r e e %
  621. % %
  622. % %
  623. % %
  624. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  625. %
  626. % IterateOverSplayTree() iterates over the splay-tree.
  627. %
  628. % The format of the IterateOverSplayTree method is:
  629. %
  630. % int IterateOverSplayTree(SplayTreeInfo *splay_info,
  631. % int (*method)(NodeInfo *,void *),const void *value)
  632. %
  633. % A description of each parameter follows:
  634. %
  635. % o splay_info: The splay-tree info.
  636. %
  637. % o method: The method.
  638. %
  639. % o value: The value.
  640. %
  641. */
  642. static int IterateOverSplayTree(SplayTreeInfo *splay_info,
  643. int (*method)(NodeInfo *,const void *),const void *value)
  644. {
  645. typedef enum
  646. {
  647. LeftTransition,
  648. RightTransition,
  649. DownTransition,
  650. UpTransition
  651. } TransitionType;
  652. int
  653. status;
  654. MagickBooleanType
  655. final_transition;
  656. NodeInfo
  657. **nodes;
  658. register long
  659. i;
  660. register NodeInfo
  661. *node;
  662. TransitionType
  663. transition;
  664. unsigned char
  665. *transitions;
  666. if (splay_info->root == (NodeInfo *) NULL)
  667. return(0);
  668. nodes=(NodeInfo **) AcquireMagickMemory((size_t) splay_info->nodes*
  669. sizeof(*nodes));
  670. transitions=(unsigned char *) AcquireMagickMemory((size_t) splay_info->nodes*
  671. sizeof(*transitions));
  672. if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL))
  673. {
  674. char
  675. *message;
  676. message=GetExceptionMessage(errno);
  677. ThrowMagickFatalException(ResourceLimitFatalError,
  678. "MemoryAllocationFailed",message);
  679. message=(char *) RelinquishMagickMemory(message);
  680. }
  681. status=0;
  682. final_transition=MagickFalse;
  683. nodes[0]=splay_info->root;
  684. transitions[0]=(unsigned char) LeftTransition;
  685. for (i=0; final_transition == MagickFalse; )
  686. {
  687. node=nodes[i];
  688. transition=(TransitionType) transitions[i];
  689. switch (transition)
  690. {
  691. case LeftTransition:
  692. {
  693. transitions[i]=(unsigned char) DownTransition;
  694. if (node->left == (NodeInfo *) NULL)
  695. break;
  696. i++;
  697. nodes[i]=node->left;
  698. transitions[i]=(unsigned char) LeftTransition;
  699. break;
  700. }
  701. case RightTransition:
  702. {
  703. transitions[i]=(unsigned char) UpTransition;
  704. if (node->right == (NodeInfo *) NULL)
  705. break;
  706. i++;
  707. nodes[i]=node->right;
  708. transitions[i]=(unsigned char) LeftTransition;
  709. break;
  710. }
  711. case DownTransition:
  712. default:
  713. {
  714. transitions[i]=(unsigned char) RightTransition;
  715. status=(*method)(node,value);
  716. if (status != 0)
  717. final_transition=MagickTrue;
  718. break;
  719. }
  720. case UpTransition:
  721. {
  722. if (i == 0)
  723. {
  724. final_transition=MagickTrue;
  725. break;
  726. }
  727. i--;
  728. break;
  729. }
  730. }
  731. }
  732. nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
  733. transitions=(unsigned char *) RelinquishMagickMemory(transitions);
  734. return(status);
  735. }
  736. /*
  737. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  738. % %
  739. % %
  740. % %
  741. % N e w S p l a y T r e e %
  742. % %
  743. % %
  744. % %
  745. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  746. %
  747. % NewSplayTree() returns a pointer to a SplayTreeInfo structure initialized
  748. % to default values.
  749. %
  750. % The format of the NewSplayTree method is:
  751. %
  752. % SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *),
  753. % void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
  754. %
  755. % A description of each parameter follows:
  756. %
  757. % o compare: The compare method.
  758. %
  759. % o relinquish_key: The key deallocation method, typically
  760. % RelinquishMagickMemory(), called whenever a key is removed from the
  761. % splay-tree.
  762. %
  763. % o relinquish_value: The value deallocation method; typically
  764. % RelinquishMagickMemory(), called whenever a value object is removed from
  765. % the splay-tree.
  766. %
  767. */
  768. MagickExport SplayTreeInfo *NewSplayTree(
  769. int (*compare)(const void *,const void *),void *(*relinquish_key)(void *),
  770. void *(*relinquish_value)(void *))
  771. {
  772. SplayTreeInfo
  773. *splay_info;
  774. splay_info=(SplayTreeInfo *) AcquireMagickMemory(sizeof(*splay_info));
  775. if (splay_info == (SplayTreeInfo *) NULL)
  776. {
  777. char
  778. *message;
  779. message=GetExceptionMessage(errno);
  780. ThrowMagickFatalException(ResourceLimitFatalError,
  781. "MemoryAllocationFailed",message);
  782. message=(char *) RelinquishMagickMemory(message);
  783. }
  784. (void) ResetMagickMemory(splay_info,0,sizeof(*splay_info));
  785. splay_info->root=(NodeInfo *) NULL;
  786. splay_info->compare=compare;
  787. splay_info->relinquish_key=relinquish_key;
  788. splay_info->relinquish_value=relinquish_value;
  789. splay_info->depth=0;
  790. splay_info->balance=MagickFalse;
  791. splay_info->key=(void *) NULL;
  792. splay_info->next=(void *) NULL;
  793. splay_info->nodes=0;
  794. splay_info->debug=IsEventLogging();
  795. splay_info->semaphore=(SemaphoreInfo *) NULL;
  796. splay_info->signature=MagickSignature;
  797. return(splay_info);
  798. }
  799. /*
  800. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  801. % %
  802. % %
  803. % %
  804. % R e m o v e N o d e B y V a l u e F r o m S p l a y T r e e %
  805. % %
  806. % %
  807. % %
  808. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  809. %
  810. % RemoveNodeByValueFromSplayTree() removes a node by value from the splay-tree.
  811. %
  812. % The format of the RemoveNodeByValueFromSplayTree method is:
  813. %
  814. % MagickBooleanType RemoveNodeByValueFromSplayTree(
  815. % SplayTreeInfo *splay_info,const void *value)
  816. %
  817. % A description of each parameter follows:
  818. %
  819. % o splay_info: The splay-tree info.
  820. %
  821. % o value: The value.
  822. %
  823. */
  824. static void *GetFirstSplayTreeNode(SplayTreeInfo *splay_info)
  825. {
  826. register NodeInfo
  827. *node;
  828. node=splay_info->root;
  829. if (splay_info->root == (NodeInfo *) NULL)
  830. return((NodeInfo *) NULL);
  831. while (node->left != (NodeInfo *) NULL)
  832. node=node->left;
  833. return(node->key);
  834. }
  835. MagickExport MagickBooleanType RemoveNodeByValueFromSplayTree(
  836. SplayTreeInfo *splay_info,const void *value)
  837. {
  838. register NodeInfo
  839. *next,
  840. *node;
  841. assert(splay_info != (SplayTreeInfo *) NULL);
  842. assert(splay_info->signature == MagickSignature);
  843. if (splay_info->debug != MagickFalse)
  844. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  845. if (splay_info->root == (NodeInfo *) NULL)
  846. return(MagickFalse);
  847. AcquireSemaphoreInfo(&splay_info->semaphore);
  848. next=(NodeInfo *) GetFirstSplayTreeNode(splay_info);
  849. while (next != (NodeInfo *) NULL)
  850. {
  851. SplaySplayTree(splay_info,next);
  852. next=(NodeInfo *) NULL;
  853. node=splay_info->root->right;
  854. if (node != (NodeInfo *) NULL)
  855. {
  856. while (node->left != (NodeInfo *) NULL)
  857. node=node->left;
  858. next=(NodeInfo *) node->key;
  859. }
  860. if (splay_info->root->value == value)
  861. {
  862. int
  863. compare;
  864. register NodeInfo
  865. *left,
  866. *right;
  867. void
  868. *key;
  869. /*
  870. We found the node that matches the value; now remove it.
  871. */
  872. key=splay_info->root->key;
  873. SplaySplayTree(splay_info,key);
  874. splay_info->key=(void *) NULL;
  875. if (splay_info->compare != (int (*)(const void *,const void *)) NULL)
  876. compare=splay_info->compare(splay_info->root->key,key);
  877. else
  878. compare=(splay_info->root->key > key) ? 1 :
  879. ((splay_info->root->key < key) ? -1 : 0);
  880. if (compare != 0)
  881. {
  882. RelinquishSemaphoreInfo(splay_info->semaphore);
  883. return(MagickFalse);
  884. }
  885. left=splay_info->root->left;
  886. right=splay_info->root->right;
  887. if ((splay_info->relinquish_value != (void *(*)(void *)) NULL) &&
  888. (splay_info->root->value != (void *) NULL))
  889. splay_info->root->value=splay_info->relinquish_value(
  890. splay_info->root->value);
  891. if ((splay_info->relinquish_key != (void *(*)(void *)) NULL) &&
  892. (splay_info->root->key != (void *) NULL))
  893. splay_info->root->key=splay_info->relinquish_key(
  894. splay_info->root->key);
  895. splay_info->root=(NodeInfo *) RelinquishMagickMemory(splay_info->root);
  896. splay_info->nodes--;
  897. if (left == (NodeInfo *) NULL)
  898. {
  899. splay_info->root=right;
  900. RelinquishSemaphoreInfo(splay_info->semaphore);
  901. return(MagickTrue);
  902. }
  903. splay_info->root=left;
  904. if (right != (NodeInfo *) NULL)
  905. {
  906. while (left->right != (NodeInfo *) NULL)
  907. left=left->right;
  908. left->right=right;
  909. }
  910. RelinquishSemaphoreInfo(splay_info->semaphore);
  911. return(MagickTrue);
  912. }
  913. }
  914. RelinquishSemaphoreInfo(splay_info->semaphore);
  915. return(MagickFalse);
  916. }
  917. /*
  918. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  919. % %
  920. % %
  921. % %
  922. % R e m o v e N o d e F r o m S p l a y T r e e %
  923. % %
  924. % %
  925. % %
  926. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  927. %
  928. % RemoveNodeFromSplayTree() removes a node from the splay-tree.
  929. %
  930. % The format of the RemoveNodeFromSplayTree method is:
  931. %
  932. % MagickBooleanType RemoveNodeFromSplayTree(SplayTreeInfo *splay_info,
  933. % const void *key)
  934. %
  935. % A description of each parameter follows:
  936. %
  937. % o splay_info: The splay-tree info.
  938. %
  939. % o key: The key.
  940. %
  941. */
  942. MagickExport MagickBooleanType RemoveNodeFromSplayTree(
  943. SplayTreeInfo *splay_info,const void *key)
  944. {
  945. int
  946. compare;
  947. register NodeInfo
  948. *left,
  949. *right;
  950. assert(splay_info != (SplayTreeInfo *) NULL);
  951. assert(splay_info->signature == MagickSignature);
  952. if (splay_info->debug != MagickFalse)
  953. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  954. if (splay_info->root == (NodeInfo *) NULL)
  955. return(MagickFalse);
  956. AcquireSemaphoreInfo(&splay_info->semaphore);
  957. SplaySplayTree(splay_info,key);
  958. splay_info->key=(void *) NULL;
  959. if (splay_info->compare != (int (*)(const void *,const void *)) NULL)
  960. compare=splay_info->compare(splay_info->root->key,key);
  961. else
  962. compare=(splay_info->root->key > key) ? 1 :
  963. ((splay_info->root->key < key) ? -1 : 0);
  964. if (compare != 0)
  965. {
  966. RelinquishSemaphoreInfo(splay_info->semaphore);
  967. return(MagickFalse);
  968. }
  969. left=splay_info->root->left;
  970. right=splay_info->root->right;
  971. if ((splay_info->relinquish_value != (void *(*)(void *)) NULL) &&
  972. (splay_info->root->value != (void *) NULL))
  973. splay_info->root->value=splay_info->relinquish_value(
  974. splay_info->root->value);
  975. if ((splay_info->relinquish_key != (void *(*)(void *)) NULL) &&
  976. (splay_info->root->key != (void *) NULL))
  977. splay_info->root->key=splay_info->relinquish_key(splay_info->root->key);
  978. splay_info->root=(NodeInfo *) RelinquishMagickMemory(splay_info->root);
  979. splay_info->nodes--;
  980. if (left == (NodeInfo *) NULL)
  981. {
  982. splay_info->root=right;
  983. RelinquishSemaphoreInfo(splay_info->semaphore);
  984. return(MagickTrue);
  985. }
  986. splay_info->root=left;
  987. if (right != (NodeInfo *) NULL)
  988. {
  989. while (left->right != (NodeInfo *) NULL)
  990. left=left->right;
  991. left->right=right;
  992. }
  993. RelinquishSemaphoreInfo(splay_info->semaphore);
  994. return(MagickTrue);
  995. }
  996. /*
  997. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  998. % %
  999. % %
  1000. % %
  1001. % R e s e t S p l a y T r e e I t e r a t o r %
  1002. % %
  1003. % %
  1004. % %
  1005. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1006. %
  1007. % ResetSplayTreeIterator() resets the splay-tree iterator. Use it in
  1008. % conjunction with GetNextValueInSplayTree() to iterate over all the nodes in
  1009. % the splay-tree.
  1010. %
  1011. % The format of the ResetSplayTreeIterator method is:
  1012. %
  1013. % ResetSplayTreeIterator(SplayTreeInfo *splay_info)
  1014. %
  1015. % A description of each parameter follows:
  1016. %
  1017. % o splay_info: The splay info.
  1018. %
  1019. */
  1020. MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_info)
  1021. {
  1022. assert(splay_info != (SplayTreeInfo *) NULL);
  1023. assert(splay_info->signature == MagickSignature);
  1024. if (splay_info->debug != MagickFalse)
  1025. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  1026. AcquireSemaphoreInfo(&splay_info->semaphore);
  1027. splay_info->next=GetFirstSplayTreeNode(splay_info);
  1028. RelinquishSemaphoreInfo(splay_info->semaphore);
  1029. }
  1030. /*
  1031. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1032. % %
  1033. % %
  1034. % %
  1035. % S p l a y S p l a y T r e e %
  1036. % %
  1037. % %
  1038. % %
  1039. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1040. %
  1041. % SplaySplayTree() splays the splay-tree.
  1042. %
  1043. % The format of the SplaySplayTree method is:
  1044. %
  1045. % void SplaySplayTree(SplayTreeInfo *splay_info,const void *key,
  1046. % NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
  1047. %
  1048. % A description of each parameter follows:
  1049. %
  1050. % o splay_info: The splay-tree info.
  1051. %
  1052. % o key: The key.
  1053. %
  1054. % o node: The node.
  1055. %
  1056. % o parent: The parent node.
  1057. %
  1058. % o grandparent: The grandparent node.
  1059. %
  1060. */
  1061. static NodeInfo *Splay(SplayTreeInfo *splay_info,const void *key,
  1062. NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
  1063. {
  1064. int
  1065. compare;
  1066. NodeInfo
  1067. **next;
  1068. register NodeInfo
  1069. *n,
  1070. *p;
  1071. n=(*node);
  1072. if (n == (NodeInfo *) NULL)
  1073. return(*parent);
  1074. if (splay_info->compare != (int (*)(const void *,const void *)) NULL)
  1075. compare=splay_info->compare(n->key,key);
  1076. else
  1077. compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0);
  1078. next=(NodeInfo **) NULL;
  1079. if (compare > 0)
  1080. next=(&n->left);
  1081. else
  1082. if (compare < 0)
  1083. next=(&n->right);
  1084. if (next != (NodeInfo **) NULL)
  1085. {
  1086. if (splay_info->depth >= MaxSplayTreeDepth)
  1087. {
  1088. splay_info->balance=MagickTrue;
  1089. return(n);
  1090. }
  1091. splay_info->depth++;
  1092. n=Splay(splay_info,key,next,node,parent);
  1093. splay_info->depth--;
  1094. if ((*node != n) || (splay_info->balance != MagickFalse))
  1095. return(n);
  1096. }
  1097. if (parent == (NodeInfo **) NULL)
  1098. return(n);
  1099. if (grandparent == (NodeInfo **) NULL)
  1100. {
  1101. if (n == (*parent)->left)
  1102. {
  1103. *node=n->right;
  1104. n->right=(*parent);
  1105. }
  1106. else
  1107. {
  1108. *node=n->left;
  1109. n->left=(*parent);
  1110. }
  1111. *parent=n;
  1112. return(n);
  1113. }
  1114. if ((n == (*parent)->left) && (*parent == (*grandparent)->left))
  1115. {
  1116. p=(*parent);
  1117. (*grandparent)->left=p->right;
  1118. p->right=(*grandparent);
  1119. p->left=n->right;
  1120. n->right=p;
  1121. *grandparent=n;
  1122. return(n);
  1123. }
  1124. if ((n == (*parent)->right) && (*parent == (*grandparent)->right))
  1125. {
  1126. p=(*parent);
  1127. (*grandparent)->right=p->left;
  1128. p->left=(*grandparent);
  1129. p->right=n->left;
  1130. n->left=p;
  1131. *grandparent=n;
  1132. return(n);
  1133. }
  1134. if (n == (*parent)->left)
  1135. {
  1136. (*parent)->left=n->right;
  1137. n->right=(*parent);
  1138. (*grandparent)->right=n->left;
  1139. n->left=(*grandparent);
  1140. *grandparent=n;
  1141. return(n);
  1142. }
  1143. (*parent)->right=n->left;
  1144. n->left=(*parent);
  1145. (*grandparent)->left=n->right;
  1146. n->right=(*grandparent);
  1147. *grandparent=n;
  1148. return(n);
  1149. }
  1150. static void SplaySplayTree(SplayTreeInfo *splay_info,const void *key)
  1151. {
  1152. if (splay_info->root == (NodeInfo *) NULL)
  1153. return;
  1154. if (splay_info->key != (void *) NULL)
  1155. {
  1156. int
  1157. compare;
  1158. if (splay_info->compare != (int (*)(const void *,const void *)) NULL)
  1159. compare=splay_info->compare(splay_info->root->key,key);
  1160. else
  1161. compare=(splay_info->key > key) ? 1 :
  1162. ((splay_info->key < key) ? -1 : 0);
  1163. if (compare == 0)
  1164. return;
  1165. }
  1166. splay_info->depth=0;
  1167. (void) Splay(splay_info,key,&splay_info->root,(NodeInfo **) NULL,
  1168. (NodeInfo **) NULL);
  1169. if (splay_info->balance != MagickFalse)
  1170. {
  1171. BalanceSplayTree(splay_info);
  1172. splay_info->depth=0;
  1173. (void) Splay(splay_info,key,&splay_info->root,(NodeInfo **) NULL,
  1174. (NodeInfo **) NULL);
  1175. if (splay_info->balance != MagickFalse)
  1176. {
  1177. char
  1178. *message;
  1179. message=GetExceptionMessage(errno);
  1180. ThrowMagickFatalException(ResourceLimitFatalError,
  1181. "MemoryAllocationFailed",message);
  1182. message=(char *) RelinquishMagickMemory(message);
  1183. }
  1184. }
  1185. splay_info->key=(void *) key;
  1186. }