wcsbase.mh
来自「开放源码的编译器open watcom 1.6.0版的源代码」· MH 代码 · 共 546 行 · 第 1/2 页
MH
546 行
//
// wcsbase.h Definitions and base implementation for the WATCOM Container
// Skip List class
//
:keep CPP_HDR
:include crwat.sp
//
#ifndef _WCSBASE_H_INCLUDED
#define _WCSBASE_H_INCLUDED
:include readonly.sp
#ifndef __cplusplus
#error wcsbase.h is for use with C++
#endif
#ifndef _STDDEF_H_INCLUDED
#include <stddef.h>
#endif
:include undefnew.sp
//
// Skip Lists are a probabilistic alternative to balanced trees, as
// described in the June 1990 issue of CACM and were invented by
// William Pugh in 1987.
//
//
// constants
//
//
// The probability one more pointer being added to a skip list node
// one quarter and one half. One of these constants may be passed to
// constructor as the optional prob parameter, WCSKIPLIST_PROB_QUARTER
// is used by default.
//
const unsigned WCSKIPLIST_PROB_QUARTER = 3;
const unsigned WCSKIPLIST_PROB_HALF = 1;
//
// The default maximum number of pointers in each node. This is used as
// a default value for the max_ptrs constructor parameter. The default
// prob and max_ptrs constructor parameters are suitable for skip lists
// with upto about 100,000 elements.
//
const unsigned WCDEFAULT_SKIPLIST_MAX_PTRS = 8;
//
// The maximum value for the max_ptrs constructor parameter. If a value
// greater than WCSKIPLIST_MAX_PTRS is passed to the max_ptrs constructor
// parameter, then WCSKIPLIST_MAX_PTRS will be used as the maximum number
// of pointers. With WCSKIPLIST_PROB_QUARTER, WCSKIPLIST_MAX_POINTERS is
// suitable for a skip list containing over four billion elements. With
// WCSKIPLIST_PROB_HALF, WCSKIPLIST_MAX_POINTERS is suitable for a skip
// list containing over one million elements.
//
const unsigned WCSKIPLIST_MAX_PTRS = 20;
//
// WCSkipListPtrs and WCSkipListNode are used internally by the SkipList
// classes to store an element and its pointers into the skip list.
//
struct WCSkipListPtrs {
WCSkipListPtrs *forward[ 1 ]; // variable sized array of forward ptrs
};
template <class Type>
class WCSkipListNode {
public:
Type data;
WCSkipListPtrs ptrs;
inline void * operator new( size_t, void * ptr ){
return ptr;
}
inline WCSkipListNode( const Type &elem ) : data( elem ) {};
inline ~WCSkipListNode() {};
};
//
// Skip List Dictionary implementation object:
// Combines the Key and Value into one object (used internally)
//
template <class Key, class Value>
class WCSkipListDictKeyVal{
public:
Key key;
Value value;
inline WCSkipListDictKeyVal( const WCSkipListDictKeyVal &orig )
: key( orig.key ), value( orig.value ) {};
inline WCSkipListDictKeyVal( const Key &new_key, const Value &new_value )
: key( new_key ), value( new_value ) {};
inline WCSkipListDictKeyVal( const Key &new_key ) : key( new_key ) {};
inline WCSkipListDictKeyVal() {};
inline ~WCSkipListDictKeyVal() {};
};
// Macros to give the user the size of allocated objects
#define WCValSkipListItemSize( Type, num_ptrs ) \
( sizeof( WCSkipListNode<Type> ) + ( num_ptrs - 1 ) * sizeof( void * ) )
#define WCPtrSkipListItemSize( Type, num_ptrs ) \
WCValSkipListItemSize( void *, num_ptrs )
#define WCValSkipListSetItemSize( Type, num_ptrs ) \
WCValSkipListItemSize( Type, num_ptrs )
#define WCPtrSkipListSetItemSize( Type, num_ptrs ) \
WCPtrSkipListItemSize( Type, num_ptrs )
#define WCValSkipListDictItemSize( Key, Value, num_ptrs ) \
( sizeof( WCSkipListNode<WCSkipListDictKeyVal<Key, Value> > ) \
+ ( num_ptrs - 1 ) * sizeof( void * ) )
#define WCPtrSkipListDictItemSize( Key, Value, num_ptrs ) \
WCValSkipListDictItemSize( void *, void *, num_ptrs )
//
// This base class provides skip list base functionality which does not
// require the templated Type.
//
// WCExcept is a base class to provide exception handling.
//
// This is an abstract class to prevent objects of this type being created.
//
class WCSkipNonTempBase : public WCExcept {
private:
// raw memory for the header element pointers
char header_mem[ sizeof( void * ) * WCSKIPLIST_MAX_PTRS ];
// if FALSE, insert will not insert a duplicate value
const WCbool allowDuplicates;
void base_init( unsigned prob, unsigned max_ptrs );
protected:
// user allocator and deallocator functions
void * (* alloc_fn)( size_t );
void (* dealloc_fn)( void *, size_t );
// for base_random_level
_WPRTLINK static unsigned randomsLeft;
_WPRTLINK static unsigned randomBits;
unsigned max_ptrs_in_node;
unsigned probability;
// the current greatest level of elements in the list
// (1 more than the number of levels in the list)
int level;
// a pointer to the header link in the skip list
// (points to initialized header_mem)
WCSkipListPtrs *header;
unsigned num_entries;
// pointer to the nodes stored in the skiplist
typedef WCSkipListPtrs* node_ptr;
// non-templated pointers to the templated Type
typedef const void *TTypePtr;
// true if elements are equivalence
virtual int base_equiv( node_ptr elem1, TTypePtr elem2 ) const = 0;
// true if lhs < rhs
virtual int base_less( node_ptr lhs, TTypePtr rhs ) const = 0;
// equivalents of new and delete
virtual node_ptr base_new_node( TTypePtr elem
, unsigned level_less_1 ) = 0;
virtual void base_delete_node( node_ptr node, unsigned level_less_1 ) = 0;
// the assignment operator base
_WPRTLINK void base_assign( const WCSkipNonTempBase * orig );
// the copy constructor base
_WPRTLINK void base_construct( const WCSkipNonTempBase * orig );
_WPRTLINK node_ptr base_find( TTypePtr elem ) const;
_WPRTLINK node_ptr base_find_with_update( TTypePtr elem,
node_ptr update[] ) const;
// this should be private eventually
inline void base_init_header() {
header = (node_ptr)header_mem;
for( int i = 0; i < max_ptrs_in_node; i++ ){
header->forward[ i ] = 0;
}
};
_WPRTLINK node_ptr base_insert( TTypePtr elem );
// insert a copy of the data contained in this node
// (used by base_construct)
virtual int base_insert_copy( node_ptr ) = 0;
// for WCSkipListDuplicatesBase
_WPRTLINK unsigned base_occurrencesOf( TTypePtr elem ) const;
_WPRTLINK int base_random_level();
// for WCSkipListDuplicatesBase
_WPRTLINK unsigned base_removeAll( TTypePtr elem );
_WPRTLINK node_ptr base_remove_but_not_delete( TTypePtr elem,
int &num_ptrs );
public:
_WPRTLINK WCSkipNonTempBase( unsigned prob, unsigned max_ptrs
, WCbool duplicates );
_WPRTLINK WCSkipNonTempBase( unsigned prob, unsigned max_ptrs
, void * (*user_alloc)( size_t )
, void (*user_dealloc)( void *, size_t )
, WCbool duplicates );
inline virtual ~WCSkipNonTempBase() {};
_WPRTLINK void clear();
_WPRTLINK WCbool remove( TTypePtr elem );
};
//
// WCSkipListBase provides the skip list functionality
//
// This is an abstract class to prevent objects of this type being created.
//
template<class Type>
class WCSkipListBase : public WCSkipNonTempBase {
protected:
// the nodes stored in the skip list
typedef WCSkipListNode<Type> NodeType;
inline node_ptr base_find( const Type &elem ) const {
return( WCSkipNonTempBase::base_find( &elem ) );
};
// given a node_ptr (which points to the forward pointers in a node),
// return a pointer to the whole node (WCSkipListNode<Type>)
// this WILL NOT WORK if sizeof( char ) != 1
static inline WCSkipListNode<Type> *base_whole_node( node_ptr node_ptrs ) {
return( (NodeType *)( (char *)node_ptrs
- offsetof( NodeType, ptrs ) ) );
};
inline node_ptr base_insert( const Type &elem ) {
return( WCSkipNonTempBase::base_insert( &elem ) );
}
// insert a copy of the data contained in node
virtual int base_insert_copy( node_ptr node ) {
return( base_insert( base_whole_node( node )->data ) != 0 );
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?