9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * OpenHashTable, Haiku Guest Additions.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Copyright (C) 2012 Oracle Corporation
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * available from http://www.virtualbox.org. This file is free software;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * General Public License (GPL) as published by the Free Software
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * This code is based on:
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * VirtualBox Guest Additions for Haiku.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Copyright 2007, Hugo Santos. All Rights Reserved.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Distributed under the terms of the MIT License.
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync The Definition template must have four methods: `HashKey', `Hash',
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync `Compare' and `GetLink;. It must also define several types as shown in the
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync following example:
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync struct Foo {
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync Foo* fNext;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync struct HashTableDefinition {
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync typedef int KeyType;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync typedef Foo ValueType;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync size_t HashKey(int key) const
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return key >> 1;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync size_t Hash(Foo* value) const
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return HashKey(value->bar);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync bool Compare(int key, Foo* value) const
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return value->bar == key;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync Foo*& GetLink(Foo* value) const
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return value->fNext;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsynctemplate<typename Definition, bool AutoExpand = true,
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync bool CheckDuplicates = false, typename Allocator = MallocAllocator>
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync typedef BOpenHashTable<Definition, AutoExpand, CheckDuplicates> HashTable;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // All allocations are of power of 2 lengths.
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // regrowth factor: 200 / 256 = 78.125%
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // 50 / 256 = 19.53125%
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync BOpenHashTable(const Definition& definition, const Allocator& allocator)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync else if (AutoExpand && fItemCount >= (fTableSize * 200 / 256))
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // TODO: a ValueType* Remove(const KeyType& key) method is missing
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return false;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return true;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync size_t index = fDefinition.Hash(value) & (fTableSize - 1);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return false;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return true;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /*! Removes all elements from the hash table. No resizing happens. The
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync elements are not deleted. If \a returnElements is \c true, the method
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync returns all elements chained via their hash table link.
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // iterate through all buckets
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // add the bucket to the list
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // update nextPointer to point to the fNext of the last
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // element in the bucket
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync memset(this->fTable, 0, sizeof(ValueType*) * this->fTableSize);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /*! If the table needs resizing, the number of bytes for the required
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync allocation is returned. If no resizing is needed, 0 is returned.
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // grow table
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync else if (size > kMinimumSize && fItemCount < size * 50 / 256)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // shrink table
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /*! Resizes the table using the given allocation. The allocation must not
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync be \c NULL. It must be of size \a size, which must a value returned
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync earlier by ResizeNeeded(). If the size requirements have changed in the
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync meantime, the method free()s the given allocation and returns \c false,
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync unless \a force is \c true, in which case the supplied allocation is
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync used in any event.
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync Otherwise \c true is returned.
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync If \a oldTable is non-null and resizing is successful, the old table
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync will not be freed, but will be returned via this parameter instead.
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync bool Resize(void* allocation, size_t size, bool force = false,
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return false;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync _Resize((ValueType**)allocation, size / sizeof(ValueType*), oldTable);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return true;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync Iterator(const HashTable* table, size_t index, ValueType* value)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // get the first one
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync while (fNext == NULL && fIndex < fTable->fTableSize)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync // for g++ 2.95
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync void _Insert(ValueType** table, size_t tableSize, ValueType* value)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync size_t index = fDefinition.Hash(value) & (tableSize - 1);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync = (ValueType**)fAllocator.Allocate(sizeof(ValueType*) * newSize);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return false;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return true;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync void _Resize(ValueType** newTable, size_t newSize, void** _oldTable = NULL)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return true;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync return false;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync#endif // _KERNEL_UTIL_OPEN_HASH_TABLE_H