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:
Augustin Cavalier 2020-03-07 21:51:35 -05:00 committed by Adrien Destugues
parent 1ba9396139
commit d4dbce2983
7 changed files with 26 additions and 301 deletions

View File

@ -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;
}

View File

@ -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 */

View File

@ -70,7 +70,6 @@ Server app_server :
DrawState.cpp
EventDispatcher.cpp
EventStream.cpp
HashTable.cpp
InputManager.cpp
IntPoint.cpp
IntRect.cpp

View File

@ -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);
}

View File

@ -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;

View File

@ -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()
{

View File

@ -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();