]>
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(key
% m_hashSize
);
110 if ( m_hashTable
[slot
] )
112 node
= m_hashTable
[slot
]->Find(wxListKey(value
));
116 node
= (wxNodeBase
*)NULL
;
122 // ----------------------------------------------------------------------------
124 // ----------------------------------------------------------------------------
126 void wxHashTableLong::Init(size_t size
)
129 m_values
= new wxArrayLong
*[size
];
130 m_keys
= new wxArrayLong
*[size
];
132 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
135 m_keys
[n
] = (wxArrayLong
*)NULL
;
141 void wxHashTableLong::Destroy()
143 for ( size_t n
= 0; n
< m_hashSize
; n
++ )
155 void wxHashTableLong::Put(long key
, long value
)
157 wxCHECK_RET( m_hashSize
, _T("must call Create() first") );
159 size_t slot
= (size_t)abs(key
% m_hashSize
);
163 m_keys
[slot
] = new wxArrayLong
;
164 m_values
[slot
] = new wxArrayLong
;
167 m_keys
[slot
]->Add(key
);
168 m_values
[slot
]->Add(value
);
173 long wxHashTableLong::Get(long key
) const
175 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
177 size_t slot
= (size_t)abs(key
% m_hashSize
);
179 wxArrayLong
*keys
= m_keys
[slot
];
182 size_t count
= keys
->GetCount();
183 for ( size_t n
= 0; n
< count
; n
++ )
185 if ( keys
->Item(n
) == key
)
187 return m_values
[slot
]->Item(n
);
195 long wxHashTableLong::Delete(long key
)
197 wxCHECK_MSG( m_hashSize
, wxNOT_FOUND
, _T("must call Create() first") );
199 size_t slot
= (size_t)abs(key
% m_hashSize
);
201 wxArrayLong
*keys
= m_keys
[slot
];
204 size_t count
= keys
->GetCount();
205 for ( size_t n
= 0; n
< count
; n
++ )
207 if ( keys
->Item(n
) == key
)
209 long val
= m_values
[slot
]->Item(n
);
212 m_values
[slot
]->RemoveAt(n
);
224 // ----------------------------------------------------------------------------
225 // old not type safe wxHashTable
226 // ----------------------------------------------------------------------------
228 wxHashTable::wxHashTable (int the_key_type
, int size
)
231 hash_table
= (wxList
**) NULL
;
232 Create(the_key_type
, size
);
234 m_deleteContents
= FALSE
;
237 current_position = -1;
238 current_node = (wxNode *) NULL;
240 key_type = the_key_type;
241 hash_table = new wxList *[size];
243 for (i = 0; i < size; i++)
244 hash_table[i] = (wxList *) NULL;
248 wxHashTable::~wxHashTable ()
253 void wxHashTable::Destroy()
255 if (!hash_table
) return;
257 for (i
= 0; i
< n
; i
++)
259 delete hash_table
[i
];
264 bool wxHashTable::Create(int the_key_type
, int size
)
269 current_position
= -1;
270 current_node
= (wxNode
*) NULL
;
272 key_type
= the_key_type
;
273 hash_table
= new wxList
*[size
];
275 for (i
= 0; i
< size
; i
++)
276 hash_table
[i
] = (wxList
*) NULL
;
281 void wxHashTable::DoCopy(const wxHashTable
& table
)
284 current_position
= table
.current_position
;
285 current_node
= NULL
; // doesn't matter - Next() will reconstruct it
286 key_type
= table
.key_type
;
288 hash_table
= new wxList
*[n
];
289 for (int i
= 0; i
< n
; i
++) {
290 if (table
.hash_table
[i
] == NULL
)
291 hash_table
[i
] = NULL
;
293 hash_table
[i
] = new wxList(key_type
);
294 *(hash_table
[i
]) = *(table
.hash_table
[i
]);
299 void wxHashTable::Put (long key
, long value
, wxObject
* object
)
304 int position
= (int) (k
% n
);
305 if (position
< 0) position
= -position
;
307 if (!hash_table
[position
])
309 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
310 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
313 hash_table
[position
]->Append (value
, object
);
317 void wxHashTable::Put (long key
, const wxChar
*value
, wxObject
* object
)
322 int position
= (int) (k
% n
);
323 if (position
< 0) position
= -position
;
325 if (!hash_table
[position
])
327 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
328 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
331 hash_table
[position
]->Append (value
, object
);
335 void wxHashTable::Put (long key
, wxObject
* object
)
340 int position
= (int) (k
% n
);
341 if (position
< 0) position
= -position
;
343 if (!hash_table
[position
])
345 hash_table
[position
] = new wxList (wxKEY_INTEGER
);
346 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
349 hash_table
[position
]->Append (k
, object
);
353 void wxHashTable::Put (const wxChar
*key
, wxObject
* object
)
355 int position
= (int) (MakeKey (key
) % n
);
356 if (position
< 0) position
= -position
;
358 if (!hash_table
[position
])
360 hash_table
[position
] = new wxList (wxKEY_STRING
);
361 if (m_deleteContents
) hash_table
[position
]->DeleteContents(TRUE
);
364 hash_table
[position
]->Append (key
, object
);
368 wxObject
*wxHashTable::Get (long key
, long value
) const
373 int position
= (int) (k
% n
);
374 if (position
< 0) position
= -position
;
376 if (!hash_table
[position
])
377 return (wxObject
*) NULL
;
380 wxNode
*node
= hash_table
[position
]->Find (value
);
382 return node
->Data ();
384 return (wxObject
*) NULL
;
388 wxObject
*wxHashTable::Get (long key
, const wxChar
*value
) const
393 int position
= (int) (k
% n
);
394 if (position
< 0) position
= -position
;
396 if (!hash_table
[position
])
397 return (wxObject
*) NULL
;
400 wxNode
*node
= hash_table
[position
]->Find (value
);
402 return node
->Data ();
404 return (wxObject
*) NULL
;
408 wxObject
*wxHashTable::Get (long key
) const
413 int position
= (int) (k
% n
);
414 if (position
< 0) position
= -position
;
416 if (!hash_table
[position
])
417 return (wxObject
*) NULL
;
420 wxNode
*node
= hash_table
[position
]->Find (k
);
421 return node
? node
->Data () : (wxObject
*)NULL
;
425 wxObject
*wxHashTable::Get (const wxChar
*key
) const
427 int position
= (int) (MakeKey (key
) % n
);
428 if (position
< 0) position
= -position
;
430 if (!hash_table
[position
])
431 return (wxObject
*) NULL
;
434 wxNode
*node
= hash_table
[position
]->Find (key
);
435 return node
? node
->Data () : (wxObject
*)NULL
;
439 wxObject
*wxHashTable::Delete (long key
)
444 int position
= (int) (k
% n
);
445 if (position
< 0) position
= -position
;
447 if (!hash_table
[position
])
448 return (wxObject
*) NULL
;
451 wxNode
*node
= hash_table
[position
]->Find (k
);
454 wxObject
*data
= node
->Data ();
460 return (wxObject
*) NULL
;
464 wxObject
*wxHashTable::Delete (const wxChar
*key
)
466 int position
= (int) (MakeKey (key
) % n
);
467 if (position
< 0) position
= -position
;
469 if (!hash_table
[position
])
470 return (wxObject
*) NULL
;
473 wxNode
*node
= hash_table
[position
]->Find (key
);
476 wxObject
*data
= node
->Data ();
482 return (wxObject
*) NULL
;
486 wxObject
*wxHashTable::Delete (long key
, int value
)
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
);
501 wxObject
*data
= node
->Data ();
507 return (wxObject
*) NULL
;
511 wxObject
*wxHashTable::Delete (long key
, const wxChar
*value
)
513 int position
= (int) (key
% n
);
514 if (position
< 0) position
= -position
;
516 if (!hash_table
[position
])
517 return (wxObject
*) NULL
;
520 wxNode
*node
= hash_table
[position
]->Find (value
);
523 wxObject
*data
= node
->Data ();
529 return (wxObject
*) NULL
;
533 long wxHashTable::MakeKey (const wxChar
*string
) const
538 int_key
+= (wxUChar
) *string
++;
543 void wxHashTable::BeginFind ()
545 current_position
= -1;
546 current_node
= (wxNode
*) NULL
;
549 wxNode
*wxHashTable::Next ()
551 wxNode
*found
= (wxNode
*) NULL
;
553 while (!end
&& !found
)
558 if (current_position
>= n
)
560 current_position
= -1;
561 current_node
= (wxNode
*) NULL
;
566 if (hash_table
[current_position
])
568 current_node
= hash_table
[current_position
]->First ();
569 found
= current_node
;
575 current_node
= current_node
->Next ();
576 found
= current_node
;
582 void wxHashTable::DeleteContents (bool flag
)
585 m_deleteContents
= flag
;
586 for (i
= 0; i
< n
; i
++)
589 hash_table
[i
]->DeleteContents (flag
);
593 void wxHashTable::Clear ()
596 for (i
= 0; i
< n
; i
++)
599 hash_table
[i
]->Clear ();