45#include "magick/studio.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/hashmap.h"
49#include "magick/hashmap-private.h"
50#include "magick/locale_.h"
51#include "magick/memory_.h"
52#include "magick/semaphore.h"
53#include "magick/signature-private.h"
54#include "magick/string_.h"
90 (*hash)(
const void *);
93 (*compare)(
const void *,
const void *);
96 *(*relinquish_key)(
void *),
97 *(*relinquish_value)(
void *);
142MagickExport MagickBooleanType AppendValueToLinkedList(
143 LinkedListInfo *list_info,
const void *value)
148 assert(list_info != (LinkedListInfo *) NULL);
149 assert(list_info->signature == MagickCoreSignature);
150 if (list_info->elements == list_info->capacity)
152 next=(ElementInfo *) AcquireMagickMemory(
sizeof(*next));
153 if (next == (ElementInfo *) NULL)
155 next->value=(
void *) value;
156 next->next=(ElementInfo *) NULL;
157 LockSemaphoreInfo(list_info->semaphore);
158 if (list_info->next == (ElementInfo *) NULL)
159 list_info->next=next;
160 if (list_info->elements == 0)
161 list_info->head=next;
163 list_info->tail->next=next;
164 list_info->tail=next;
165 list_info->elements++;
166 UnlockSemaphoreInfo(list_info->semaphore);
196MagickExport
void ClearLinkedList(LinkedListInfo *list_info,
197 void *(*relinquish_value)(
void *))
205 assert(list_info != (LinkedListInfo *) NULL);
206 assert(list_info->signature == MagickCoreSignature);
207 LockSemaphoreInfo(list_info->semaphore);
208 next=list_info->head;
209 while (next != (ElementInfo *) NULL)
211 if (relinquish_value != (
void *(*)(
void *)) NULL)
212 next->value=relinquish_value(next->value);
215 element=(ElementInfo *) RelinquishMagickMemory(element);
217 list_info->head=(ElementInfo *) NULL;
218 list_info->tail=(ElementInfo *) NULL;
219 list_info->next=(ElementInfo *) NULL;
220 list_info->elements=0;
221 UnlockSemaphoreInfo(list_info->semaphore);
250MagickExport MagickBooleanType CompareHashmapString(
const void *target,
257 p=(
const char *) target;
258 q=(
const char *) source;
259 return(LocaleCompare(p,q) == 0 ? MagickTrue : MagickFalse);
288MagickExport MagickBooleanType CompareHashmapStringInfo(
const void *target,
295 p=(
const StringInfo *) target;
296 q=(
const StringInfo *) source;
297 return(CompareStringInfo(p,q) == 0 ? MagickTrue : MagickFalse);
322MagickExport HashmapInfo *DestroyHashmap(HashmapInfo *hashmap_info)
333 assert(hashmap_info != (HashmapInfo *) NULL);
334 assert(hashmap_info->signature == MagickCoreSignature);
335 LockSemaphoreInfo(hashmap_info->semaphore);
336 for (i=0; i < (ssize_t) hashmap_info->capacity; i++)
338 list_info=hashmap_info->map[i];
339 if (list_info != (LinkedListInfo *) NULL)
341 list_info->next=list_info->head;
342 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
343 while (entry != (EntryInfo *) NULL)
345 if (hashmap_info->relinquish_key != (
void *(*)(
void *)) NULL)
346 entry->key=hashmap_info->relinquish_key(entry->key);
347 if (hashmap_info->relinquish_value != (
void *(*)(
void *)) NULL)
348 entry->value=hashmap_info->relinquish_value(entry->value);
349 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
352 if (list_info != (LinkedListInfo *) NULL)
353 list_info=DestroyLinkedList(list_info,RelinquishMagickMemory);
355 hashmap_info->map=(LinkedListInfo **) RelinquishMagickMemory(
357 hashmap_info->signature=(~MagickCoreSignature);
358 UnlockSemaphoreInfo(hashmap_info->semaphore);
359 DestroySemaphoreInfo(&hashmap_info->semaphore);
360 hashmap_info=(HashmapInfo *) RelinquishMagickMemory(hashmap_info);
361 return(hashmap_info);
390MagickExport LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
391 void *(*relinquish_value)(
void *))
399 assert(list_info != (LinkedListInfo *) NULL);
400 assert(list_info->signature == MagickCoreSignature);
401 LockSemaphoreInfo(list_info->semaphore);
402 for (next=list_info->head; next != (ElementInfo *) NULL; )
404 if (relinquish_value != (
void *(*)(
void *)) NULL)
405 next->value=relinquish_value(next->value);
408 entry=(ElementInfo *) RelinquishMagickMemory(entry);
410 list_info->signature=(~MagickCoreSignature);
411 UnlockSemaphoreInfo(list_info->semaphore);
412 DestroySemaphoreInfo(&list_info->semaphore);
413 list_info=(LinkedListInfo *) RelinquishMagickMemory(list_info);
439MagickPrivate ElementInfo *GetHeadElementInLinkedList(
440 LinkedListInfo *list_info)
442 assert(list_info != (LinkedListInfo *) NULL);
443 assert(list_info->signature == MagickCoreSignature);
444 return(list_info->head);
469MagickExport
void *GetLastValueInLinkedList(LinkedListInfo *list_info)
474 assert(list_info != (LinkedListInfo *) NULL);
475 assert(list_info->signature == MagickCoreSignature);
476 if (list_info->elements == 0)
477 return((
void *) NULL);
478 LockSemaphoreInfo(list_info->semaphore);
479 value=list_info->tail->value;
480 UnlockSemaphoreInfo(list_info->semaphore);
506MagickExport
void *GetNextKeyInHashmap(HashmapInfo *hashmap_info)
517 assert(hashmap_info != (HashmapInfo *) NULL);
518 assert(hashmap_info->signature == MagickCoreSignature);
519 LockSemaphoreInfo(hashmap_info->semaphore);
520 while (hashmap_info->next < hashmap_info->capacity)
522 list_info=hashmap_info->map[hashmap_info->next];
523 if (list_info != (LinkedListInfo *) NULL)
525 if (hashmap_info->head_of_list == MagickFalse)
527 list_info->next=list_info->head;
528 hashmap_info->head_of_list=MagickTrue;
530 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
531 if (entry != (EntryInfo *) NULL)
534 UnlockSemaphoreInfo(hashmap_info->semaphore);
537 hashmap_info->head_of_list=MagickFalse;
539 hashmap_info->next++;
541 UnlockSemaphoreInfo(hashmap_info->semaphore);
542 return((
void *) NULL);
567MagickExport
void *GetNextValueInHashmap(HashmapInfo *hashmap_info)
578 assert(hashmap_info != (HashmapInfo *) NULL);
579 assert(hashmap_info->signature == MagickCoreSignature);
580 LockSemaphoreInfo(hashmap_info->semaphore);
581 while (hashmap_info->next < hashmap_info->capacity)
583 list_info=hashmap_info->map[hashmap_info->next];
584 if (list_info != (LinkedListInfo *) NULL)
586 if (hashmap_info->head_of_list == MagickFalse)
588 list_info->next=list_info->head;
589 hashmap_info->head_of_list=MagickTrue;
591 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
592 if (entry != (EntryInfo *) NULL)
595 UnlockSemaphoreInfo(hashmap_info->semaphore);
598 hashmap_info->head_of_list=MagickFalse;
600 hashmap_info->next++;
602 UnlockSemaphoreInfo(hashmap_info->semaphore);
603 return((
void *) NULL);
628MagickExport
void *GetNextValueInLinkedList(LinkedListInfo *list_info)
633 assert(list_info != (LinkedListInfo *) NULL);
634 assert(list_info->signature == MagickCoreSignature);
635 LockSemaphoreInfo(list_info->semaphore);
636 if (list_info->next == (ElementInfo *) NULL)
638 UnlockSemaphoreInfo(list_info->semaphore);
639 return((
void *) NULL);
641 value=list_info->next->value;
642 list_info->next=list_info->next->next;
643 UnlockSemaphoreInfo(list_info->semaphore);
669MagickExport
size_t GetNumberOfEntriesInHashmap(
670 const HashmapInfo *hashmap_info)
672 assert(hashmap_info != (HashmapInfo *) NULL);
673 assert(hashmap_info->signature == MagickCoreSignature);
674 return(hashmap_info->entries);
701MagickExport
size_t GetNumberOfElementsInLinkedList(
702 const LinkedListInfo *list_info)
704 assert(list_info != (LinkedListInfo *) NULL);
705 assert(list_info->signature == MagickCoreSignature);
706 return(list_info->elements);
733MagickExport
void *GetValueFromHashmap(HashmapInfo *hashmap_info,
748 assert(hashmap_info != (HashmapInfo *) NULL);
749 assert(hashmap_info->signature == MagickCoreSignature);
750 if (key == (
const void *) NULL)
751 return((
void *) NULL);
752 LockSemaphoreInfo(hashmap_info->semaphore);
753 hash=hashmap_info->hash(key);
754 list_info=hashmap_info->map[hash % hashmap_info->capacity];
755 if (list_info != (LinkedListInfo *) NULL)
757 list_info->next=list_info->head;
758 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
759 while (entry != (EntryInfo *) NULL)
761 if (entry->hash == hash)
767 if (hashmap_info->compare !=
768 (MagickBooleanType (*)(
const void *,
const void *)) NULL)
769 compare=hashmap_info->compare(key,entry->key);
770 if (compare != MagickFalse)
773 UnlockSemaphoreInfo(hashmap_info->semaphore);
777 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
780 UnlockSemaphoreInfo(hashmap_info->semaphore);
781 return((
void *) NULL);
810MagickExport
void *GetValueFromLinkedList(LinkedListInfo *list_info,
822 assert(list_info != (LinkedListInfo *) NULL);
823 assert(list_info->signature == MagickCoreSignature);
824 if (index >= list_info->elements)
825 return((
void *) NULL);
826 LockSemaphoreInfo(list_info->semaphore);
829 value=list_info->head->value;
830 UnlockSemaphoreInfo(list_info->semaphore);
833 if (index == (list_info->elements-1))
835 value=list_info->tail->value;
836 UnlockSemaphoreInfo(list_info->semaphore);
839 next=list_info->head;
840 for (i=0; i < (ssize_t) index; i++)
843 UnlockSemaphoreInfo(list_info->semaphore);
870MagickExport
size_t HashPointerType(
const void *pointer)
875 hash=(size_t) pointer;
876 hash+=(~(hash << 9));
906MagickExport
size_t HashStringType(
const void *
string)
923 signature_info=AcquireSignatureInfo();
924 signature=StringToStringInfo((
const char *)
string);
925 UpdateSignature(signature_info,signature);
926 FinalizeSignature(signature_info);
927 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
929 for (i=0; i < 8; i++)
931 signature=DestroyStringInfo(signature);
932 signature_info=DestroySignatureInfo(signature_info);
959MagickExport
size_t HashStringInfoType(
const void *string_info)
973 signature_info=AcquireSignatureInfo();
974 UpdateSignature(signature_info,(
const StringInfo *) string_info);
975 FinalizeSignature(signature_info);
976 digest=GetStringInfoDatum(GetSignatureDigest(signature_info));
978 for (i=0; i < 8; i++)
980 signature_info=DestroySignatureInfo(signature_info);
1012MagickExport MagickBooleanType InsertValueInLinkedList(
1013 LinkedListInfo *list_info,
const size_t index,
const void *value)
1021 assert(list_info != (LinkedListInfo *) NULL);
1022 assert(list_info->signature == MagickCoreSignature);
1023 if (value == (
const void *) NULL)
1024 return(MagickFalse);
1025 if ((index > list_info->elements) ||
1026 (list_info->elements == list_info->capacity))
1027 return(MagickFalse);
1028 next=(ElementInfo *) AcquireMagickMemory(
sizeof(*next));
1029 if (next == (ElementInfo *) NULL)
1030 return(MagickFalse);
1031 next->value=(
void *) value;
1032 next->next=(ElementInfo *) NULL;
1033 LockSemaphoreInfo(list_info->semaphore);
1034 if (list_info->elements == 0)
1036 if (list_info->next == (ElementInfo *) NULL)
1037 list_info->next=next;
1038 list_info->head=next;
1039 list_info->tail=next;
1045 if (list_info->next == list_info->head)
1046 list_info->next=next;
1047 next->next=list_info->head;
1048 list_info->head=next;
1051 if (index == list_info->elements)
1053 if (list_info->next == (ElementInfo *) NULL)
1054 list_info->next=next;
1055 list_info->tail->next=next;
1056 list_info->tail=next;
1063 element=list_info->head;
1064 next->next=element->next;
1065 for (i=1; i < (ssize_t) index; i++)
1067 element=element->next;
1068 next->next=element->next;
1072 if (list_info->next == next->next)
1073 list_info->next=next;
1076 list_info->elements++;
1077 UnlockSemaphoreInfo(list_info->semaphore);
1113MagickExport MagickBooleanType InsertValueInSortedLinkedList(
1114 LinkedListInfo *list_info,
int (*compare)(
const void *,
const void *),
1115 void **replace,
const void *value)
1126 assert(list_info != (LinkedListInfo *) NULL);
1127 assert(list_info->signature == MagickCoreSignature);
1128 if ((compare == (
int (*)(
const void *,
const void *)) NULL) ||
1129 (value == (
const void *) NULL))
1130 return(MagickFalse);
1131 if (list_info->elements == list_info->capacity)
1132 return(MagickFalse);
1133 next=(ElementInfo *) AcquireMagickMemory(
sizeof(*next));
1134 if (next == (ElementInfo *) NULL)
1135 return(MagickFalse);
1136 next->value=(
void *) value;
1137 element=(ElementInfo *) NULL;
1138 LockSemaphoreInfo(list_info->semaphore);
1139 next->next=list_info->head;
1140 while (next->next != (ElementInfo *) NULL)
1142 i=(ssize_t) compare(value,next->next->value);
1143 if ((i < 0) || ((replace != (
void **) NULL) && (i == 0)))
1147 *replace=next->next->value;
1148 next->next=next->next->next;
1149 if (element != (ElementInfo *) NULL)
1150 element->next=(ElementInfo *) RelinquishMagickMemory(
1152 list_info->elements--;
1154 if (element != (ElementInfo *) NULL)
1157 list_info->head=next;
1161 next->next=next->next->next;
1163 if (next->next == (ElementInfo *) NULL)
1165 if (element != (ElementInfo *) NULL)
1168 list_info->head=next;
1169 list_info->tail=next;
1171 list_info->elements++;
1172 UnlockSemaphoreInfo(list_info->semaphore);
1198MagickExport MagickBooleanType IsHashmapEmpty(
const HashmapInfo *hashmap_info)
1200 assert(hashmap_info != (HashmapInfo *) NULL);
1201 assert(hashmap_info->signature == MagickCoreSignature);
1202 return(hashmap_info->entries == 0 ? MagickTrue : MagickFalse);
1227MagickExport MagickBooleanType IsLinkedListEmpty(
1228 const LinkedListInfo *list_info)
1230 assert(list_info != (LinkedListInfo *) NULL);
1231 assert(list_info->signature == MagickCoreSignature);
1232 return(list_info->elements == 0 ? MagickTrue : MagickFalse);
1260MagickExport MagickBooleanType LinkedListToArray(LinkedListInfo *list_info,
1269 assert(list_info != (LinkedListInfo *) NULL);
1270 assert(list_info->signature == MagickCoreSignature);
1271 if (array == (
void **) NULL)
1272 return(MagickFalse);
1273 LockSemaphoreInfo(list_info->semaphore);
1274 next=list_info->head;
1275 for (i=0; next != (ElementInfo *) NULL; i++)
1277 array[i]=next->value;
1280 UnlockSemaphoreInfo(list_info->semaphore);
1330MagickExport HashmapInfo *NewHashmap(
const size_t capacity,
1331 size_t (*hash)(
const void *),
1332 MagickBooleanType (*compare)(
const void *,
const void *),
1333 void *(*relinquish_key)(
void *),
void *(*relinquish_value)(
void *))
1338 hashmap_info=(HashmapInfo *) AcquireMagickMemory(
sizeof(*hashmap_info));
1339 if (hashmap_info == (HashmapInfo *) NULL)
1340 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1341 (void) memset(hashmap_info,0,
sizeof(*hashmap_info));
1342 hashmap_info->hash=HashPointerType;
1343 if (hash != (
size_t (*)(
const void *)) NULL)
1344 hashmap_info->hash=hash;
1345 hashmap_info->compare=(MagickBooleanType (*)(
const void *,
const void *)) NULL;
1346 if (compare != (MagickBooleanType (*)(
const void *,
const void *)) NULL)
1347 hashmap_info->compare=compare;
1348 hashmap_info->relinquish_key=relinquish_key;
1349 hashmap_info->relinquish_value=relinquish_value;
1350 hashmap_info->entries=0;
1351 hashmap_info->capacity=capacity;
1352 hashmap_info->map=(LinkedListInfo **) NULL;
1353 if (~capacity >= 1UL)
1354 hashmap_info->map=(LinkedListInfo **) AcquireQuantumMemory((
size_t)
1355 capacity+1UL,
sizeof(*hashmap_info->map));
1356 if (hashmap_info->map == (LinkedListInfo **) NULL)
1357 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1358 (void) memset(hashmap_info->map,0,(
size_t) capacity*
1359 sizeof(*hashmap_info->map));
1360 hashmap_info->semaphore=AllocateSemaphoreInfo();
1361 hashmap_info->signature=MagickCoreSignature;
1362 return(hashmap_info);
1388MagickExport LinkedListInfo *NewLinkedList(
const size_t capacity)
1393 list_info=(LinkedListInfo *) AcquireMagickMemory(
sizeof(*list_info));
1394 if (list_info == (LinkedListInfo *) NULL)
1395 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1396 (void) memset(list_info,0,
sizeof(*list_info));
1397 list_info->capacity=capacity == 0 ? (size_t) (~0) : capacity;
1398 list_info->elements=0;
1399 list_info->head=(ElementInfo *) NULL;
1400 list_info->tail=(ElementInfo *) NULL;
1401 list_info->next=(ElementInfo *) NULL;
1402 list_info->semaphore=AllocateSemaphoreInfo();
1403 list_info->signature=MagickCoreSignature;
1436static MagickBooleanType IncreaseHashmapCapacity(HashmapInfo *hashmap_info)
1438#define MaxCapacities 20
1441 capacities[MaxCapacities] =
1443 17, 31, 61, 131, 257, 509, 1021, 2053, 4099, 8191, 16381, 32771,
1444 65537, 131071, 262147, 524287, 1048573, 2097143, 4194301, 8388617
1469 for (i=0; i < MaxCapacities; i++)
1470 if (hashmap_info->capacity < capacities[i])
1472 if (i >= (MaxCapacities-1))
1473 return(MagickFalse);
1474 capacity=capacities[i+1];
1475 map=(LinkedListInfo **) AcquireQuantumMemory((
size_t) capacity+1UL,
1477 if (map == (LinkedListInfo **) NULL)
1478 return(MagickFalse);
1479 (void) memset(map,0,(
size_t) capacity*
sizeof(*map));
1483 for (i=0; i < (ssize_t) hashmap_info->capacity; i++)
1488 list_info=hashmap_info->map[i];
1489 if (list_info == (LinkedListInfo *) NULL)
1491 LockSemaphoreInfo(list_info->semaphore);
1492 for (next=list_info->head; next != (ElementInfo *) NULL; )
1496 entry=(EntryInfo *) element->value;
1497 map_info=map[entry->hash % capacity];
1498 if (map_info == (LinkedListInfo *) NULL)
1500 map_info=NewLinkedList(0);
1501 map[entry->hash % capacity]=map_info;
1503 map_info->next=element;
1504 element->next=map_info->head;
1505 map_info->head=element;
1506 map_info->elements++;
1508 list_info->signature=(~MagickCoreSignature);
1509 UnlockSemaphoreInfo(list_info->semaphore);
1510 DestroySemaphoreInfo(&list_info->semaphore);
1511 list_info=(LinkedListInfo *) RelinquishMagickMemory(list_info);
1513 hashmap_info->map=(LinkedListInfo **) RelinquishMagickMemory(
1515 hashmap_info->map=map;
1516 hashmap_info->capacity=capacity;
1520MagickExport MagickBooleanType PutEntryInHashmap(HashmapInfo *hashmap_info,
1521 const void *key,
const void *value)
1533 assert(hashmap_info != (HashmapInfo *) NULL);
1534 assert(hashmap_info->signature == MagickCoreSignature);
1535 if ((key == (
void *) NULL) || (value == (
void *) NULL))
1536 return(MagickFalse);
1537 next=(EntryInfo *) AcquireMagickMemory(
sizeof(*next));
1538 if (next == (EntryInfo *) NULL)
1539 return(MagickFalse);
1540 LockSemaphoreInfo(hashmap_info->semaphore);
1541 next->hash=hashmap_info->hash(key);
1542 next->key=(
void *) key;
1543 next->value=(
void *) value;
1544 list_info=hashmap_info->map[next->hash % hashmap_info->capacity];
1545 if (list_info == (LinkedListInfo *) NULL)
1547 list_info=NewLinkedList(0);
1548 hashmap_info->map[next->hash % hashmap_info->capacity]=list_info;
1552 list_info->next=list_info->head;
1553 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
1554 for (i=0; entry != (EntryInfo *) NULL; i++)
1556 if (entry->hash == next->hash)
1562 if (hashmap_info->compare !=
1563 (MagickBooleanType (*)(
const void *,
const void *)) NULL)
1564 compare=hashmap_info->compare(key,entry->key);
1565 if (compare != MagickFalse)
1567 (void) RemoveElementFromLinkedList(list_info,i);
1568 if (hashmap_info->relinquish_key != (
void *(*)(
void *)) NULL)
1569 entry->key=hashmap_info->relinquish_key(entry->key);
1570 if (hashmap_info->relinquish_value != (
void *(*)(
void *)) NULL)
1571 entry->value=hashmap_info->relinquish_value(entry->value);
1572 entry=(EntryInfo *) RelinquishMagickMemory(entry);
1576 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
1579 if (InsertValueInLinkedList(list_info,0,next) == MagickFalse)
1581 next=(EntryInfo *) RelinquishMagickMemory(next);
1582 UnlockSemaphoreInfo(hashmap_info->semaphore);
1583 return(MagickFalse);
1585 if (list_info->elements >= (hashmap_info->capacity-1))
1586 if (IncreaseHashmapCapacity(hashmap_info) == MagickFalse)
1588 UnlockSemaphoreInfo(hashmap_info->semaphore);
1589 return(MagickFalse);
1591 hashmap_info->entries++;
1592 UnlockSemaphoreInfo(hashmap_info->semaphore);
1622MagickExport
void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
1628 assert(list_info != (LinkedListInfo *) NULL);
1629 assert(list_info->signature == MagickCoreSignature);
1630 if ((list_info->elements == 0) || (value == (
const void *) NULL))
1631 return((
void *) NULL);
1632 LockSemaphoreInfo(list_info->semaphore);
1633 if (value == list_info->head->value)
1635 if (list_info->next == list_info->head)
1636 list_info->next=list_info->head->next;
1637 next=list_info->head;
1638 list_info->head=list_info->head->next;
1639 next=(ElementInfo *) RelinquishMagickMemory(next);
1646 next=list_info->head;
1647 while ((next->next != (ElementInfo *) NULL) &&
1648 (next->next->value != value))
1650 if (next->next == (ElementInfo *) NULL)
1652 UnlockSemaphoreInfo(list_info->semaphore);
1653 return((
void *) NULL);
1656 next->next=element->next;
1657 if (element == list_info->tail)
1658 list_info->tail=next;
1659 if (list_info->next == element)
1660 list_info->next=element->next;
1661 element=(ElementInfo *) RelinquishMagickMemory(element);
1663 list_info->elements--;
1664 UnlockSemaphoreInfo(list_info->semaphore);
1665 return((
void *) value);
1694MagickExport
void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
1706 assert(list_info != (LinkedListInfo *) NULL);
1707 assert(list_info->signature == MagickCoreSignature);
1708 if (index >= list_info->elements)
1709 return((
void *) NULL);
1710 LockSemaphoreInfo(list_info->semaphore);
1713 if (list_info->next == list_info->head)
1714 list_info->next=list_info->head->next;
1715 value=list_info->head->value;
1716 next=list_info->head;
1717 list_info->head=list_info->head->next;
1718 next=(ElementInfo *) RelinquishMagickMemory(next);
1725 next=list_info->head;
1726 for (i=1; i < (ssize_t) index; i++)
1729 next->next=element->next;
1730 if (element == list_info->tail)
1731 list_info->tail=next;
1732 if (list_info->next == element)
1733 list_info->next=element->next;
1734 value=element->value;
1735 element=(ElementInfo *) RelinquishMagickMemory(element);
1737 list_info->elements--;
1738 UnlockSemaphoreInfo(list_info->semaphore);
1766MagickExport
void *RemoveEntryFromHashmap(HashmapInfo *hashmap_info,
1784 assert(hashmap_info != (HashmapInfo *) NULL);
1785 assert(hashmap_info->signature == MagickCoreSignature);
1786 if (key == (
const void *) NULL)
1787 return((
void *) NULL);
1788 LockSemaphoreInfo(hashmap_info->semaphore);
1789 hash=hashmap_info->hash(key);
1790 list_info=hashmap_info->map[hash % hashmap_info->capacity];
1791 if (list_info != (LinkedListInfo *) NULL)
1793 list_info->next=list_info->head;
1794 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
1795 for (i=0; entry != (EntryInfo *) NULL; i++)
1797 if (entry->hash == hash)
1803 if (hashmap_info->compare !=
1804 (MagickBooleanType (*)(
const void *,
const void *)) NULL)
1805 compare=hashmap_info->compare(key,entry->key);
1806 if (compare != MagickFalse)
1808 entry=(EntryInfo *) RemoveElementFromLinkedList(list_info,i);
1809 if (entry == (EntryInfo *) NULL)
1811 UnlockSemaphoreInfo(hashmap_info->semaphore);
1812 return((
void *) NULL);
1814 if (hashmap_info->relinquish_key != (
void *(*)(
void *)) NULL)
1815 entry->key=hashmap_info->relinquish_key(entry->key);
1817 entry=(EntryInfo *) RelinquishMagickMemory(entry);
1818 hashmap_info->entries--;
1819 UnlockSemaphoreInfo(hashmap_info->semaphore);
1823 entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
1826 UnlockSemaphoreInfo(hashmap_info->semaphore);
1827 return((
void *) NULL);
1853MagickExport
void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
1858 assert(list_info != (LinkedListInfo *) NULL);
1859 assert(list_info->signature == MagickCoreSignature);
1860 if (list_info->elements == 0)
1861 return((
void *) NULL);
1862 LockSemaphoreInfo(list_info->semaphore);
1863 if (list_info->next == list_info->tail)
1864 list_info->next=(ElementInfo *) NULL;
1865 if (list_info->elements == 1UL)
1867 value=list_info->head->value;
1868 list_info->head=(ElementInfo *) NULL;
1869 list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);
1876 value=list_info->tail->value;
1877 next=list_info->head;
1878 while (next->next != list_info->tail)
1880 list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);
1881 list_info->tail=next;
1882 next->next=(ElementInfo *) NULL;
1884 list_info->elements--;
1885 UnlockSemaphoreInfo(list_info->semaphore);
1912MagickExport
void ResetHashmapIterator(HashmapInfo *hashmap_info)
1914 assert(hashmap_info != (HashmapInfo *) NULL);
1915 assert(hashmap_info->signature == MagickCoreSignature);
1916 LockSemaphoreInfo(hashmap_info->semaphore);
1917 hashmap_info->next=0;
1918 hashmap_info->head_of_list=MagickFalse;
1919 UnlockSemaphoreInfo(hashmap_info->semaphore);
1946MagickExport
void ResetLinkedListIterator(LinkedListInfo *list_info)
1948 assert(list_info != (LinkedListInfo *) NULL);
1949 assert(list_info->signature == MagickCoreSignature);
1950 LockSemaphoreInfo(list_info->semaphore);
1951 list_info->next=list_info->head;
1952 UnlockSemaphoreInfo(list_info->semaphore);
1980MagickPrivate
void SetHeadElementInLinkedList(LinkedListInfo *list_info,
1981 ElementInfo *element)
1986 assert(list_info != (LinkedListInfo *) NULL);
1987 assert(list_info->signature == MagickCoreSignature);
1988 assert(element != (ElementInfo *) NULL);
1989 if (element == list_info->head)
1991 prev=list_info->head;
1992 while (prev != (ElementInfo *) NULL)
1994 if (prev->next == element)
1996 prev->next=element->next;
1997 element->next=list_info->head;
1998 if (list_info->head == list_info->next)
1999 list_info->next=element;
2000 list_info->head=element;