From 29e738bdb5d05a18da2e1d89b936119fa7357184 Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 26 May 1999 09:28:30 +0000 Subject: [PATCH] These have been moved to the include directory. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4297 72102866-910b-0410-8b05-ffd578937521 --- Source/FastArray.x | 179 ------------ Source/FastMap.x | 658 --------------------------------------------- 2 files changed, 837 deletions(-) delete mode 100644 Source/FastArray.x delete mode 100644 Source/FastMap.x diff --git a/Source/FastArray.x b/Source/FastArray.x deleted file mode 100644 index 3d73987ea..000000000 --- a/Source/FastArray.x +++ /dev/null @@ -1,179 +0,0 @@ -/* A fast inline array table implementation without objc method overhead. - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * Author: Richard Frith-Macdonald - * Created: Nov 1998 - * - * This file is part of the GNUstep Base Library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include -#include - -/* To easily un-inline functions for debugging */ -#ifndef INLINE -#define INLINE inline -#endif - -#define NS_BLOCK_ASSERTIONS 1 - -/* - * This file should be INCLUDED in files wanting to use the FastArray - * functions - these are all declared inline for maximum performance. - * - * The file including this one may predefine some macros to alter - * the behaviour (default macros assume the items are NSObjects - * that are to be retained in the array) ... - * - * FAST_ARRAY_RETAIN() - * Macro to retain an array item - * - * FAST_ARRAY_RELEASE() - * Macro to release the item. - * - */ - -#ifndef FAST_ARRAY_RETAIN -#define FAST_ARRAY_RETAIN(X) [(X).o retain] -#endif - -#ifndef FAST_ARRAY_RELEASE -#define FAST_ARRAY_RELEASE(X) [(X).o release] -#endif - -typedef union { - id o; - Class c; - int i; - unsigned I; - long l; - unsigned long L; - void *p; - const void *P; - char *s; - const char *S; - SEL C; - gsu8 u8; - gsu16 u16; - gsu32 u32; -} FastArrayItem; - -struct _FastArray { - FastArrayItem *ptr; - unsigned count; - unsigned cap; - unsigned old; - NSZone *zone; -}; -typedef struct _FastArray FastArray_t; -typedef struct _FastArray *FastArray; - -static INLINE void -FastArrayAddItem(FastArray array, FastArrayItem item) -{ - if (array->count == array->cap) - { - unsigned next; - FastArrayItem *tmp; - - next = array->cap + array->old; - tmp = NSZoneRealloc(array->zone, array->ptr, next*sizeof(FastArrayItem)); - - if (tmp == 0) - { - [NSException raise: NSMallocException - format: @"failed to grow FastArray"]; - } - array->ptr = tmp; - array->old = array->cap; - array->cap = next; - } - FAST_ARRAY_RETAIN(item); - array->ptr[array->count++] = item; -} - -static INLINE void -FastArrayRemoveItemAtIndex(FastArray array, unsigned index) -{ - NSCAssert(index < array->count, NSInvalidArgumentException); - FAST_ARRAY_RELEASE(array->ptr[index]); - while (++index < array->count) - array->ptr[index-1] = array->ptr[index]; - array->count--; -} - -static INLINE void -FastArraySetItemAtIndex(FastArray array, FastArrayItem item, unsigned index) -{ - NSCAssert(index < array->count, NSInvalidArgumentException); - if (array->ptr[index].o != item.o) - { - FAST_ARRAY_RELEASE(array->ptr[index]); - FAST_ARRAY_RETAIN(item); - array->ptr[index] = item; - } -} - -static INLINE FastArrayItem -FastArrayItemAtIndex(FastArray array, unsigned index) -{ - NSCAssert(index < array->count, NSInvalidArgumentException); - return array->ptr[index]; -} - -static INLINE unsigned -FastArrayCount(FastArray array) -{ - return array->count; -} - -static INLINE void -FastArrayClear(FastArray array) -{ - if (array->ptr) - { - NSZoneFree(array->zone, (void*)array->ptr); - array->ptr = 0; - } -} - -static INLINE void -FastArrayEmpty(FastArray array) -{ - unsigned i = array->count; - - while (i-- > 0) - FAST_ARRAY_RELEASE(array->ptr[i]); - FastArrayClear(array); - array->cap = 0; - array->count = 0; -} - -static INLINE FastArray -FastArrayInitWithZoneAndCapacity(FastArray array, NSZone *zone, size_t capacity) -{ - array->zone = zone; - array->count = 0; - if (capacity < 1) - capacity = 2; - array->cap = capacity; - array->old = capacity/2; - array->ptr=(FastArrayItem*)NSZoneMalloc(zone,capacity*sizeof(FastArrayItem)); - return array; -} - - diff --git a/Source/FastMap.x b/Source/FastMap.x deleted file mode 100644 index d9e8d7026..000000000 --- a/Source/FastMap.x +++ /dev/null @@ -1,658 +0,0 @@ -/* A fast map/hash table implementation for NSObjects - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * Author: Richard Frith-Macdonald - * Created: Thu Oct 1 09:30:00 GMT 1998 - * - * Based on original o_map code by Albin L. Jones - * - * This file is part of the GNUstep Base Library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include -#include - -/* To easily un-inline functions for debugging */ -#ifndef INLINE -#define INLINE inline -#endif - -/* - * This file should be INCLUDED in files wanting to use the FastMap - * functions - these are all declared inline for maximum performance. - * - * The file including this one may predefine some macros to alter - * the behaviour (default macros assume the items are NSObjects - * that are to be retained in the table) ... - * - * FAST_MAP_HAS_VALUE - * If defined as 0, then this becomes a hash table rather than - * a map table. - * - * FAST_MAP_RETAIN_KEY() - * Macro to retain the key item in a map or hash table. - * - * FAST_MAP_RETAIN_VAL() - * Macro to retain the value item in a map table. - * - * FAST_MAP_RELEASE_KEY() - * Macro to release the key item in a map or hash table. - * - * FAST_MAP_RELEASE_VAL() - * Macro to release the value item in a map table. - * - * FAST_MAP_HASH() - * Macro to get the hash of a key item. - * - * FAST_MAP_EQUAL() - * Macro to compare two key items for equality - produces zero - * if the items are not equal. - */ - -#ifndef FAST_MAP_HAS_VALUE -#define FAST_MAP_HAS_VALUE 1 -#endif - -#ifndef FAST_MAP_RETAIN_KEY -#define FAST_MAP_RETAIN_KEY(X) [(X).o retain] -#endif - -#ifndef FAST_MAP_RELEASE_KEY -#define FAST_MAP_RELEASE_KEY(X) [(X).o release] -#endif - -#ifndef FAST_MAP_RETAIN_VAL -#define FAST_MAP_RETAIN_VAL(X) [(X).o retain] -#endif - -#ifndef FAST_MAP_RELEASE_VAL -#define FAST_MAP_RELEASE_VAL(X) [(X).o release] -#endif - -#ifndef FAST_MAP_HASH -#define FAST_MAP_HASH(X) [(X).o hash] -#endif - -#ifndef FAST_MAP_EQUAL -#define FAST_MAP_EQUAL(X,Y) [(X).o isEqual: (Y).o] -#endif - -typedef union { - id o; - NSObject *O; - Class c; - SEL C; - int i; - unsigned I; - long l; - unsigned long L; - void *p; - const void *P; - char *s; - const char *S; - gsu8 u8; - gsu16 u16; - gsu32 u32; -} FastMapItem; - -typedef struct _FastMapTable FastMapTable_t; -typedef struct _FastMapBucket FastMapBucket_t; -typedef struct _FastMapNode FastMapNode_t; -typedef struct _FastMapEnumerator FastMapEnumerator_t; - -typedef FastMapTable_t *FastMapTable; -typedef FastMapBucket_t *FastMapBucket; -typedef FastMapNode_t *FastMapNode; -typedef FastMapEnumerator_t *FastMapEnumerator; - -struct _FastMapNode { - FastMapNode nextInBucket; /* Linked list of bucket. */ - FastMapNode nextInMap; /* For enumerating. */ - FastMapItem key; -#if FAST_MAP_HAS_VALUE - FastMapItem value; -#endif -}; - -struct _FastMapBucket { - size_t nodeCount; /* Number of nodes in bucket. */ - FastMapNode firstNode; /* The linked list of nodes. */ -}; - -struct _FastMapTable { - NSZone *zone; - size_t nodeCount; /* Number of nodes in map. */ - FastMapNode firstNode; /* List for enumerating. */ - size_t bucketCount; /* Number of buckets in map. */ - FastMapBucket buckets; /* Array of buckets. */ - FastMapNode freeNodes; /* List of unused nodes. */ - size_t chunkCount; /* Number of chunks in array. */ - FastMapNode *nodeChunks; /* Chunks of allocated memory. */ -}; - -struct _FastMapEnumerator { - FastMapTable map; /* the map being enumerated. */ - FastMapNode node; /* The next node to use. */ -}; - -static INLINE FastMapBucket -FastMapPickBucket(FastMapItem key, FastMapBucket buckets, size_t bucketCount) -{ - return buckets + FAST_MAP_HASH(key) % bucketCount; -} - -static INLINE FastMapBucket -FastMapBucketForKey(FastMapTable map, FastMapItem key) -{ - return FastMapPickBucket(key, map->buckets, map->bucketCount); -} - -static INLINE void -FastMapLinkNodeIntoBucket(FastMapBucket bucket, FastMapNode node) -{ - node->nextInBucket = bucket->firstNode; - bucket->firstNode = node; -} - -static INLINE void -FastMapUnlinkNodeFromBucket(FastMapBucket bucket, FastMapNode node) -{ - if (node == bucket->firstNode) - { - bucket->firstNode = node->nextInBucket; - } - else - { - FastMapNode tmp = bucket->firstNode; - - while (tmp->nextInBucket != node) - { - tmp = tmp->nextInBucket; - } - tmp->nextInBucket = node->nextInBucket; - } - node->nextInBucket = 0; -} - -static INLINE void -FastMapLinkNodeIntoMap(FastMapTable map, FastMapNode node) -{ - node->nextInMap = map->firstNode; - map->firstNode = node; -} - -static INLINE void -FastMapUnlinkNodeFromMap(FastMapTable map, FastMapNode node) -{ - if (node == map->firstNode) - { - map->firstNode = node->nextInMap; - } - else - { - FastMapNode tmp = map->firstNode; - - while (tmp->nextInMap != node) - { - tmp = tmp->nextInMap; - } - tmp->nextInMap = node->nextInMap; - } - node->nextInMap = 0; -} - -static INLINE void -FastMapAddNodeToBucket(FastMapBucket bucket, FastMapNode node) -{ - FastMapLinkNodeIntoBucket(bucket, node); - bucket->nodeCount += 1; -} - -static INLINE void -FastMapAddNodeToMap(FastMapTable map, FastMapNode node) -{ - FastMapBucket bucket; - - bucket = FastMapBucketForKey(map, node->key); - FastMapAddNodeToBucket(bucket, node); - FastMapLinkNodeIntoMap(map, node); - map->nodeCount++; -} - -static INLINE void -FastMapRemoveNodeFromBucket(FastMapBucket bucket, FastMapNode node) -{ - bucket->nodeCount--; - FastMapUnlinkNodeFromBucket(bucket, node); -} - -static INLINE void -FastMapRemoveNodeFromMap(FastMapTable map, FastMapBucket bkt, FastMapNode node) -{ - map->nodeCount--; - FastMapUnlinkNodeFromMap(map, node); - FastMapRemoveNodeFromBucket(bkt, node); -} - -static INLINE void -FastMapRemangleBuckets(FastMapTable map, - FastMapBucket old_buckets, - size_t old_bucketCount, - FastMapBucket new_buckets, - size_t new_bucketCount) -{ - while (old_bucketCount-- > 0) - { - FastMapNode node; - - while ((node = old_buckets->firstNode) != 0) - { - FastMapBucket bkt; - - FastMapRemoveNodeFromBucket(old_buckets, node); - bkt = FastMapPickBucket(node->key, new_buckets, new_bucketCount); - FastMapAddNodeToBucket(bkt, node); - } - old_buckets++; - } -} - -static INLINE void -FastMapMoreNodes(FastMapTable map) -{ - FastMapNode *newArray; - size_t arraySize = (map->chunkCount+1)*sizeof(FastMapNode); - - newArray = (FastMapNode*)NSZoneMalloc(map->zone, arraySize); - - if (newArray) - { - FastMapNode newNodes; - size_t chunkCount; - size_t chunkSize; - - memcpy(newArray,map->nodeChunks,(map->chunkCount)*sizeof(FastMapNode)); - if (map->nodeChunks != 0) - { - NSZoneFree(map->zone, map->nodeChunks); - } - map->nodeChunks = newArray; - - if (map->chunkCount == 0) - { - chunkCount = map->bucketCount > 1 ? map->bucketCount : 2; - } - else - { - chunkCount = ((map->nodeCount>>2)+1)<<1; - } - chunkSize = chunkCount * sizeof(FastMapNode_t); - newNodes = (FastMapNode)NSZoneMalloc(map->zone, chunkSize); - if (newNodes) - { - map->nodeChunks[map->chunkCount++] = newNodes; - newNodes[--chunkCount].nextInMap = map->freeNodes; - while (chunkCount--) - { - newNodes[chunkCount].nextInMap = &newNodes[chunkCount+1]; - } - map->freeNodes = newNodes; - } - } -} - -#if FAST_MAP_HAS_VALUE -static INLINE FastMapNode -FastMapNewNode(FastMapTable map, FastMapItem key, FastMapItem value) -{ - FastMapNode node = map->freeNodes; - - if (node == 0) - { - FastMapMoreNodes(map); - node = map->freeNodes; - if (node == 0) - { - return 0; - } - } - - map->freeNodes = node->nextInMap; - node->key = key; - node->value = value; - node->nextInBucket = 0; - node->nextInMap = 0; - - return node; -} -#else -static INLINE FastMapNode -FastMapNewNode(FastMapTable map, FastMapItem key) -{ - FastMapNode node = map->freeNodes; - - if (node == 0) - { - FastMapMoreNodes(map); - node = map->freeNodes; - if (node == 0) - { - return 0; - } - } - - map->freeNodes = node->nextInMap; - node->key = key; - node->nextInBucket = 0; - node->nextInMap = 0; - return node; -} -#endif - -static INLINE void -FastMapFreeNode(FastMapTable map, FastMapNode node) -{ - FAST_MAP_RELEASE_KEY(node->key); -#if FAST_MAP_HAS_VALUE - FAST_MAP_RELEASE_VAL(node->value); -#endif - node->nextInMap = map->freeNodes; - map->freeNodes = node; -} - -static INLINE FastMapNode -FastMapNodeForKeyInBucket(FastMapBucket bucket, FastMapItem key) -{ - FastMapNode node = bucket->firstNode; - - while ((node != 0) && FAST_MAP_EQUAL(node->key, key) == NO) - { - node = node->nextInBucket; - } - return node; -} - -static INLINE FastMapNode -FastMapNodeForKey(FastMapTable map, FastMapItem key) -{ - FastMapBucket bucket; - FastMapNode node; - - if (map->nodeCount == 0) - return 0; - bucket = FastMapBucketForKey(map, key); - node = FastMapNodeForKeyInBucket(bucket, key); - return node; -} - -static INLINE void -FastMapResize(FastMapTable map, size_t new_capacity) -{ - FastMapBucket new_buckets; - size_t size = 1; - size_t old = 1; - - /* - * Find next size up in the fibonacci series - */ - while (size < new_capacity) - { - size_t tmp = old; - old = size; - size += tmp; - } - /* - * Avoid 8 - since hash functions frequently generate uneven distributions - * around powers of two - we don't want lots of keys falling into a single - * bucket. - */ - if (size == 8) size++; - - /* - * Make a new set of buckets for this map - */ - new_buckets = (FastMapBucket)NSZoneCalloc(map->zone, size, - sizeof(FastMapBucket_t)); - if (new_buckets != 0) - { - FastMapRemangleBuckets(map, - map->buckets, - map->bucketCount, - new_buckets, - size); - - if (map->buckets != 0) - { - NSZoneFree(map->zone, map->buckets); - } - map->buckets = new_buckets; - map->bucketCount = size; - } -} - -static INLINE void -FastMapRightSizeMap(FastMapTable map, size_t capacity) -{ - /* FIXME: Now, this is a guess, based solely on my intuition. If anyone - * knows of a better ratio (or other test, for that matter) and can - * provide evidence of its goodness, please get in touch with me, Albin - * L. Jones . */ - - if (3 * capacity >= 4 * map->bucketCount) - { - FastMapResize(map, (3 * capacity)/4 + 1); - } -} - -/** Enumerating **/ - -/* WARNING: You should not alter a map while an enumeration is - * in progress. The results of doing so are reasonably unpremapable. - * With that in mind, read the following warnings carefully. But - * remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT. */ - -/* IMPORTANT WARNING: Map enumerators, as I have map them up, have a - * wonderous property. Namely, that, while enumerating, one may add - * new elements (i.e., new nodes) to the map while an enumeration is - * in progress (i.e., after `o_map_enumerator_for_map()' has been - * called), and the enumeration remains the same. */ - -/* WARNING: The above warning should not, in any way, be taken as - * assurance that this property of map enumerators will be preserved - * in future editions of the library. I'm still thinking about - * this. */ - -/* IMPORTANT WARNING: Enumerators have yet another wonderous property. - * Once a node has been returned by `FastMapEnumeratorNextNode()', it may be - * removed from the map without effecting the rest of the current - * enumeration. */ - -/* EXTREMELY IMPORTANT WARNING: The purpose of this warning is point - * out that, at this time, various (i.e., many) functions depend on - * the behaviours outlined above. So be prepared for some serious - * breakage when you go fudging around with these things. */ - -static INLINE FastMapEnumerator_t -FastMapEnumeratorForMap(FastMapTable map) -{ - FastMapEnumerator_t enumerator; - - enumerator.map = map; - enumerator.node = map->firstNode; - - return enumerator; -} - -static INLINE FastMapNode -FastMapEnumeratorNextNode(FastMapEnumerator enumerator) -{ - FastMapNode node; - - node = enumerator->node; - - if (node != 0) - enumerator->node = node->nextInMap; - - /* Send back NODE. */ - return node; -} - -#if FAST_MAP_HAS_VALUE -static INLINE FastMapNode -FastMapAddPairNoRetain(FastMapTable map, FastMapItem key, FastMapItem value) -{ - FastMapNode node; - - node = FastMapNewNode(map, key, value); - - if (node != 0) - { - FastMapRightSizeMap(map, map->nodeCount); - FastMapAddNodeToMap(map, node); - } - return node; -} - -static INLINE FastMapNode -FastMapAddPair(FastMapTable map, FastMapItem key, FastMapItem value) -{ - FastMapNode node; - - FAST_MAP_RETAIN_KEY(key); - FAST_MAP_RETAIN_VAL(value); - node = FastMapNewNode(map, key, value); - - if (node != 0) - { - FastMapRightSizeMap(map, map->nodeCount); - FastMapAddNodeToMap(map, node); - } - return node; -} -#else -static INLINE FastMapNode -FastMapAddKeyNoRetain(FastMapTable map, FastMapItem key) -{ - FastMapNode node; - - node = FastMapNewNode(map, key); - - if (node != 0) - { - FastMapRightSizeMap(map, map->nodeCount); - FastMapAddNodeToMap(map, node); - } - return node; -} - -static INLINE FastMapNode -FastMapAddKey(FastMapTable map, FastMapItem key) -{ - FastMapNode node; - - FAST_MAP_RETAIN_KEY(key); - node = FastMapNewNode(map, key); - - if (node != 0) - { - FastMapRightSizeMap(map, map->nodeCount); - FastMapAddNodeToMap(map, node); - } - return node; -} -#endif - -static INLINE void -FastMapRemoveKey(FastMapTable map, FastMapItem key) -{ - FastMapBucket bucket = FastMapBucketForKey(map, key); - - if (bucket != 0) - { - FastMapNode node = FastMapNodeForKeyInBucket(bucket, key); - - if (node != 0) - { - FastMapRemoveNodeFromMap(map, bucket, node); - FastMapFreeNode(map, node); - } - } -} - -static INLINE void -FastMapCleanMap(FastMapTable map) -{ - FastMapBucket bucket = map->buckets; - int i; - - for (i = 0; i < map->bucketCount; i++) - { - while (bucket->nodeCount != 0) - { - FastMapNode node = bucket->firstNode; - - FastMapRemoveNodeFromBucket(bucket, node); - FastMapFreeNode(map, node); - } - bucket++; - } - map->firstNode = 0; - map->nodeCount = 0; -} - -static INLINE void -FastMapEmptyMap(FastMapTable map) -{ - int i; - - FastMapCleanMap(map); - if (map->buckets != 0) - { - NSZoneFree(map->zone, map->buckets); - map->buckets = 0; - map->bucketCount = 0; - } - if (map->nodeChunks != 0) - { - for (i = 0; i < map->chunkCount; i++) - { - NSZoneFree(map->zone, map->nodeChunks[i]); - } - map->chunkCount = 0; - NSZoneFree(map->zone, map->nodeChunks); - map->nodeChunks = 0; - } - map->freeNodes = 0; - map->zone = 0; -} - -static INLINE FastMapTable -FastMapInitWithZoneAndCapacity(FastMapTable map, NSZone *zone, size_t capacity) -{ - map->zone = zone; - map->nodeCount = 0; - map->bucketCount = 0; - map->firstNode = 0; - map->buckets = 0; - map->nodeChunks = 0; - map->freeNodes = 0; - map->chunkCount = 0; - FastMapRightSizeMap(map, capacity); - FastMapMoreNodes(map); -} - -