app_server: Drop custom HashTable and use HashMap instead.
Change-Id: I7d5aae6a7fd2b4f47704a931a23eee09a4eedcac Reviewed-on: https://review.haiku-os.org/c/haiku/+/2323 Reviewed-by: John Scipione <jscipione@gmail.com>
This commit is contained in:
parent
1ba9396139
commit
d4dbce2983
@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
|
||||
|
||||
#include "HashTable.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <stdlib.h>
|
||||
//#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
struct HashTable::entry {
|
||||
entry* next;
|
||||
Hashable* value;
|
||||
};
|
||||
|
||||
|
||||
HashTable::HashTable(bool owning, int32 capacity, float loadFactor)
|
||||
:
|
||||
fTable(NULL),
|
||||
fCount(0),
|
||||
fThreshold(0),
|
||||
fOwning(owning)
|
||||
{
|
||||
if (capacity < 10)
|
||||
capacity = 10;
|
||||
if (loadFactor <= 0.3)
|
||||
loadFactor = 0.3;
|
||||
|
||||
fLoadFactor = loadFactor;
|
||||
fCapacity = capacity;
|
||||
}
|
||||
|
||||
|
||||
HashTable::~HashTable()
|
||||
{
|
||||
MakeEmpty(fOwning);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HashTable::MakeEmpty(bool deleteValues)
|
||||
{
|
||||
if (fTable == NULL)
|
||||
return;
|
||||
|
||||
for (int32 index = fCapacity; --index >= 0;) {
|
||||
struct entry *entry, *next;
|
||||
|
||||
for (entry = fTable[index]; entry != NULL; entry = next) {
|
||||
next = entry->next;
|
||||
|
||||
if (deleteValues)
|
||||
delete entry->value;
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
free(fTable);
|
||||
fTable = NULL;
|
||||
}
|
||||
|
||||
|
||||
Hashable *
|
||||
HashTable::GetValue(Hashable& key) const
|
||||
{
|
||||
struct entry* entry = _GetHashEntry(key);
|
||||
|
||||
return entry != NULL ? entry->value : NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
HashTable::AddItem(Hashable *value)
|
||||
{
|
||||
struct entry *entry = _GetHashEntry(*value);
|
||||
int32 hash = value->Hash();
|
||||
int32 index;
|
||||
|
||||
// already in hash?
|
||||
if (entry != NULL)
|
||||
return true;
|
||||
|
||||
if (fCount >= fThreshold)
|
||||
_Rehash();
|
||||
|
||||
index = hash % fCapacity;
|
||||
|
||||
entry = new (nothrow) HashTable::entry;
|
||||
if (entry == NULL)
|
||||
return false;
|
||||
|
||||
entry->value = value;
|
||||
entry->next = fTable[index];
|
||||
fTable[index] = entry;
|
||||
fCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Hashable *
|
||||
HashTable::RemoveItem(Hashable& key)
|
||||
{
|
||||
struct entry* previous = NULL;
|
||||
struct entry* entry;
|
||||
uint32 hash;
|
||||
int32 index;
|
||||
|
||||
if (fTable == NULL)
|
||||
return NULL;
|
||||
|
||||
hash = key.Hash();
|
||||
index = hash % fCapacity;
|
||||
|
||||
for (entry = fTable[index]; entry != NULL; entry = entry->next) {
|
||||
if (entry->value->Hash() == hash && entry->value->CompareTo(key)) {
|
||||
// found value in array
|
||||
Hashable* value;
|
||||
|
||||
if (previous)
|
||||
previous->next = entry->next;
|
||||
else
|
||||
fTable[index] = entry->next;
|
||||
|
||||
fCount--;
|
||||
value = entry->value;
|
||||
delete entry;
|
||||
return value;
|
||||
}
|
||||
|
||||
previous = entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
HashTable::_Rehash()
|
||||
{
|
||||
struct entry** newTable;
|
||||
int32 oldCapacity = fCapacity;
|
||||
int32 newCapacity, i;
|
||||
|
||||
if (fCount != 0)
|
||||
newCapacity = oldCapacity * 2 + 1;
|
||||
else
|
||||
newCapacity = fCapacity;
|
||||
|
||||
newTable = (struct entry **)malloc(newCapacity * sizeof(struct entry *));
|
||||
if (newTable == NULL)
|
||||
return false;
|
||||
|
||||
memset(newTable, 0, newCapacity * sizeof(struct entry *));
|
||||
|
||||
if (fTable != NULL) {
|
||||
// repopulate the entries into the new array
|
||||
for (i = fCapacity; i-- > 0;) {
|
||||
struct entry* entry;
|
||||
struct entry* next;
|
||||
|
||||
for (entry = fTable[i]; entry != NULL; entry = next) {
|
||||
next = entry->next;
|
||||
|
||||
int32 index = entry->value->Hash() % newCapacity;
|
||||
entry->next = newTable[index];
|
||||
newTable[index] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
free(fTable);
|
||||
}
|
||||
|
||||
fTable = newTable;
|
||||
fCapacity = newCapacity;
|
||||
fThreshold = int32(newCapacity * fLoadFactor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
struct HashTable::entry *
|
||||
HashTable::_GetHashEntry(Hashable& key) const
|
||||
{
|
||||
struct entry* entry;
|
||||
uint32 hash = key.Hash();
|
||||
|
||||
if (fTable == NULL)
|
||||
return NULL;
|
||||
|
||||
for (entry = fTable[hash % fCapacity]; entry != NULL; entry = entry->next) {
|
||||
if (entry->value->Hash() == hash && entry->value->CompareTo(key))
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef _HASH_TABLE_H_
|
||||
#define _HASH_TABLE_H_
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
class Hashable {
|
||||
public:
|
||||
virtual ~Hashable() {};
|
||||
virtual uint32 Hash() const = 0;
|
||||
virtual bool CompareTo(Hashable& hashable) const = 0;
|
||||
};
|
||||
|
||||
class HashTable {
|
||||
public:
|
||||
HashTable(bool owning = false, int32 capacity = 100, float loadFactor = 0.75);
|
||||
~HashTable();
|
||||
|
||||
void MakeEmpty(bool deleteValues = true);
|
||||
bool IsEmpty() const { return fCount == 0; }
|
||||
bool ContainsKey(Hashable& key) const { return _GetHashEntry(key) != NULL; }
|
||||
int32 CountItems() const { return fCount; }
|
||||
|
||||
Hashable *GetValue(Hashable& key) const;
|
||||
|
||||
bool AddItem(Hashable* value);
|
||||
Hashable *RemoveItem(Hashable& key);
|
||||
|
||||
protected:
|
||||
struct entry;
|
||||
|
||||
bool _Rehash();
|
||||
entry *_GetHashEntry(Hashable& key) const;
|
||||
|
||||
entry** fTable;
|
||||
int32 fCapacity, fCount, fThreshold;
|
||||
float fLoadFactor;
|
||||
bool fOwning;
|
||||
};
|
||||
|
||||
#endif /* HASHTABLE_H */
|
@ -70,7 +70,6 @@ Server app_server :
|
||||
DrawState.cpp
|
||||
EventDispatcher.cpp
|
||||
EventStream.cpp
|
||||
HashTable.cpp
|
||||
InputManager.cpp
|
||||
IntPoint.cpp
|
||||
IntRect.cpp
|
||||
|
@ -406,7 +406,7 @@ FontManager::_RemoveStyle(font_directory& directory, FontStyle* style)
|
||||
directory.styles.RemoveItem(style);
|
||||
directory.revision++;
|
||||
|
||||
fStyleHashTable.RemoveItem(*style);
|
||||
fStyleHashTable.Remove(FontKey(style->Family()->ID(), style->ID()));
|
||||
|
||||
style->Release();
|
||||
}
|
||||
@ -619,7 +619,7 @@ FontManager::_AddFont(font_directory& directory, BEntry& entry)
|
||||
}
|
||||
|
||||
directory.styles.AddItem(style);
|
||||
fStyleHashTable.AddItem(style);
|
||||
fStyleHashTable.Put(FontKey(style->Family()->ID(), style->ID()), style);
|
||||
|
||||
if (directory.AlreadyScanned())
|
||||
directory.revision++;
|
||||
@ -981,7 +981,7 @@ FontFamily*
|
||||
FontManager::GetFamily(uint16 familyID) const
|
||||
{
|
||||
FontKey key(familyID, 0);
|
||||
FontStyle* style = (FontStyle*)fStyleHashTable.GetValue(key);
|
||||
FontStyle* style = fStyleHashTable.Get(key);
|
||||
if (style != NULL)
|
||||
return style->Family();
|
||||
|
||||
@ -1074,7 +1074,7 @@ FontStyle*
|
||||
FontManager::GetStyle(uint16 familyID, uint16 styleID) const
|
||||
{
|
||||
FontKey key(familyID, styleID);
|
||||
return (FontStyle*)fStyleHashTable.GetValue(key);
|
||||
return fStyleHashTable.Get(key);
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,8 +10,7 @@
|
||||
#define FONT_MANAGER_H
|
||||
|
||||
|
||||
#include "HashTable.h"
|
||||
|
||||
#include <HashMap.h>
|
||||
#include <Looper.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
@ -111,6 +110,25 @@ private:
|
||||
|
||||
FT_CharMap _GetSupportedCharmap(const FT_Face& face);
|
||||
|
||||
private:
|
||||
struct FontKey {
|
||||
FontKey(uint16 family, uint16 style)
|
||||
: familyID(family), styleID(style) {}
|
||||
|
||||
uint32 GetHashCode() const
|
||||
{
|
||||
return familyID | (styleID << 16UL);
|
||||
}
|
||||
|
||||
bool operator==(const FontKey& other) const
|
||||
{
|
||||
return familyID == other.familyID
|
||||
&& styleID == other.styleID;
|
||||
}
|
||||
|
||||
uint16 familyID, styleID;
|
||||
};
|
||||
|
||||
private:
|
||||
status_t fInitStatus;
|
||||
|
||||
@ -122,7 +140,7 @@ private:
|
||||
MappingList fMappings;
|
||||
FamilyList fFamilies;
|
||||
|
||||
HashTable fStyleHashTable;
|
||||
HashMap<FontKey, FontStyle*> fStyleHashTable;
|
||||
|
||||
ServerFont* fDefaultPlainFont;
|
||||
ServerFont* fDefaultBoldFont;
|
||||
|
@ -86,22 +86,6 @@ FontStyle::~FontStyle()
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
FontStyle::Hash() const
|
||||
{
|
||||
return (ID() << 16) | fFamily->ID();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FontStyle::CompareTo(Hashable& other) const
|
||||
{
|
||||
// our hash values are unique (unless you have more than 65536 font
|
||||
// families installed...)
|
||||
return Hash() == other.Hash();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FontStyle::Lock()
|
||||
{
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "ReferenceCounting.h"
|
||||
#include "HashTable.h"
|
||||
|
||||
|
||||
struct node_ref;
|
||||
@ -29,24 +28,6 @@ class FontFamily;
|
||||
class ServerFont;
|
||||
|
||||
|
||||
class FontKey : public Hashable {
|
||||
public:
|
||||
FontKey(uint16 familyID, uint16 styleID)
|
||||
: fHash(familyID | (styleID << 16UL))
|
||||
{
|
||||
}
|
||||
virtual ~FontKey() {};
|
||||
|
||||
virtual uint32 Hash() const
|
||||
{ return fHash; }
|
||||
virtual bool CompareTo(Hashable& other) const
|
||||
{ return fHash == other.Hash(); }
|
||||
|
||||
private:
|
||||
uint32 fHash;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\class FontStyle FontStyle.h
|
||||
\brief Object used to represent a font style
|
||||
@ -54,15 +35,12 @@ class FontKey : public Hashable {
|
||||
FontStyle objects help abstract a lot of the font engine details while
|
||||
still offering plenty of information the style in question.
|
||||
*/
|
||||
class FontStyle : public ReferenceCounting, public Hashable {
|
||||
class FontStyle : public ReferenceCounting {
|
||||
public:
|
||||
FontStyle(node_ref& nodeRef, const char* path,
|
||||
FT_Face face);
|
||||
virtual ~FontStyle();
|
||||
|
||||
virtual uint32 Hash() const;
|
||||
virtual bool CompareTo(Hashable& other) const;
|
||||
|
||||
const node_ref& NodeRef() const { return fNodeRef; }
|
||||
|
||||
bool Lock();
|
||||
|
Loading…
Reference in New Issue
Block a user