umemcmp.h

00001 /*<std-header orig-src='shore' incl-file-exclusion='UMEMCMP_H'>
00002 
00003  $Id: umemcmp.h,v 1.21 2010/05/26 01:20:12 nhall Exp $
00004 
00005 SHORE -- Scalable Heterogeneous Object REpository
00006 
00007 Copyright (c) 1994-99 Computer Sciences Department, University of
00008                       Wisconsin -- Madison
00009 All Rights Reserved.
00010 
00011 Permission to use, copy, modify and distribute this software and its
00012 documentation is hereby granted, provided that both the copyright
00013 notice and this permission notice appear in all copies of the
00014 software, derivative works or modified versions, and any portions
00015 thereof, and that both notices appear in supporting documentation.
00016 
00017 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00018 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00019 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00020 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00021 
00022 This software was developed with support by the Advanced Research
00023 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00024 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00025 Further funding for this work was provided by DARPA through
00026 Rome Research Laboratory Contract No. F30602-97-2-0247.
00027 
00028 */
00029 
00030 #ifndef UMEMCMP_H
00031 #define UMEMCMP_H
00032 
00033 #include "w_defines.h"
00034 
00035 /*  -- do not edit anything above this line --   </std-header>*/
00036 
00037 /*
00038  * This file provides an version of memcmp() called umemcmp that
00039  * compared unsigned characters instead of signed.
00040  * For correct operation of the btree code umemcmp() must be used.
00041  * In fact we recommend you using memcmp only to test for 
00042  * == or != as it can give different results for > and < depending
00043  * on the compiler.
00044  */
00045 
00046 #include <assert.h>
00047 
00048 #ifndef W_WORKAROUND_H
00049 #include <w_workaround.h>
00050 #endif
00051 
00052 // Simple byte-by-byte comparisions
00053 inline int __umemcmp(const unsigned char* p, const unsigned char* q, int n)
00054 {
00055     int i;
00056     for (i = 0; (i < n) && (*p == *q); i++, p++, q++) ;
00057     return (i < n) ? *p - *q : 0;
00058 }
00059 
00060 /*
00061  * XXX this is a dangerous assumption; correct operation for umemcpy()
00062  * should be verified!
00063  *
00064  * So far only sparcs (sunos) have been found to need a special umemcmp.
00065  * On HPs and Decstation/ultrix the library version of memcmp
00066  * uses unsigned chars.
00067  */
00068 #if defined(COMMON_USE_UMEMCMP) || defined(Sparc)
00069 
00070 inline uint int_alignment_check(const void *i) 
00071 {
00072     uint tmp = (ptrdiff_t) i & (sizeof(int)-1);
00073     w_assert9(tmp == (ptrdiff_t) i % sizeof(int));
00074     return tmp;
00075 }
00076 inline bool is_int_aligned(const void *i)
00077 {
00078     return int_alignment_check(i) == 0;
00079 }
00080 
00081 // Smarter way if things are aligned.  Basically this does the
00082 // comparison an int at a time.
00083 inline int umemcmp_smart(const void* p_, const void* q_, int n)
00084 {
00085     const unsigned char* p = (const unsigned char*)p_;
00086     const unsigned char* q = (const unsigned char*)q_;
00087 
00088     // If short, just use simple method
00089     if (n < (int)(2*sizeof(int)))
00090         return __umemcmp(p, q, n);
00091 
00092     // See if both are aligned to the same value
00093     if (int_alignment_check(p) == int_alignment_check(q)) {
00094         if (!is_int_aligned(p)) {
00095             // can't handle misaliged, use simple method
00096             return __umemcmp(p, q, n);
00097         }
00098 
00099         // Compare an int at a time
00100         uint i;
00101         for (i = 0; i < n/sizeof(int); i++) {
00102             if (((unsigned*)p)[i] != ((unsigned*)q)[i]) {
00103                 return (((unsigned*)p)[i] > ((unsigned*)q)[i]) ? 1 : -1;
00104             }
00105         }
00106         // take care of the leftover bytes
00107         int j = i*sizeof(int);
00108         if (j) return __umemcmp(p+j, q+j, n-j);
00109     } else {
00110         // misaligned with respect to eachother
00111         return __umemcmp(p, q, n);
00112     }
00113     return 0; // must be equal
00114 }
00115 
00116 inline int umemcmp_old(const void* p, const void* q, int n)
00117 {
00118     return __umemcmp((unsigned char*)p, (unsigned char*)q, n);
00119 }
00120 
00121 inline int umemcmp(const void* p, const void* q, int n)
00122 {
00123 #if W_DEBUG_LEVEL > 2
00124     // check for any bugs in umemcmp_smart
00125     int t1 = umemcmp_smart(p, q, n);
00126     int t2 = __umemcmp((unsigned char*)p, (unsigned char*)q, n);
00127     assert(t1 == t2 || (t1 < 0 && t2 < 0) || (t1 > 0 && t2 > 0));
00128     return t1;
00129 #else
00130     return umemcmp_smart(p, q, n);
00131 #endif 
00132 }
00133 
00134 #else  /* defined(Sparc) */
00135 
00136 inline int umemcmp(const void* p, const void* q, int n)
00137 {
00138 #if W_DEBUG_LEVEL > 2
00139     // verify that memcmp is equivalent to umemcmp
00140     int t1 = memcmp(p, q, n);
00141     int t2 = __umemcmp((unsigned char*)p, (unsigned char*)q, n);
00142     w_assert3(t1 == t2 || (t1 < 0 && t2 < 0) || (t1 > 0 && t2 > 0));
00143     return t1;
00144 #else
00145     return memcmp(p, q, n);
00146 #endif 
00147 }
00148 
00149 #endif /* defined(Sparc)  */
00150 
00151 /*<std-footer incl-file-exclusion='UMEMCMP_H'>  -- do not edit anything below this line -- */
00152 
00153 #endif          /*</std-footer>*/

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7