]>
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"
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 #if WXWIN_COMPATIBILITY_2_4
124 // ----------------------------------------------------------------------------
126 // ----------------------------------------------------------------------------
128 wxHashTableLong::~wxHashTableLong()
133 void wxHashTableLong::Init(size_t size
)
136 m_values
= new wxArrayLong
*[size
];
137 m_keys
= new wxArrayLong
*[size
];
139 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
142 m_keys
[n
] = (wxArrayLong
*)NULL
;
148 void wxHashTableLong::Create(size_t size
)
153 void wxHashTableLong::Destroy()
155 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
167 void wxHashTableLong::Put(long key
, long value
)
169 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
171 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
175 m_keys
[slot
] = new wxArrayLong
;
176 m_values
[slot
] = new wxArrayLong
;
179 m_keys
[slot
]->Add(key
);
180 m_values
[slot
]->Add(value
);
185 long wxHashTableLong::Get(long key
) const
187 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
189 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
191 wxArrayLong
*keys
= m_keys
[slot
];
194 size_t count
= keys
->GetCount();
195 for ( size_t n
= 0; n
< count
; n
++ )
197 if ( keys
->Item(n
) == key
)
199 return m_values
[slot
]->Item(n
);
207 long wxHashTableLong::Delete(long key
)
209 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
211 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
213 wxArrayLong
*keys
= m_keys
[slot
];
216 size_t count
= keys
->GetCount();
217 for ( size_t n
= 0; n
< count
; n
++ )
219 if ( keys
->Item(n
) == key
)
221 long val
= m_values
[slot
]->Item(n
);
224 m_values
[slot
]->RemoveAt(n
);
236 // ----------------------------------------------------------------------------
237 // wxStringHashTable: more efficient than storing strings in a list
238 // ----------------------------------------------------------------------------
240 wxStringHashTable::wxStringHashTable(size_t sizeTable
)
242 m_keys
= new wxArrayLong
*[sizeTable
];
243 m_values
= new wxArrayString
*[sizeTable
];
245 m_hashSize
= sizeTable
;
246 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
248 m_values
[n
] = (wxArrayString
*)NULL
;
249 m_keys
[n
] = (wxArrayLong
*)NULL
;
253 wxStringHashTable::~wxStringHashTable()
258 void wxStringHashTable::Destroy()
260 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
271 void wxStringHashTable::Put(long key
, const wxString
& value
)
273 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
275 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
279 m_keys
[slot
] = new wxArrayLong
;
280 m_values
[slot
] = new wxArrayString
;
283 m_keys
[slot
]->Add(key
);
284 m_values
[slot
]->Add(value
);
287 wxString
wxStringHashTable::Get(long key
, bool *wasFound
) const
289 wxCHECK_MSG( m_hashSize
, _T(""), _T("must call Create() first") );
291 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
293 wxArrayLong
*keys
= m_keys
[slot
];
296 size_t count
= keys
->GetCount();
297 for ( size_t n
= 0; n
< count
; n
++ )
299 if ( keys
->Item(n
) == key
)
304 return m_values
[slot
]->Item(n
);
315 bool wxStringHashTable::Delete(long key
) const
317 wxCHECK_MSG( m_hashSize
, FALSE
, _T("must call Create() first") );
319 size_t slot
= (size_t)abs((int)(key
% (long)m_hashSize
));
321 wxArrayLong
*keys
= m_keys
[slot
];
324 size_t count
= keys
->GetCount();
325 for ( size_t n
= 0; n
< count
; n
++ )
327 if ( keys
->Item(n
) == key
)
330 m_values
[slot
]->RemoveAt(n
);
339 #endif // WXWIN_COMPATIBILITY_2_4
341 // ----------------------------------------------------------------------------
342 // old not type safe wxHashTable
343 // ----------------------------------------------------------------------------
345 wxHashTable::wxHashTable (int the_key_type
, int size
)
348 hash_table
= (wxList
**) NULL
;
349 Create(the_key_type
, size
);
351 m_deleteContents
= FALSE
;
354 current_position = -1;
355 current_node = (wxNode *) NULL;
357 key_type = the_key_type;
358 hash_table = new wxList *[size];
360 for (i = 0; i < size; i++)
361 hash_table[i] = (wxList *) NULL;
365 wxHashTable::~wxHashTable ()
370 void wxHashTable::Destroy()
372 if (!hash_table
) return;
374 for (i
= 0; i
< n
; i
++)
376 delete hash_table
[i
];
381 bool wxHashTable::Create(int the_key_type
, int size
)
386 current_position
= -1;
387 current_node
= (wxNode
*) NULL
;
389 key_type
= the_key_type
;
390 hash_table
= new wxList
*[size
];
392 for (i
= 0; i
< size
; i
++)
393 hash_table
[i
] = (wxList
*) NULL
;
398 void wxHashTable::DoCopy(const wxHashTable
& table
)
401 m_count
= table
.m_count
;
402 current_position
= table
.current_position
;
403 current_node
= NULL
; // doesn't matter - Next() will reconstruct it
404 key_type
= table
.key_type
;
406 hash_table
= new wxList
*[n
];
407 for (int i
= 0; i
< n
; i
++) {
408 if (table
.hash_table
[i
] == NULL
)
409 hash_table
[i
] = NULL
;
411 hash_table
[i
] = new wxList(key_type
);
412 *(hash_table
[i
]) = *(table
.hash_table
[i
]);
417 void wxHashTable::Put (long key
, long value
, wxObject
* object
)
422 int position
= (int) (k
% n
);
423 if (position
< 0) position
= -position
;
425 if (!hash_table
[position
])
427 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
428 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
431 hash_table
[position
]->Append (value
, object
);
435 void wxHashTable::Put (long key
, const wxChar
*value
, wxObject
* object
)
440 int position
= (int) (k
% n
);
441 if (position
< 0) position
= -position
;
443 if (!hash_table
[position
])
445 hash_table
[position
] = new wxList (wxKEY_STRING
);
446 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
449 hash_table
[position
]->Append (value
, object
);
453 void wxHashTable::Put (long key
, wxObject
* object
)
458 int position
= (int) (k
% n
);
459 if (position
< 0) position
= -position
;
461 if (!hash_table
[position
])
463 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
464 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
467 hash_table
[position
]->Append (k
, object
);
471 void wxHashTable::Put (const wxChar
*key
, wxObject
* object
)
473 int position
= (int) (MakeKey (key
) % n
);
474 if (position
< 0) position
= -position
;
476 if (!hash_table
[position
])
478 hash_table
[position
] = new wxList (wxKEY_STRING
);
479 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
482 hash_table
[position
]->Append (key
, object
);
486 wxObject
*wxHashTable::Get (long key
, long value
) const
491 int position
= (int) (k
% n
);
492 if (position
< 0) position
= -position
;
494 if (!hash_table
[position
])
495 return (wxObject
*) NULL
;
498 wxNode
*node
= hash_table
[position
]->Find (value
);
500 return node
->GetData ();
502 return (wxObject
*) NULL
;
506 wxObject
*wxHashTable::Get (long key
, const wxChar
*value
) const
511 int position
= (int) (k
% n
);
512 if (position
< 0) position
= -position
;
514 if (!hash_table
[position
])
515 return (wxObject
*) NULL
;
518 wxNode
*node
= hash_table
[position
]->Find (value
);
520 return node
->GetData ();
522 return (wxObject
*) NULL
;
526 wxObject
*wxHashTable::Get (long key
) const
531 int position
= (int) (k
% n
);
532 if (position
< 0) position
= -position
;
534 if (!hash_table
[position
])
535 return (wxObject
*) NULL
;
538 wxNode
*node
= hash_table
[position
]->Find (k
);
539 return node
? node
->GetData () : (wxObject
*)NULL
;
543 wxObject
*wxHashTable::Get (const wxChar
*key
) const
545 int position
= (int) (MakeKey (key
) % n
);
546 if (position
< 0) position
= -position
;
548 if (!hash_table
[position
])
549 return (wxObject
*) NULL
;
552 wxNode
*node
= hash_table
[position
]->Find (key
);
553 return node
? node
->GetData () : (wxObject
*)NULL
;
557 wxObject
*wxHashTable::Delete (long key
)
562 int position
= (int) (k
% n
);
563 if (position
< 0) position
= -position
;
565 if (!hash_table
[position
])
566 return (wxObject
*) NULL
;
569 wxNode
*node
= hash_table
[position
]->Find (k
);
572 wxObject
*data
= node
->GetData ();
578 return (wxObject
*) NULL
;
582 wxObject
*wxHashTable::Delete (const wxChar
*key
)
584 int position
= (int) (MakeKey (key
) % n
);
585 if (position
< 0) position
= -position
;
587 if (!hash_table
[position
])
588 return (wxObject
*) NULL
;
591 wxNode
*node
= hash_table
[position
]->Find (key
);
594 wxObject
*data
= node
->GetData ();
600 return (wxObject
*) NULL
;
604 wxObject
*wxHashTable::Delete (long key
, int value
)
609 int position
= (int) (k
% n
);
610 if (position
< 0) position
= -position
;
612 if (!hash_table
[position
])
613 return (wxObject
*) NULL
;
616 wxNode
*node
= hash_table
[position
]->Find (value
);
619 wxObject
*data
= node
->GetData ();
625 return (wxObject
*) NULL
;
629 wxObject
*wxHashTable::Delete (long key
, const wxChar
*value
)
631 int position
= (int) (key
% n
);
632 if (position
< 0) position
= -position
;
634 if (!hash_table
[position
])
635 return (wxObject
*) NULL
;
638 wxNode
*node
= hash_table
[position
]->Find (value
);
641 wxObject
*data
= node
->GetData ();
647 return (wxObject
*) NULL
;
651 long wxHashTable::MakeKey (const wxChar
*string
) const
656 int_key
+= (wxUChar
) *string
++;
661 void wxHashTable::BeginFind ()
663 current_position
= -1;
664 current_node
= (wxNode
*) NULL
;
667 wxNode
*wxHashTable::Next ()
669 wxNode
*found
= (wxNode
*) NULL
;
671 while (!end
&& !found
)
676 if (current_position
>= n
)
678 current_position
= -1;
679 current_node
= (wxNode
*) NULL
;
684 if (hash_table
[current_position
])
686 current_node
= hash_table
[current_position
]->GetFirst ();
687 found
= current_node
;
693 current_node
= current_node
->GetNext ();
694 found
= current_node
;
700 void wxHashTable::DeleteContents (bool flag
)
703 m_deleteContents
= flag
;
704 for (i
= 0; i
< n
; i
++)
707 hash_table
[i
]->DeleteContents (flag
);
711 void wxHashTable::Clear ()
716 for (i
= 0; i
< n
; i
++)
719 hash_table
[i
]->Clear ();