00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <volume_io/internal_volume_io.h>
00016
#include <bicpl/data_structures.h>
00017
#include <bicpl/prog_utils.h>
00018
00019
#ifndef lint
00020
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Data_structures/skiplist.c,v 1.12 2000/02/06 15:30:12 stever Exp $";
00021
#endif
00022
00023
private int get_random_level(
void );
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define MAX_SKIP_LEVELS 50
00040 #define SKIP_P 0.5
00041
00042 typedef struct
00043
{
00044 skip_struct *update[
MAX_SKIP_LEVELS];
00045 }
update_struct;
00046
00047 #define ALLOC_SKIP_STRUCT( ptr, n_level ) \
00048
ALLOC_VAR_SIZED_STRUCT( ptr, skip_struct *, n_level )
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 public void initialize_skiplist(
00064
skiplist_struct *skiplist )
00065 {
00066
int i;
00067
00068 skiplist->
level = 1;
00069
00070
ALLOC_SKIP_STRUCT( skiplist->
header,
MAX_SKIP_LEVELS );
00071
00072 for_less( i, 0,
MAX_SKIP_LEVELS )
00073 skiplist->
header->
forward[i] = NULL;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 private BOOLEAN
find_data_position(
00092
skiplist_struct *skiplist,
00093
float key,
00094
update_struct *update )
00095 {
00096
int i;
00097
skip_struct *x;
00098 BOOLEAN found;
00099
00100 x = skiplist->
header;
00101
00102
for( i = skiplist->
level-1; i >= 0; --i )
00103 {
00104
while( x->
forward[i] != NULL && x->
forward[i]->
key < key )
00105 x = x->
forward[i];
00106
00107 update->
update[i] = x;
00108 }
00109
00110 x = update->
update[0]->
forward[0];
00111
00112 found = x != NULL && x->
key == key;
00113
00114
return( found );
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 private void insert_data_in_skiplist(
00134
skiplist_struct *skiplist,
00135
update_struct *update,
00136
float key,
00137
void *data_ptr )
00138 {
00139
int i, new_level;
00140
skip_struct *x;
00141
#ifdef DEBUG
00142
int prev_size = -1;
00143
void test_skiplist_integrity();
00144
#endif
00145
00146 new_level =
get_random_level();
00147
00148
if( new_level > skiplist->
level )
00149 {
00150
for( i = skiplist->
level; i < new_level; ++i )
00151 update->
update[i] = skiplist->
header;
00152
00153
#ifdef DEBUG
00154
prev_size = skiplist->
level;
00155
#endif
00156
skiplist->
level = new_level;
00157 }
00158
00159
ALLOC_SKIP_STRUCT( x, new_level );
00160
00161 x->
data_ptr = data_ptr;
00162 x->
key = key;
00163
00164
for( i = 0; i < new_level; ++i )
00165 {
00166 x->
forward[i] = update->
update[i]->
forward[i];
00167 update->
update[i]->
forward[i] = x;
00168 }
00169
00170
#ifdef DEBUG
00171
test_skiplist_integrity( skiplist );
00172
#endif
00173
}
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 private void delete_entry_from_skiplist(
00190
skiplist_struct *skiplist,
00191
update_struct *update )
00192 {
00193
int i;
00194
skip_struct *x;
00195
00196 x = update->
update[0]->
forward[0];
00197
00198
for( i = 0; i < skiplist->
level; ++i )
00199 {
00200
if( update->
update[i]->
forward[i] != x )
00201
break;
00202 update->
update[i]->
forward[i] = x->
forward[i];
00203 }
00204
00205 FREE( x );
00206
00207
while( skiplist->
level > 1 &&
00208 skiplist->
header->
forward[skiplist->
level-1] == NULL )
00209 {
00210 --skiplist->
level;
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 private int get_random_level(
void )
00229 {
00230
int level;
00231
00232 level = 1;
00233
00234
while(
get_random_0_to_1() <
SKIP_P && level <
MAX_SKIP_LEVELS-1 )
00235 ++level;
00236
00237
return( level );
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 public void delete_skiplist(
00254
skiplist_struct *skiplist )
00255 {
00256
skip_struct *ptr, *deleting;
00257
00258 ptr = skiplist->
header;
00259
00260
while( ptr != NULL )
00261 {
00262 deleting = ptr;
00263 ptr = ptr->
forward[0];
00264 FREE( deleting );
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 public BOOLEAN
search_skiplist(
00285
skiplist_struct *skiplist,
00286
float key,
00287
void **data_ptr )
00288 {
00289 BOOLEAN found;
00290
update_struct update_ptrs;
00291
00292 found =
find_data_position( skiplist, key, &update_ptrs );
00293
00294
if( found )
00295 *data_ptr = update_ptrs.
update[0]->
forward[0]->
data_ptr;
00296
00297
return( found );
00298 }
00299
00300 public BOOLEAN
search_skiplist_and_return_pointer(
00301
skiplist_struct *skiplist,
00302
float key,
00303
skip_struct **entry_ptr,
00304
void **data_ptr )
00305 {
00306 BOOLEAN found;
00307
update_struct update_ptrs;
00308
00309 found =
find_data_position( skiplist, key, &update_ptrs );
00310
00311
if( found )
00312 {
00313 *entry_ptr = update_ptrs.
update[0]->
forward[0];
00314 *data_ptr = (*entry_ptr)->
data_ptr;
00315 }
00316
00317
return( found );
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 public BOOLEAN
insert_in_skiplist(
00336
skiplist_struct *skiplist,
00337
float key,
00338
void *data_ptr )
00339 {
00340 BOOLEAN already_there;
00341
update_struct update_ptrs;
00342
00343 already_there =
find_data_position( skiplist, key, &update_ptrs );
00344
00345
if( !already_there )
00346
insert_data_in_skiplist( skiplist, &update_ptrs, key, data_ptr );
00347
00348
return( !already_there );
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 public BOOLEAN
delete_from_skiplist(
00367
skiplist_struct *skiplist,
00368
float key,
00369
void **data_ptr )
00370 {
00371 BOOLEAN in_skiplist;
00372
update_struct update_ptrs;
00373
00374 in_skiplist =
find_data_position( skiplist, key, &update_ptrs );
00375
00376
if( in_skiplist )
00377 {
00378 *data_ptr = update_ptrs.
update[0]->
forward[0]->
data_ptr;
00379
00380
delete_entry_from_skiplist( skiplist, &update_ptrs );
00381 }
00382
00383
return( in_skiplist );
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 public BOOLEAN
get_first_skiplist_entry(
00404
skiplist_struct *skiplist,
00405
skip_struct **entry_ptr,
00406
float *key,
00407
void **data_ptr )
00408 {
00409 *entry_ptr = skiplist->
header->
forward[0];
00410
00411
if( *entry_ptr != NULL )
00412 {
00413 *key = (*entry_ptr)->
key;
00414 *data_ptr = (*entry_ptr)->data_ptr;
00415 }
00416
00417
return( *entry_ptr != NULL );
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 public BOOLEAN
get_next_skiplist_entry(
00436
skip_struct **entry_ptr,
00437
float *key,
00438
void **data_ptr )
00439 {
00440 *entry_ptr = (*entry_ptr)->
forward[0];
00441
00442
if( *entry_ptr != NULL )
00443 {
00444 *key = (*entry_ptr)->
key;
00445 *data_ptr = (*entry_ptr)->data_ptr;
00446 }
00447
00448
return( *entry_ptr != NULL );
00449 }
00450
00451
#ifdef DEBUG
00452
00453
private BOOLEAN test_skiplist_integrity(
00454
skiplist_struct *skiplist )
00455 {
00456
int i;
00457
update_struct update;
00458 BOOLEAN okay;
00459
00460 for_less( i, 0, skiplist->
level )
00461 update.update[i] = skiplist->header->forward[i];
00462
00463 while( update.update[0] != NULL )
00464 {
00465 i = 1;
00466
while( i < skiplist->
level && update.
update[0] == update.
update[i] )
00467 {
00468 update.
update[i] = update.
update[i]->
forward[i];
00469 ++i;
00470 }
00471 update.
update[0] = update.
update[0]->
forward[0];
00472 }
00473
00474 okay =
TRUE;
00475
00476 for_less( i, 0, skiplist->
level )
00477 if( update.update[i] != NULL )
00478 okay = FALSE;
00479
00480 if( !okay )
00481 handle_internal_error( "Skiplist integrity" );
00482
00483 return( okay );
00484 }
00485 #endif