]>
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 and Markus Holzem
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"
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 IMPLEMENT_DYNAMIC_CLASS(wxHashTable
, wxObject
)
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
51 // wxHashTablleBase for working with "void *" data
52 // ----------------------------------------------------------------------------
54 wxHashTableBase::wxHashTableBase()
56 m_deleteContents
= FALSE
;
57 m_hashTable
= (wxListBase
**)NULL
;
60 m_keyType
= wxKEY_NONE
;
63 void wxHashTableBase::Create(wxKeyType keyType
, size_t size
)
69 m_hashTable
= new wxListBase
*[size
];
70 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
72 m_hashTable
[n
] = (wxListBase
*) NULL
;
76 void wxHashTableBase::Destroy()
80 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
82 delete m_hashTable
[n
];
85 delete [] m_hashTable
;
87 m_hashTable
= (wxListBase
**)NULL
;
93 void wxHashTableBase::DeleteContents(bool flag
)
95 m_deleteContents
= flag
;
96 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
100 m_hashTable
[n
]->DeleteContents(flag
);
105 wxNodeBase
*wxHashTableBase::GetNode(long key
, long value
) const
107 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
110 if ( m_hashTable
[slot
] )
112 node
= m_hashTable
[slot
]->Find(wxListKey(value
));
116 node
= (wxNodeBase
*)NULL
;
122 // ----------------------------------------------------------------------------
124 // ----------------------------------------------------------------------------
126 wxHashTableLong::~wxHashTableLong()
131 void wxHashTableLong::Init(size_t size
)
134 m_values
= new wxArrayLong
*[size
];
135 m_keys
= new wxArrayLong
*[size
];
137 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
140 m_keys
[n
] = (wxArrayLong
*)NULL
;
146 void wxHashTableLong::Create(size_t size
)
151 void wxHashTableLong::Destroy()
153 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
165 void wxHashTableLong::Put(long key
, long value
)
167 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
169 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
173 m_keys
[slot
] = new wxArrayLong
;
174 m_values
[slot
] = new wxArrayLong
;
177 m_keys
[slot
]->Add(key
);
178 m_values
[slot
]->Add(value
);
183 long wxHashTableLong::Get(long key
) const
185 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
187 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
189 wxArrayLong
*keys
= m_keys
[slot
];
192 size_t count
= keys
->GetCount();
193 for ( size_t n
= 0; n
< count
; n
++ )
195 if ( keys
->Item(n
) == key
)
197 return m_values
[slot
]->Item(n
);
205 long wxHashTableLong::Delete(long key
)
207 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
209 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
211 wxArrayLong
*keys
= m_keys
[slot
];
214 size_t count
= keys
->GetCount();
215 for ( size_t n
= 0; n
< count
; n
++ )
217 if ( keys
->Item(n
) == key
)
219 long val
= m_values
[slot
]->Item(n
);
222 m_values
[slot
]->RemoveAt(n
);
234 // ----------------------------------------------------------------------------
235 // wxStringHashTable: more efficient than storing strings in a list
236 // ----------------------------------------------------------------------------
238 wxStringHashTable::wxStringHashTable(size_t sizeTable
)
240 m_keys
= new wxArrayLong
*[sizeTable
];
241 m_values
= new wxArrayString
*[sizeTable
];
243 m_hashSize
= sizeTable
;
244 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
246 m_values
[n
] = (wxArrayString
*)NULL
;
247 m_keys
[n
] = (wxArrayLong
*)NULL
;
251 wxStringHashTable::~wxStringHashTable()
256 void wxStringHashTable::Destroy()
258 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
269 void wxStringHashTable::Put(long key
, const wxString
& value
)
271 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
273 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
277 m_keys
[slot
] = new wxArrayLong
;
278 m_values
[slot
] = new wxArrayString
;
281 m_keys
[slot
]->Add(key
);
282 m_values
[slot
]->Add(value
);
285 wxString
wxStringHashTable::Get(long key
, bool *wasFound
) const
287 wxCHECK_MSG( m_hashSize
, _T(""), _T("must call Create() first") );
289 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
291 wxArrayLong
*keys
= m_keys
[slot
];
294 size_t count
= keys
->GetCount();
295 for ( size_t n
= 0; n
< count
; n
++ )
297 if ( keys
->Item(n
) == key
)
302 return m_values
[slot
]->Item(n
);
313 bool wxStringHashTable::Delete(long key
) const
315 wxCHECK_MSG( m_hashSize
, FALSE
, _T("must call Create() first") );
317 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
319 wxArrayLong
*keys
= m_keys
[slot
];
322 size_t count
= keys
->GetCount();
323 for ( size_t n
= 0; n
< count
; n
++ )
325 if ( keys
->Item(n
) == key
)
328 m_values
[slot
]->RemoveAt(n
);
337 // ----------------------------------------------------------------------------
338 // old not type safe wxHashTable
339 // ----------------------------------------------------------------------------
341 wxHashTable::wxHashTable (int the_key_type
, int size
)
344 hash_table
= (wxList
**) NULL
;
345 Create(the_key_type
, size
);
347 m_deleteContents
= FALSE
;
350 current_position = -1;
351 current_node = (wxNode *) NULL;
353 key_type = the_key_type;
354 hash_table = new wxList *[size];
356 for (i = 0; i < size; i++)
357 hash_table[i] = (wxList *) NULL;
361 wxHashTable::~wxHashTable ()
366 void wxHashTable::Destroy()
368 if (!hash_table
) return;
370 for (i
= 0; i
< n
; i
++)
372 delete hash_table
[i
];
377 bool wxHashTable::Create(int the_key_type
, int size
)
382 current_position
= -1;
383 current_node
= (wxNode
*) NULL
;
385 key_type
= the_key_type
;
386 hash_table
= new wxList
*[size
];
388 for (i
= 0; i
< size
; i
++)
389 hash_table
[i
] = (wxList
*) NULL
;
394 void wxHashTable::DoCopy(const wxHashTable
& table
)
397 m_count
= table
.m_count
;
398 current_position
= table
.current_position
;
399 current_node
= NULL
; // doesn't matter - Next() will reconstruct it
400 key_type
= table
.key_type
;
402 hash_table
= new wxList
*[n
];
403 for (int i
= 0; i
< n
; i
++) {
404 if (table
.hash_table
[i
] == NULL
)
405 hash_table
[i
] = NULL
;
407 hash_table
[i
] = new wxList(key_type
);
408 *(hash_table
[i
]) = *(table
.hash_table
[i
]);
413 void wxHashTable::Put (long key
, long value
, wxObject
* object
)
418 int position
= (int) (k
% n
);
419 if (position
< 0) position
= -position
;
421 if (!hash_table
[position
])
423 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
424 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
427 hash_table
[position
]->Append (value
, object
);
431 void wxHashTable::Put (long key
, const wxChar
*value
, wxObject
* object
)
436 int position
= (int) (k
% n
);
437 if (position
< 0) position
= -position
;
439 if (!hash_table
[position
])
441 hash_table
[position
] = new wxList (wxKEY_STRING
);
442 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
445 hash_table
[position
]->Append (value
, object
);
449 void wxHashTable::Put (long key
, wxObject
* object
)
454 int position
= (int) (k
% n
);
455 if (position
< 0) position
= -position
;
457 if (!hash_table
[position
])
459 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
460 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
463 hash_table
[position
]->Append (k
, object
);
467 void wxHashTable::Put (const wxChar
*key
, wxObject
* object
)
469 int position
= (int) (MakeKey (key
) % n
);
470 if (position
< 0) position
= -position
;
472 if (!hash_table
[position
])
474 hash_table
[position
] = new wxList (wxKEY_STRING
);
475 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
478 hash_table
[position
]->Append (key
, object
);
482 wxObject
*wxHashTable::Get (long key
, long value
) const
487 int position
= (int) (k
% n
);
488 if (position
< 0) position
= -position
;
490 if (!hash_table
[position
])
491 return (wxObject
*) NULL
;
494 wxNode
*node
= hash_table
[position
]->Find (value
);
496 return node
->Data ();
498 return (wxObject
*) NULL
;
502 wxObject
*wxHashTable::Get (long key
, const wxChar
*value
) const
507 int position
= (int) (k
% n
);
508 if (position
< 0) position
= -position
;
510 if (!hash_table
[position
])
511 return (wxObject
*) NULL
;
514 wxNode
*node
= hash_table
[position
]->Find (value
);
516 return node
->Data ();
518 return (wxObject
*) NULL
;
522 wxObject
*wxHashTable::Get (long key
) const
527 int position
= (int) (k
% n
);
528 if (position
< 0) position
= -position
;
530 if (!hash_table
[position
])
531 return (wxObject
*) NULL
;
534 wxNode
*node
= hash_table
[position
]->Find (k
);
535 return node
? node
->Data () : (wxObject
*)NULL
;
539 wxObject
*wxHashTable::Get (const wxChar
*key
) const
541 int position
= (int) (MakeKey (key
) % n
);
542 if (position
< 0) position
= -position
;
544 if (!hash_table
[position
])
545 return (wxObject
*) NULL
;
548 wxNode
*node
= hash_table
[position
]->Find (key
);
549 return node
? node
->Data () : (wxObject
*)NULL
;
553 wxObject
*wxHashTable::Delete (long key
)
558 int position
= (int) (k
% n
);
559 if (position
< 0) position
= -position
;
561 if (!hash_table
[position
])
562 return (wxObject
*) NULL
;
565 wxNode
*node
= hash_table
[position
]->Find (k
);
568 wxObject
*data
= node
->Data ();
574 return (wxObject
*) NULL
;
578 wxObject
*wxHashTable::Delete (const wxChar
*key
)
580 int position
= (int) (MakeKey (key
) % n
);
581 if (position
< 0) position
= -position
;
583 if (!hash_table
[position
])
584 return (wxObject
*) NULL
;
587 wxNode
*node
= hash_table
[position
]->Find (key
);
590 wxObject
*data
= node
->Data ();
596 return (wxObject
*) NULL
;
600 wxObject
*wxHashTable::Delete (long key
, int value
)
605 int position
= (int) (k
% n
);
606 if (position
< 0) position
= -position
;
608 if (!hash_table
[position
])
609 return (wxObject
*) NULL
;
612 wxNode
*node
= hash_table
[position
]->Find (value
);
615 wxObject
*data
= node
->Data ();
621 return (wxObject
*) NULL
;
625 wxObject
*wxHashTable::Delete (long key
, const wxChar
*value
)
627 int position
= (int) (key
% n
);
628 if (position
< 0) position
= -position
;
630 if (!hash_table
[position
])
631 return (wxObject
*) NULL
;
634 wxNode
*node
= hash_table
[position
]->Find (value
);
637 wxObject
*data
= node
->Data ();
643 return (wxObject
*) NULL
;
647 long wxHashTable::MakeKey (const wxChar
*string
) const
652 int_key
+= (wxUChar
) *string
++;
657 void wxHashTable::BeginFind ()
659 current_position
= -1;
660 current_node
= (wxNode
*) NULL
;
663 wxNode
*wxHashTable::Next ()
665 wxNode
*found
= (wxNode
*) NULL
;
667 while (!end
&& !found
)
672 if (current_position
>= n
)
674 current_position
= -1;
675 current_node
= (wxNode
*) NULL
;
680 if (hash_table
[current_position
])
682 current_node
= hash_table
[current_position
]->First ();
683 found
= current_node
;
689 current_node
= current_node
->Next ();
690 found
= current_node
;
696 void wxHashTable::DeleteContents (bool flag
)
699 m_deleteContents
= flag
;
700 for (i
= 0; i
< n
; i
++)
703 hash_table
[i
]->DeleteContents (flag
);
707 void wxHashTable::Clear ()
712 for (i
= 0; i
< n
; i
++)
715 hash_table
[i
]->Clear ();