]>
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::Destroy()
148 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
160 void wxHashTableLong::Put(long key
, long value
)
162 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
164 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
168 m_keys
[slot
] = new wxArrayLong
;
169 m_values
[slot
] = new wxArrayLong
;
172 m_keys
[slot
]->Add(key
);
173 m_values
[slot
]->Add(value
);
178 long wxHashTableLong::Get(long key
) const
180 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
182 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
184 wxArrayLong
*keys
= m_keys
[slot
];
187 size_t count
= keys
->GetCount();
188 for ( size_t n
= 0; n
< count
; n
++ )
190 if ( keys
->Item(n
) == key
)
192 return m_values
[slot
]->Item(n
);
200 long wxHashTableLong::Delete(long key
)
202 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
204 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
206 wxArrayLong
*keys
= m_keys
[slot
];
209 size_t count
= keys
->GetCount();
210 for ( size_t n
= 0; n
< count
; n
++ )
212 if ( keys
->Item(n
) == key
)
214 long val
= m_values
[slot
]->Item(n
);
217 m_values
[slot
]->RemoveAt(n
);
229 // ----------------------------------------------------------------------------
230 // wxStringHashTable: more efficient than storing strings in a list
231 // ----------------------------------------------------------------------------
233 wxStringHashTable::wxStringHashTable(size_t sizeTable
)
235 m_keys
= new wxArrayLong
*[sizeTable
];
236 m_values
= new wxArrayString
*[sizeTable
];
238 m_hashSize
= sizeTable
;
239 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
241 m_values
[n
] = (wxArrayString
*)NULL
;
242 m_keys
[n
] = (wxArrayLong
*)NULL
;
246 wxStringHashTable::~wxStringHashTable()
251 void wxStringHashTable::Destroy()
253 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
264 void wxStringHashTable::Put(long key
, const wxString
& value
)
266 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
268 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
272 m_keys
[slot
] = new wxArrayLong
;
273 m_values
[slot
] = new wxArrayString
;
276 m_keys
[slot
]->Add(key
);
277 m_values
[slot
]->Add(value
);
280 wxString
wxStringHashTable::Get(long key
, bool *wasFound
) const
282 wxCHECK_MSG( m_hashSize
, _T(""), _T("must call Create() first") );
284 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
286 wxArrayLong
*keys
= m_keys
[slot
];
289 size_t count
= keys
->GetCount();
290 for ( size_t n
= 0; n
< count
; n
++ )
292 if ( keys
->Item(n
) == key
)
297 return m_values
[slot
]->Item(n
);
308 // ----------------------------------------------------------------------------
309 // old not type safe wxHashTable
310 // ----------------------------------------------------------------------------
312 wxHashTable::wxHashTable (int the_key_type
, int size
)
315 hash_table
= (wxList
**) NULL
;
316 Create(the_key_type
, size
);
318 m_deleteContents
= FALSE
;
321 current_position = -1;
322 current_node = (wxNode *) NULL;
324 key_type = the_key_type;
325 hash_table = new wxList *[size];
327 for (i = 0; i < size; i++)
328 hash_table[i] = (wxList *) NULL;
332 wxHashTable::~wxHashTable ()
337 void wxHashTable::Destroy()
339 if (!hash_table
) return;
341 for (i
= 0; i
< n
; i
++)
343 delete hash_table
[i
];
348 bool wxHashTable::Create(int the_key_type
, int size
)
353 current_position
= -1;
354 current_node
= (wxNode
*) NULL
;
356 key_type
= the_key_type
;
357 hash_table
= new wxList
*[size
];
359 for (i
= 0; i
< size
; i
++)
360 hash_table
[i
] = (wxList
*) NULL
;
365 void wxHashTable::DoCopy(const wxHashTable
& table
)
368 current_position
= table
.current_position
;
369 current_node
= NULL
; // doesn't matter - Next() will reconstruct it
370 key_type
= table
.key_type
;
372 hash_table
= new wxList
*[n
];
373 for (int i
= 0; i
< n
; i
++) {
374 if (table
.hash_table
[i
] == NULL
)
375 hash_table
[i
] = NULL
;
377 hash_table
[i
] = new wxList(key_type
);
378 *(hash_table
[i
]) = *(table
.hash_table
[i
]);
383 void wxHashTable::Put (long key
, long value
, wxObject
* object
)
388 int position
= (int) (k
% n
);
389 if (position
< 0) position
= -position
;
391 if (!hash_table
[position
])
393 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
394 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
397 hash_table
[position
]->Append (value
, object
);
401 void wxHashTable::Put (long key
, const wxChar
*value
, wxObject
* object
)
406 int position
= (int) (k
% n
);
407 if (position
< 0) position
= -position
;
409 if (!hash_table
[position
])
411 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
412 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
415 hash_table
[position
]->Append (value
, object
);
419 void wxHashTable::Put (long key
, 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 (k
, object
);
437 void wxHashTable::Put (const wxChar
*key
, wxObject
* object
)
439 int position
= (int) (MakeKey (key
) % n
);
440 if (position
< 0) position
= -position
;
442 if (!hash_table
[position
])
444 hash_table
[position
] = new wxList (wxKEY_STRING
);
445 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
448 hash_table
[position
]->Append (key
, object
);
452 wxObject
*wxHashTable::Get (long key
, long value
) const
457 int position
= (int) (k
% n
);
458 if (position
< 0) position
= -position
;
460 if (!hash_table
[position
])
461 return (wxObject
*) NULL
;
464 wxNode
*node
= hash_table
[position
]->Find (value
);
466 return node
->Data ();
468 return (wxObject
*) NULL
;
472 wxObject
*wxHashTable::Get (long key
, const wxChar
*value
) const
477 int position
= (int) (k
% n
);
478 if (position
< 0) position
= -position
;
480 if (!hash_table
[position
])
481 return (wxObject
*) NULL
;
484 wxNode
*node
= hash_table
[position
]->Find (value
);
486 return node
->Data ();
488 return (wxObject
*) NULL
;
492 wxObject
*wxHashTable::Get (long key
) const
497 int position
= (int) (k
% n
);
498 if (position
< 0) position
= -position
;
500 if (!hash_table
[position
])
501 return (wxObject
*) NULL
;
504 wxNode
*node
= hash_table
[position
]->Find (k
);
505 return node
? node
->Data () : (wxObject
*)NULL
;
509 wxObject
*wxHashTable::Get (const wxChar
*key
) const
511 int position
= (int) (MakeKey (key
) % n
);
512 if (position
< 0) position
= -position
;
514 if (!hash_table
[position
])
515 return (wxObject
*) NULL
;
518 wxNode
*node
= hash_table
[position
]->Find (key
);
519 return node
? node
->Data () : (wxObject
*)NULL
;
523 wxObject
*wxHashTable::Delete (long key
)
528 int position
= (int) (k
% n
);
529 if (position
< 0) position
= -position
;
531 if (!hash_table
[position
])
532 return (wxObject
*) NULL
;
535 wxNode
*node
= hash_table
[position
]->Find (k
);
538 wxObject
*data
= node
->Data ();
544 return (wxObject
*) NULL
;
548 wxObject
*wxHashTable::Delete (const wxChar
*key
)
550 int position
= (int) (MakeKey (key
) % n
);
551 if (position
< 0) position
= -position
;
553 if (!hash_table
[position
])
554 return (wxObject
*) NULL
;
557 wxNode
*node
= hash_table
[position
]->Find (key
);
560 wxObject
*data
= node
->Data ();
566 return (wxObject
*) NULL
;
570 wxObject
*wxHashTable::Delete (long key
, int value
)
575 int position
= (int) (k
% n
);
576 if (position
< 0) position
= -position
;
578 if (!hash_table
[position
])
579 return (wxObject
*) NULL
;
582 wxNode
*node
= hash_table
[position
]->Find (value
);
585 wxObject
*data
= node
->Data ();
591 return (wxObject
*) NULL
;
595 wxObject
*wxHashTable::Delete (long key
, const wxChar
*value
)
597 int position
= (int) (key
% n
);
598 if (position
< 0) position
= -position
;
600 if (!hash_table
[position
])
601 return (wxObject
*) NULL
;
604 wxNode
*node
= hash_table
[position
]->Find (value
);
607 wxObject
*data
= node
->Data ();
613 return (wxObject
*) NULL
;
617 long wxHashTable::MakeKey (const wxChar
*string
) const
622 int_key
+= (wxUChar
) *string
++;
627 void wxHashTable::BeginFind ()
629 current_position
= -1;
630 current_node
= (wxNode
*) NULL
;
633 wxNode
*wxHashTable::Next ()
635 wxNode
*found
= (wxNode
*) NULL
;
637 while (!end
&& !found
)
642 if (current_position
>= n
)
644 current_position
= -1;
645 current_node
= (wxNode
*) NULL
;
650 if (hash_table
[current_position
])
652 current_node
= hash_table
[current_position
]->First ();
653 found
= current_node
;
659 current_node
= current_node
->Next ();
660 found
= current_node
;
666 void wxHashTable::DeleteContents (bool flag
)
669 m_deleteContents
= flag
;
670 for (i
= 0; i
< n
; i
++)
673 hash_table
[i
]->DeleteContents (flag
);
677 void wxHashTable::Clear ()
680 for (i
= 0; i
< n
; i
++)
683 hash_table
[i
]->Clear ();