📄 sorted_set.cpp
字号:
#include <hk_physics/physics.h>
#ifdef HK_HAVE_PRAGMA_INTERFACE
# pragma implementation
#endif
#include <hk_physics/types/sorted_set.h>
hk_Sorted_Set::hk_Sorted_Set(int start_size, hk_Memory *mem)
{
m_malloced_size = start_size;
m_n_added_elements = 0;
m_elems = hk_allocate(hk_SS_Element, m_malloced_size, HK_MEMORY_CLASS_SORTED_SET);
m_free_list = 0;
for( unsigned int i = 0; i < m_malloced_size; i++){
m_elems[i].m_next = i+1;
}
m_elems[m_malloced_size-1].m_next = HK_SORTED_SET_UNUSED;
m_first_element = HK_SORTED_SET_UNUSED;
#ifdef HK_SORTED_SET_USELONG
m_first_long = HK_SORTED_SET_UNUSED;
#endif
m_min_value = HK_SORTED_SET_MAXVALUE;
}
hk_Sorted_Set::~hk_Sorted_Set()
{
hk_deallocate( hk_SS_Element, m_elems, m_malloced_size, HK_MEMORY_CLASS_SORTED_SET);
}
hk_Sorted_Set::hk_ss_index hk_Sorted_Set::add_ss_element(
void *elem,
hk_ss_real value, hk_Memory *mem)
{
// search free element first
HK_ASSERT(value < HK_SORTED_SET_MAXVALUE);
hk_SS_Element *e;
hk_ss_index return_index;
m_n_added_elements += 1;
// check for space left in array
if ( m_free_list != HK_SORTED_SET_UNUSED )
{
// use old place
return_index = m_free_list;
e = &m_elems[m_free_list];
m_free_list = e->m_next;
}
else
{
// increase array
unsigned int i;
hk_SS_Element *new_elems = hk_allocate( hk_SS_Element, 2 * (m_malloced_size+1), HK_MEMORY_CLASS_SORTED_SET);
for(i=0; i < m_malloced_size; i++){
new_elems[i] = m_elems[i];
}
hk_deallocate(hk_SS_Element, m_elems, m_malloced_size, HK_MEMORY_CLASS_SORTED_SET);
m_malloced_size = m_malloced_size * 2 + 1;
m_elems = new_elems;
return_index = i;
e = &m_elems[i++];
m_free_list = i;
for(; i < m_malloced_size; i++){
m_elems[i].m_next = i+1;
}
m_elems[m_malloced_size-1].m_next = HK_SORTED_SET_UNUSED;
}
e->m_element = elem;
e->m_value = value;
#ifdef HK_SORTED_SET_USELONG
e->m_long_next = HK_SORTED_SET_LONG_UNUSED;
#endif
if ( value <= m_min_value ){ // quick insert first element
m_min_value = value;
e->m_next = m_first_element;
if (m_first_element != HK_SORTED_SET_UNUSED) {
m_elems[m_first_element].m_prev = return_index;
}
m_first_element = return_index;
e->m_prev = HK_SORTED_SET_UNUSED;
//check();
return return_index;
}
HK_ASSERT( m_first_element != HK_SORTED_SET_UNUSED);
// find place to insert element, we know at least one exists
int lastj = m_first_element;
#ifdef HK_SORTED_SET_USELONG
// lastj is the last element after we want to insert
int lo = m_first_long;
int max_cmp_len = 3;
while (lo != HK_SORTED_SET_UNUSED){
// do _long jumps if possible
hk_SS_Element *flong = & m_elems[lo];
if (flong->m_value >= value){
break;
}
max_cmp_len++;
lastj = lo;
lo = flong->m_long_next;
}
int firstj_after = lastj;
int count_cmp = 0;
#endif
hk_SS_Element *f = & m_elems[lastj];
int j = f->m_next;
for (; j != HK_SORTED_SET_UNUSED; j = f->m_next){
f = &m_elems[j];
#ifdef HK_SORTED_SET_USELONG
count_cmp ++;
#endif
if ( value > f->m_value ){
lastj = j;
continue;
}
hk_SS_Element *l = &m_elems[lastj];
e->m_next = l->m_next;
m_elems[j].m_prev = return_index;
e->m_prev = lastj;
l->m_next = return_index;
goto end;
}
// insert after the last element f
e->m_next = j;
e->m_prev = lastj;
f->m_next = return_index;
end:
#ifdef HK_SORTED_SET_USELONG
// insert long jmp
if ( count_cmp > max_cmp_len ) {
int new_long_pos = firstj_after; // search new position for longjump
for (int k = 2; k < max_cmp_len; k ++){
new_long_pos = m_elems[new_long_pos].m_next;
}
int next_of_first = m_elems[firstj_after].m_long_next;
hk_SS_Element *nl = &m_elems[new_long_pos];
HK_ASSERT(nl->m_long_next == HK_SORTED_SET_LONG_UNUSED);
if ( next_of_first != HK_SORTED_SET_LONG_UNUSED ){ // real long as first element
nl->m_long_next = next_of_first;
nl->m_long_prev = firstj_after;
if ( next_of_first != HK_SORTED_SET_UNUSED ) {
m_elems[next_of_first].m_long_prev = new_long_pos;
}
m_elems[firstj_after].m_long_next = new_long_pos;
}else{ // insert long as first long
nl->m_long_next = m_first_long;
nl->m_long_prev = HK_SORTED_SET_UNUSED;
if (m_first_long != HK_SORTED_SET_UNUSED){
m_elems[m_first_long].m_long_prev = new_long_pos;
}
m_first_long = new_long_pos;
}
}
#endif
//check();
return return_index;
}
void hk_Sorted_Set::remove_ss_element(hk_ss_index index){
hk_SS_Element *e = & m_elems[index];
unsigned int prev = e->m_prev;
unsigned int next = e->m_next;
if (prev != HK_SORTED_SET_UNUSED) { // not the first element
m_elems[prev].m_next = next;
if (next != HK_SORTED_SET_UNUSED){
m_elems[next].m_prev = prev;
}
}else{
m_first_element = next;
if (next != HK_SORTED_SET_UNUSED){
m_elems[next].m_prev = prev;
m_min_value = m_elems[next].m_value;
}else{
m_min_value = HK_SORTED_SET_MAXVALUE;
}
}
#ifdef HK_SORTED_SET_USELONG
unsigned int long_next = e->m_long_next;
if ( long_next != HK_SORTED_SET_LONG_UNUSED ){
// element is used as a long insert
unsigned int long_prev = e ->m_long_prev;
if ( long_next != HK_SORTED_SET_UNUSED ) {
m_elems[long_next].m_long_prev = long_prev;
}
if (long_prev == HK_SORTED_SET_UNUSED ){
m_first_long = long_next;
}else{
m_elems[long_prev].m_long_next = long_next;
}
}
#endif
m_n_added_elements -= 1;
e->m_next = m_free_list;
m_free_list = index;
//check();
}
#if 0 && defined(HK_DEBUG)
void hk_Sorted_Set::check(){
{
HK_SORTED_SET_FIXED_POINT last_val = 0;
for (unsigned int i = m_first_element; i != HK_SORTED_SET_UNUSED; i = m_elems[i].m_next){
hk_Sorted_Set_Element *e = &m_elems[i];
HK_ASSERT(last_val <= e->m_value);
last_val = e->m_value;
if ( i == first_element ) {
HK_ASSERT( e->m_prev == HK_SORTED_SET_UNUSED);
}else{
HK_ASSERT( m_elems[e->m_prev].m_next == i );
}
if ( e->m_next != HK_SORTED_SET_UNUSED ) {
HK_ASSERT( elems[e->m_next].m_prev == i);
}
}
}
#ifdef HK_SORTED_SET_USELONG
{
HK_SORTED_SET_FIXED_POINT last_val = 0;
for (unsigned int i = m_first_long; i != HK_SORTED_SET_UNUSED; i = elems[i].long_next){
hk_Sorted_Set_Element *e = &m_elems[i];
HK_ASSERT(last_val <= e->m_value);
last_val = e->m_value;
if ( i == m_first_long ) {
HK_ASSERT( e->m_long_prev == HK_SORTED_SET_UNUSED);
}else{
HK_ASSERT( m_elems[e->m_long_prev].m_long_next == i );
}
if ( e->m_long_next != HK_SORTED_SET_UNUSED ) {
HK_ASSERT( m_elems[e->m_long_next].m_long_prev == i);
}
}
}
#endif
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -