]>
git.saurik.com Git - wxWidgets.git/blob - src/common/hash.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxHashTable implementation
4 // Author: Julian Smart
5 // Modified by: VZ at 25.02.00: type safe hashes with WX_DECLARE_HASH()
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "hash.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 IMPLEMENT_DYNAMIC_CLASS(wxHashTable
, wxObject
)
48 // ============================================================================
50 // ============================================================================
52 // ----------------------------------------------------------------------------
53 // wxHashTablleBase for working with "void *" data
54 // ----------------------------------------------------------------------------
56 wxHashTableBase::wxHashTableBase()
58 m_deleteContents
= FALSE
;
59 m_hashTable
= (wxListBase
**)NULL
;
62 m_keyType
= wxKEY_NONE
;
65 void wxHashTableBase::Create(wxKeyType keyType
, size_t size
)
71 m_hashTable
= new wxListBase
*[size
];
72 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
74 m_hashTable
[n
] = (wxListBase
*) NULL
;
78 void wxHashTableBase::Destroy()
82 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
84 delete m_hashTable
[n
];
87 delete [] m_hashTable
;
89 m_hashTable
= (wxListBase
**)NULL
;
95 void wxHashTableBase::DeleteContents(bool flag
)
97 m_deleteContents
= flag
;
98 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
100 if ( m_hashTable
[n
] )
102 m_hashTable
[n
]->DeleteContents(flag
);
107 wxNodeBase
*wxHashTableBase::GetNode(long key
, long value
) const
109 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
112 if ( m_hashTable
[slot
] )
114 node
= m_hashTable
[slot
]->Find(wxListKey(value
));
118 node
= (wxNodeBase
*)NULL
;
124 #if WXWIN_COMPATIBILITY_2_4
126 // ----------------------------------------------------------------------------
128 // ----------------------------------------------------------------------------
130 wxHashTableLong::~wxHashTableLong()
135 void wxHashTableLong::Init(size_t size
)
138 m_values
= new wxArrayLong
*[size
];
139 m_keys
= new wxArrayLong
*[size
];
141 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
144 m_keys
[n
] = (wxArrayLong
*)NULL
;
150 void wxHashTableLong::Create(size_t size
)
155 void wxHashTableLong::Destroy()
157 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
169 void wxHashTableLong::Put(long key
, long value
)
171 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
173 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
177 m_keys
[slot
] = new wxArrayLong
;
178 m_values
[slot
] = new wxArrayLong
;
181 m_keys
[slot
]->Add(key
);
182 m_values
[slot
]->Add(value
);
187 long wxHashTableLong::Get(long key
) const
189 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
191 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
193 wxArrayLong
*keys
= m_keys
[slot
];
196 size_t count
= keys
->GetCount();
197 for ( size_t n
= 0; n
< count
; n
++ )
199 if ( keys
->Item(n
) == key
)
201 return m_values
[slot
]->Item(n
);
209 long wxHashTableLong::Delete(long key
)
211 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
213 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
215 wxArrayLong
*keys
= m_keys
[slot
];
218 size_t count
= keys
->GetCount();
219 for ( size_t n
= 0; n
< count
; n
++ )
221 if ( keys
->Item(n
) == key
)
223 long val
= m_values
[slot
]->Item(n
);
226 m_values
[slot
]->RemoveAt(n
);
238 // ----------------------------------------------------------------------------
239 // wxStringHashTable: more efficient than storing strings in a list
240 // ----------------------------------------------------------------------------
242 wxStringHashTable::wxStringHashTable(size_t sizeTable
)
244 m_keys
= new wxArrayLong
*[sizeTable
];
245 m_values
= new wxArrayString
*[sizeTable
];
247 m_hashSize
= sizeTable
;
248 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
250 m_values
[n
] = (wxArrayString
*)NULL
;
251 m_keys
[n
] = (wxArrayLong
*)NULL
;
255 wxStringHashTable::~wxStringHashTable()
260 void wxStringHashTable::Destroy()
262 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
273 void wxStringHashTable::Put(long key
, const wxString
& value
)
275 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
277 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
281 m_keys
[slot
] = new wxArrayLong
;
282 m_values
[slot
] = new wxArrayString
;
285 m_keys
[slot
]->Add(key
);
286 m_values
[slot
]->Add(value
);
289 wxString
wxStringHashTable::Get(long key
, bool *wasFound
) const
291 wxCHECK_MSG( m_hashSize
, _T(""), _T("must call Create() first") );
293 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
295 wxArrayLong
*keys
= m_keys
[slot
];
298 size_t count
= keys
->GetCount();
299 for ( size_t n
= 0; n
< count
; n
++ )
301 if ( keys
->Item(n
) == key
)
306 return m_values
[slot
]->Item(n
);
317 bool wxStringHashTable::Delete(long key
) const
319 wxCHECK_MSG( m_hashSize
, FALSE
, _T("must call Create() first") );
321 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
323 wxArrayLong
*keys
= m_keys
[slot
];
326 size_t count
= keys
->GetCount();
327 for ( size_t n
= 0; n
< count
; n
++ )
329 if ( keys
->Item(n
) == key
)
332 m_values
[slot
]->RemoveAt(n
);
341 #endif // WXWIN_COMPATIBILITY_2_4
343 // ----------------------------------------------------------------------------
344 // old not type safe wxHashTable
345 // ----------------------------------------------------------------------------
347 wxHashTable::wxHashTable (int the_key_type
, int size
)
350 hash_table
= (wxList
**) NULL
;
351 Create(the_key_type
, size
);
353 m_deleteContents
= FALSE
;
356 current_position = -1;
357 current_node = (wxNode *) NULL;
359 key_type = the_key_type;
360 hash_table = new wxList *[size];
362 for (i = 0; i < size; i++)
363 hash_table[i] = (wxList *) NULL;
367 wxHashTable::~wxHashTable ()
372 void wxHashTable::Destroy()
374 if (!hash_table
) return;
376 for (i
= 0; i
< n
; i
++)
378 delete hash_table
[i
];
383 bool wxHashTable::Create(int the_key_type
, int size
)
388 current_position
= -1;
389 current_node
= (wxNode
*) NULL
;
391 key_type
= the_key_type
;
392 hash_table
= new wxList
*[size
];
394 for (i
= 0; i
< size
; i
++)
395 hash_table
[i
] = (wxList
*) NULL
;
400 void wxHashTable::DoCopy(const wxHashTable
& table
)
403 m_count
= table
.m_count
;
404 current_position
= table
.current_position
;
405 current_node
= NULL
; // doesn't matter - Next() will reconstruct it
406 key_type
= table
.key_type
;
408 hash_table
= new wxList
*[n
];
409 for (int i
= 0; i
< n
; i
++) {
410 if (table
.hash_table
[i
] == NULL
)
411 hash_table
[i
] = NULL
;
413 hash_table
[i
] = new wxList(key_type
);
414 *(hash_table
[i
]) = *(table
.hash_table
[i
]);
419 void wxHashTable::Put (long key
, long value
, wxObject
* object
)
424 int position
= (int) (k
% n
);
425 if (position
< 0) position
= -position
;
427 if (!hash_table
[position
])
429 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
430 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
433 hash_table
[position
]->Append (value
, object
);
437 void wxHashTable::Put (long key
, const wxChar
*value
, wxObject
* object
)
442 int position
= (int) (k
% n
);
443 if (position
< 0) position
= -position
;
445 if (!hash_table
[position
])
447 hash_table
[position
] = new wxList (wxKEY_STRING
);
448 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
451 hash_table
[position
]->Append (value
, object
);
455 void wxHashTable::Put (long key
, wxObject
* object
)
460 int position
= (int) (k
% n
);
461 if (position
< 0) position
= -position
;
463 if (!hash_table
[position
])
465 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
466 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
469 hash_table
[position
]->Append (k
, object
);
473 void wxHashTable::Put (const wxChar
*key
, wxObject
* object
)
475 int position
= (int) (MakeKey (key
) % n
);
476 if (position
< 0) position
= -position
;
478 if (!hash_table
[position
])
480 hash_table
[position
] = new wxList (wxKEY_STRING
);
481 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
484 hash_table
[position
]->Append (key
, object
);
488 wxObject
*wxHashTable::Get (long key
, long value
) const
493 int position
= (int) (k
% n
);
494 if (position
< 0) position
= -position
;
496 if (!hash_table
[position
])
497 return (wxObject
*) NULL
;
500 wxNode
*node
= hash_table
[position
]->Find (value
);
502 return node
->GetData ();
504 return (wxObject
*) NULL
;
508 wxObject
*wxHashTable::Get (long key
, const wxChar
*value
) const
513 int position
= (int) (k
% n
);
514 if (position
< 0) position
= -position
;
516 if (!hash_table
[position
])
517 return (wxObject
*) NULL
;
520 wxNode
*node
= hash_table
[position
]->Find (value
);
522 return node
->GetData ();
524 return (wxObject
*) NULL
;
528 wxObject
*wxHashTable::Get (long key
) const
533 int position
= (int) (k
% n
);
534 if (position
< 0) position
= -position
;
536 if (!hash_table
[position
])
537 return (wxObject
*) NULL
;
540 wxNode
*node
= hash_table
[position
]->Find (k
);
541 return node
? node
->GetData () : (wxObject
*)NULL
;
545 wxObject
*wxHashTable::Get (const wxChar
*key
) const
547 int position
= (int) (MakeKey (key
) % n
);
548 if (position
< 0) position
= -position
;
550 if (!hash_table
[position
])
551 return (wxObject
*) NULL
;
554 wxNode
*node
= hash_table
[position
]->Find (key
);
555 return node
? node
->GetData () : (wxObject
*)NULL
;
559 wxObject
*wxHashTable::Delete (long key
)
564 int position
= (int) (k
% n
);
565 if (position
< 0) position
= -position
;
567 if (!hash_table
[position
])
568 return (wxObject
*) NULL
;
571 wxNode
*node
= hash_table
[position
]->Find (k
);
574 wxObject
*data
= node
->GetData ();
580 return (wxObject
*) NULL
;
584 wxObject
*wxHashTable::Delete (const wxChar
*key
)
586 int position
= (int) (MakeKey (key
) % n
);
587 if (position
< 0) position
= -position
;
589 if (!hash_table
[position
])
590 return (wxObject
*) NULL
;
593 wxNode
*node
= hash_table
[position
]->Find (key
);
596 wxObject
*data
= node
->GetData ();
602 return (wxObject
*) NULL
;
606 wxObject
*wxHashTable::Delete (long key
, int value
)
611 int position
= (int) (k
% n
);
612 if (position
< 0) position
= -position
;
614 if (!hash_table
[position
])
615 return (wxObject
*) NULL
;
618 wxNode
*node
= hash_table
[position
]->Find (value
);
621 wxObject
*data
= node
->GetData ();
627 return (wxObject
*) NULL
;
631 wxObject
*wxHashTable::Delete (long key
, const wxChar
*value
)
633 int position
= (int) (key
% n
);
634 if (position
< 0) position
= -position
;
636 if (!hash_table
[position
])
637 return (wxObject
*) NULL
;
640 wxNode
*node
= hash_table
[position
]->Find (value
);
643 wxObject
*data
= node
->GetData ();
649 return (wxObject
*) NULL
;
653 long wxHashTable::MakeKey (const wxChar
*string
) const
658 int_key
+= (wxUChar
) *string
++;
663 void wxHashTable::BeginFind ()
665 current_position
= -1;
666 current_node
= (wxNode
*) NULL
;
669 wxNode
*wxHashTable::Next ()
671 wxNode
*found
= (wxNode
*) NULL
;
673 while (!end
&& !found
)
678 if (current_position
>= n
)
680 current_position
= -1;
681 current_node
= (wxNode
*) NULL
;
686 if (hash_table
[current_position
])
688 current_node
= hash_table
[current_position
]->GetFirst ();
689 found
= current_node
;
695 current_node
= current_node
->GetNext ();
696 found
= current_node
;
702 void wxHashTable::DeleteContents (bool flag
)
705 m_deleteContents
= flag
;
706 for (i
= 0; i
< n
; i
++)
709 hash_table
[i
]->DeleteContents (flag
);
713 void wxHashTable::Clear ()
718 for (i
= 0; i
< n
; i
++)
721 hash_table
[i
]->Clear ();