umemcmp.h

00001 /*<std-header orig-src='shore' incl-file-exclusion='UMEMCMP_H'>
00002 
00003  $Id: umemcmp.h,v 1.22 2010/12/08 17:37:34 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  */
00066 #if defined(Sparc)
00067 
00068 inline uint int_alignment_check(const void *i) 
00069 {
00070     uint tmp = (ptrdiff_t) i & (sizeof(int)-1);
00071     w_assert9(tmp == (ptrdiff_t) i % sizeof(int));
00072     return tmp;
00073 }
00074 inline bool is_int_aligned(const void *i)
00075 {
00076     return int_alignment_check(i) == 0;
00077 }
00078 
00079 // Smarter way if things are aligned.  Basically this does the
00080 // comparison an int at a time.
00081 inline int umemcmp_smart(const void* p_, const void* q_, int n)
00082 {
00083     const unsigned char* p = (const unsigned char*)p_;
00084     const unsigned char* q = (const unsigned char*)q_;
00085 
00086     // If short, just use simple method
00087     if (n < (int)(2*sizeof(int)))
00088         return __umemcmp(p, q, n);
00089 
00090     // See if both are aligned to the same value
00091     if (int_alignment_check(p) == int_alignment_check(q)) {
00092         if (!is_int_aligned(p)) {
00093             // can't handle misaliged, use simple method
00094             return __umemcmp(p, q, n);
00095         }
00096 
00097         // Compare an int at a time
00098         uint i;
00099         for (i = 0; i < n/sizeof(int); i++) {
00100             if (((unsigned*)p)[i] != ((unsigned*)q)[i]) {
00101                 return (((unsigned*)p)[i] > ((unsigned*)q)[i]) ? 1 : -1;
00102             }
00103         }
00104         // take care of the leftover bytes
00105         int j = i*sizeof(int);
00106         if (j) return __umemcmp(p+j, q+j, n-j);
00107     } else {
00108         // misaligned with respect to eachother
00109         return __umemcmp(p, q, n);
00110     }
00111     return 0; // must be equal
00112 }
00113 
00114 inline int umemcmp_old(const void* p, const void* q, int n)
00115 {
00116     return __umemcmp((unsigned char*)p, (unsigned char*)q, n);
00117 }
00118 
00119 inline int umemcmp(const void* p, const void* q, int n)
00120 {
00121 #if W_DEBUG_LEVEL > 2
00122     // check for any bugs in umemcmp_smart
00123     int t1 = umemcmp_smart(p, q, n);
00124     int t2 = __umemcmp((unsigned char*)p, (unsigned char*)q, n);
00125     assert(t1 == t2 || (t1 < 0 && t2 < 0) || (t1 > 0 && t2 > 0));
00126     return t1;
00127 #else
00128     return umemcmp_smart(p, q, n);
00129 #endif 
00130 }
00131 
00132 #else  /* defined(Sparc) */
00133 
00134 inline int umemcmp(const void* p, const void* q, int n)
00135 {
00136 #if W_DEBUG_LEVEL > 2
00137     // verify that memcmp is equivalent to umemcmp
00138     int t1 = memcmp(p, q, n);
00139     int t2 = __umemcmp((unsigned char*)p, (unsigned char*)q, n);
00140     w_assert3(t1 == t2 || (t1 < 0 && t2 < 0) || (t1 > 0 && t2 > 0));
00141     return t1;
00142 #else
00143     return memcmp(p, q, n);
00144 #endif 
00145 }
00146 
00147 #endif /* defined(Sparc)  */
00148 
00149 /*<std-footer incl-file-exclusion='UMEMCMP_H'>  -- do not edit anything below this line -- */
00150 
00151 #endif          /*</std-footer>*/

Generated on Thu Dec 9 08:42:26 2010 for Shore Storage Manager by  doxygen 1.4.7