00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <VM/VM_Math.h>
00025 #include "UT_Assert.h"
00026 #include "UT_ValArray.h"
00027 #include "UT_Types.h"
00028 #include "UT_Math.h"
00029 #include <algorithm>
00030
00031 template <typename T>
00032 UT_ValArray<T>::UT_ValArray(const UT_ValArray<T> &a)
00033 : arrSize(a.entries()), nbrEntries(a.entries())
00034 {
00035 int64 en;
00036
00037 en = a.entries();
00038 if (en)
00039 {
00040 arr = (T *)calloc(sizeof(T), en);
00041 memcpy(arr, a.arr, en * sizeof(T));
00042 }
00043 else arr = 0;
00044 }
00045
00046 template <typename T>
00047 UT_ValArray<T>::~UT_ValArray()
00048 {
00049 if (arr) free(arr);
00050 }
00051
00052 template <typename T>
00053 void
00054 UT_ValArray<T>::swap( UT_ValArray<T> &other )
00055 {
00056 UTswap( arr, other.arr );
00057 UTswap( arrSize, other.arrSize );
00058 UTswap( nbrEntries, other.nbrEntries );
00059 }
00060
00061 template <typename T>
00062 unsigned int
00063 UT_ValArray<T>::insert(unsigned int index)
00064 {
00065 if (index >= nbrEntries)
00066 {
00067 if (index >= arrSize) resize(bumpAlloc(index));
00068 nbrEntries = index+1;
00069 return index;
00070 }
00071 if (nbrEntries == arrSize)
00072 {
00073 resize(bumpAlloc(arrSize+1));
00074 }
00075 memmove(&arr[index+1], &arr[index],((nbrEntries-index)*sizeof(T)));
00076
00077 nbrEntries++;
00078 return index;
00079 }
00080
00081 template <typename T>
00082 unsigned int
00083 UT_ValArray<T>::append(T t)
00084 {
00085 if (nbrEntries == arrSize)
00086 resize(bumpAlloc(arrSize+1));
00087
00088 arr[nbrEntries] = t;
00089 return nbrEntries++;
00090 }
00091
00092 template <typename T>
00093 void
00094 UT_ValArray<T>::appendMultiple(T t, int count)
00095 {
00096 UT_ASSERT_P(count >= 0);
00097 if (count <= 0)
00098 return;
00099 if (nbrEntries + count >= arrSize)
00100 resize(bumpAlloc(nbrEntries + count));
00101
00102 int i;
00103 for (i = 0; i < count; i++)
00104 arr[nbrEntries+i] = t;
00105 nbrEntries += count;
00106 }
00107
00108 template <typename T>
00109 unsigned int
00110 UT_ValArray<T>::insert(T t, unsigned int index)
00111 {
00112 if (index == nbrEntries) return append(t);
00113 return insertAt(t, index);
00114 }
00115
00116 template <typename T>
00117 unsigned int
00118 UT_ValArray<T>::sortedInsert(T t, Comparator compare)
00119 {
00120 int low, mid, high;
00121
00122 low = 0;
00123 high = entries() - 1;
00124 while (low <= high)
00125 {
00126 mid = (low + high) / 2;
00127 if (compare(&t, &arr[mid]) < 0)
00128 high = mid - 1;
00129 else if (compare(&t, &arr[mid]) > 0)
00130 low = mid + 1;
00131 else
00132 {
00133 insertAt(t, mid);
00134 return mid;
00135 }
00136 }
00137 insertAt(t, low);
00138 return low;
00139 }
00140
00141 template <typename T>
00142 unsigned int
00143 UT_ValArray<T>::sortedInsert(T t)
00144 {
00145 int low, mid, high;
00146
00147 low = 0;
00148 high = entries() - 1;
00149 while (low <= high)
00150 {
00151 mid = (low + high) / 2;
00152 if (t < arr[mid])
00153 high = mid - 1;
00154 else if (t > arr[mid])
00155 low = mid + 1;
00156 else
00157 {
00158 insertAt(t, mid);
00159 return mid;
00160 }
00161 }
00162 insertAt(t, low);
00163 return low;
00164 }
00165
00166 template <typename T>
00167 unsigned int
00168 UT_ValArray<T>::uniqueSortedInsert(T t, Comparator compare)
00169 {
00170 int low, mid, high;
00171
00172 low = 0;
00173 high = entries() - 1;
00174 while (low <= high)
00175 {
00176 mid = (low + high) / 2;
00177 if (compare(&t, &arr[mid]) < 0)
00178 high = mid - 1;
00179 else if (compare(&t, &arr[mid]) > 0)
00180 low = mid + 1;
00181 else
00182 return (unsigned)mid;
00183 }
00184 insertAt(t, low);
00185 return low;
00186 }
00187
00188 template <typename T>
00189 unsigned int
00190 UT_ValArray<T>::uniqueSortedInsert(T t)
00191 {
00192 int low, mid, high;
00193
00194 low = 0;
00195 high = entries() - 1;
00196 while (low <= high)
00197 {
00198 mid = (low + high) / 2;
00199 if (t < arr[mid])
00200 high = mid - 1;
00201 else if (t > arr[mid])
00202 low = mid + 1;
00203 else
00204 return (unsigned)mid;
00205 }
00206 insertAt(t, low);
00207 return low;
00208 }
00209
00210 template <typename T>
00211 int
00212 UT_ValArray<T>::uniqueSortedFind(T item) const
00213 {
00214 int low;
00215 int mid;
00216 int high;
00217
00218 low = 0;
00219 high = entries() - 1;
00220 while( low <= high )
00221 {
00222 mid = (low + high) / 2;
00223 if( item < arr[mid] )
00224 high = mid - 1;
00225 else if( item > arr[mid] )
00226 low = mid + 1;
00227 else
00228 return mid;
00229 }
00230
00231 return -1;
00232 }
00233
00234 template <typename T>
00235 unsigned int
00236 UT_ValArray<T>::heapPush(T t, Comparator compare)
00237 {
00238 int i = append(t);
00239
00240 while( i > 0 && compare(&arr[i / 2], &t) < 0 )
00241 {
00242 arr[i] = arr[i / 2];
00243 i = i / 2;
00244 }
00245 arr[i] = t;
00246 return i;
00247 }
00248
00249 template <typename T>
00250 unsigned int
00251 UT_ValArray<T>::heapPush(T t)
00252 {
00253 int i = append(t);
00254
00255 while( i > 0 && (arr[i / 2] < t) )
00256 {
00257 arr[i] = arr[i / 2];
00258 i = i / 2;
00259 }
00260 arr[i] = t;
00261 return i;
00262 }
00263
00264 template <typename T>
00265 T
00266 UT_ValArray<T>::heapPop(Comparator compare)
00267 {
00268 UT_ASSERT_P(nbrEntries > 0);
00269 T result = (T)0;
00270 if( nbrEntries > 0 )
00271 {
00272 result = arr[0];
00273 arr[0] = arr[nbrEntries - 1];
00274 removeAt(nbrEntries - 1);
00275 heapify(0, compare);
00276 }
00277 return result;
00278 }
00279
00280 template <typename T>
00281 T
00282 UT_ValArray<T>::heapPop()
00283 {
00284 UT_ASSERT_P(nbrEntries > 0);
00285 T result = (T)0;
00286 if( nbrEntries > 0 )
00287 {
00288 result = arr[0];
00289 arr[0] = arr[nbrEntries - 1];
00290 removeAt(nbrEntries - 1);
00291 heapify(0);
00292 }
00293 return result;
00294 }
00295
00296
00297 template <typename T>
00298 unsigned int
00299 UT_ValArray<T>::concat(const UT_ValArray<T> &a)
00300 {
00301 unsigned int extraSpace;
00302
00303 extraSpace = a.nbrEntries;
00304
00305 if ( ( arrSize - nbrEntries ) <= extraSpace )
00306 resize( arrSize + extraSpace );
00307
00308 memcpy( &arr[nbrEntries], &(a.arr[0]), extraSpace * sizeof(T) );
00309
00310 return (nbrEntries += extraSpace);
00311 }
00312
00313 template <typename T>
00314 unsigned int
00315 UT_ValArray<T>::multipleInsert(unsigned int index, unsigned int count)
00316 {
00317 int bigindex = index+count;
00318
00319 if (index >= nbrEntries)
00320 {
00321 if (bigindex >= (int)arrSize) resize(bumpAlloc(bigindex));
00322 nbrEntries = bigindex;
00323 return index;
00324 }
00325 if ((nbrEntries + count) > arrSize)
00326 {
00327 resize(bumpAlloc(nbrEntries+count));
00328 }
00329
00330 memmove(&arr[bigindex], &arr[index],((nbrEntries-index)*sizeof(T)));
00331 nbrEntries += count;
00332 return index;
00333 }
00334
00335 template <typename T>
00336 unsigned int
00337 UT_ValArray<T>::insertAt(T t, unsigned int index)
00338 {
00339 if (index >= nbrEntries)
00340 {
00341 if (index >= arrSize) resize(bumpAlloc(index));
00342 nbrEntries = index+1;
00343 arr[index] = t;
00344 return index;
00345 }
00346 if (nbrEntries == arrSize)
00347 {
00348 resize(bumpAlloc(arrSize));
00349 }
00350 memmove(&arr[index+1], &arr[index],((nbrEntries-index)*sizeof(T)));
00351 arr[index] = t;
00352
00353 nbrEntries++;
00354 return index;
00355 }
00356
00357 template <typename T>
00358 int
00359 UT_ValArray<T>::findAndRemove(T t)
00360 {
00361 int idx = find(t);
00362 return (idx < 0) ? -1 : removeAt((unsigned int)idx);
00363 }
00364
00365 template <typename T>
00366 int
00367 UT_ValArray<T>::removeAt(unsigned int idx)
00368 {
00369 if (idx != --nbrEntries)
00370 memmove(&arr[idx], &arr[idx+1], ((nbrEntries-idx)*sizeof(T)));
00371
00372 return idx;
00373 }
00374
00375 template <typename T>
00376 int
00377 UT_ValArray<T>::shift(unsigned int srcIdx, unsigned int destIdx,
00378 unsigned int howMany)
00379 {
00380 if (srcIdx == destIdx) return 0;
00381 unsigned int sIdx = srcIdx + howMany - 1;
00382 unsigned int dIdx = destIdx + howMany - 1;
00383 if (sIdx>=arrSize || dIdx>=arrSize) return -1;
00384 if (dIdx>=nbrEntries|| (sIdx==nbrEntries-1 && sIdx > dIdx))
00385 nbrEntries = dIdx+1;
00386
00387 memmove(&arr[destIdx], &arr[srcIdx], (howMany*sizeof(T)));
00388 return 0;
00389 }
00390
00391 template <typename T>
00392 void
00393 UT_ValArray<T>::cycle(int howMany)
00394 {
00395 T *tempPtr;
00396 int numShift;
00397 int remaining;
00398
00399 if (howMany == 0 || nbrEntries < 1) return;
00400
00401 numShift = howMany % (int)nbrEntries;
00402 if (numShift < 0) numShift += nbrEntries;
00403 remaining = nbrEntries - numShift;
00404 tempPtr = new T[numShift];
00405
00406 memmove(tempPtr, &arr[remaining], (numShift * sizeof(T)));
00407 memmove(&arr[numShift], &arr[0], (remaining * sizeof(T)));
00408 memmove(&arr[0], tempPtr, (numShift * sizeof(T)));
00409
00410 delete [] tempPtr;
00411 }
00412
00413 template <typename T>
00414 void
00415 UT_ValArray<T>::constant(T value)
00416 {
00417 for (int i = 0; i < nbrEntries; i++)
00418 {
00419 arr[i] = value;
00420 }
00421 }
00422
00423 template <typename T>
00424 void
00425 UT_ValArray<T>::constant()
00426 {
00427 memset(arr, 0, nbrEntries*sizeof(T));
00428 }
00429
00430 template <typename T>
00431 int
00432 UT_ValArray<T>::find(T t, unsigned int s) const
00433 {
00434 const T *p, *end;
00435
00436 for( p = arr + s, end = arr + nbrEntries; p < end; ++p )
00437 if( *p == t ) return (p - arr);
00438 return -1;
00439 }
00440
00441 template <typename T>
00442 int
00443 UT_ValArray<T>::find(T t, Comparator compare) const
00444 {
00445 T *found;
00446
00447 if( nbrEntries == 0 ) return -1;
00448
00449 found = (T *)::bsearch(&t, arr, (int)nbrEntries, sizeof(T),
00450 (ut_ptr_compare_func_t)compare);
00451 return found ? (found - arr) : -1;
00452 }
00453
00454 template <typename T>
00455 void
00456 UT_ValArray<T>::reverse()
00457 {
00458 int i;
00459 for( i=0; i<nbrEntries/2; i++ )
00460 UTswap( arr[i], arr[nbrEntries-1-i] );
00461 }
00462
00463 template <typename T>
00464 void
00465 UT_ValArray<T>::sort(Comparator compare)
00466 {
00467 qsort(arr, nbrEntries, sizeof(T), (ut_ptr_compare_func_t)compare);
00468 }
00469
00470 template <typename T>
00471 void
00472 UT_ValArray<T>::sortAscending()
00473 {
00474
00475 std::sort(arr, arr + nbrEntries);
00476 }
00477
00478 template <typename T>
00479 T
00480 UT_ValArray<T>::selectNthLargest(int idx)
00481 {
00482
00483
00484 UT_ASSERT(entries() > 0);
00485 if (entries() == 0)
00486 return (T)0;
00487
00488 idx = SYSclamp(idx, (int)0, (int)(entries())-1);
00489
00490 std::nth_element(arr, &arr[idx], &arr[entries()]);
00491
00492 return arr[idx];
00493 }
00494
00495 template <typename T>
00496 void
00497 UT_ValArray<T>::resize(unsigned int sz, unsigned short)
00498 {
00499 if (sz == arrSize) return;
00500 if (sz == 0 )
00501 {
00502 if (arr) free(arr);
00503 arr = 0;
00504 arrSize = nbrEntries = 0;
00505 return;
00506 }
00507
00508
00509 if (arr)
00510 {
00511 arr = (T *)realloc(arr, sz*sizeof(T));
00512
00513 if (sz > arrSize)
00514 memset(arr+arrSize, 0, sizeof(T)*(sz-arrSize));
00515 }
00516 else arr = (T *)calloc(sizeof(T), sz);
00517
00518 if (sz < arrSize && nbrEntries > sz) nbrEntries = sz;
00519 arrSize = sz;
00520 }
00521
00522 template <typename T>
00523 UT_ValArray<T> &
00524 UT_ValArray<T>::operator=(const UT_ValArray<T> &a)
00525 {
00526 if (this == &a)
00527 return *this;
00528
00529 if (arrSize < a.entries())
00530 resize(a.entries());
00531
00532 memcpy(arr, a.arr, a.entries()*sizeof(T));
00533 nbrEntries = a.entries();
00534
00535 return *this;
00536 }
00537
00538 template <typename T>
00539 bool
00540 UT_ValArray<T>::operator==(const UT_ValArray<T> &a) const
00541 {
00542 if (this == &a) return true;
00543 if (nbrEntries != a.entries()) return false;
00544 for (int i = 0; i < nbrEntries; i++)
00545 if (!(arr[i] == a(i))) return false;
00546 return true;
00547 }
00548
00549 template <typename T>
00550 bool
00551 UT_ValArray<T>::operator!=(const UT_ValArray<T> &a) const
00552 {
00553 return (!operator==(a));
00554 }
00555
00556 template <typename T>
00557 int
00558 UT_ValArray<T>::isEqual(const UT_ValArray<T> &a, Comparator compare) const
00559 {
00560 if (this == &a) return 1;
00561 if (nbrEntries != a.entries()) return 0;
00562 for (unsigned int i = 0; i < nbrEntries; i++)
00563 {
00564 T v2 = a(i);
00565 if (compare(&arr[i], &v2)) return 0;
00566 }
00567 return 1;
00568 }
00569
00570 template <typename T>
00571 unsigned int
00572 UT_ValArray<T>::apply(int (*applyFct)(T &t, void *d), void *d)
00573 {
00574 unsigned int i;
00575 for (i = 0; i < nbrEntries; i++)
00576 if (applyFct(arr[i], d)) break;
00577 return i;
00578 }
00579
00580 template <typename T>
00581 void
00582 UT_ValArray<T>::display() const
00583 {
00584 printf("%d entries, contents not displayable.\n");
00585 }
00586
00587 template <typename T>
00588 void
00589 UT_ValArray<T>::heapify(unsigned int idx, Comparator compare)
00590 {
00591 int lidx = 2*idx, ridx = lidx + 1;
00592 int largest = idx;
00593
00594 if( lidx < nbrEntries && compare(&arr[lidx], &arr[largest]) > 0 )
00595 {
00596 largest = lidx;
00597 }
00598 if( ridx < nbrEntries && compare(&arr[ridx], &arr[largest]) > 0 )
00599 {
00600 largest = ridx;
00601 }
00602 if( largest != idx )
00603 {
00604 UTswap(arr[idx], arr[largest]);
00605 heapify(largest, compare);
00606 }
00607 }
00608
00609 template <typename T>
00610 void
00611 UT_ValArray<T>::heapify(unsigned int idx)
00612 {
00613 int lidx = 2*idx, ridx = lidx + 1;
00614 int largest = idx;
00615
00616 if( lidx < nbrEntries && (arr[lidx] > arr[largest]) )
00617 {
00618 largest = lidx;
00619 }
00620 if( ridx < nbrEntries && (arr[ridx] > arr[largest]) )
00621 {
00622 largest = ridx;
00623 }
00624 if( largest != idx )
00625 {
00626 UTswap(arr[idx], arr[largest]);
00627 heapify(largest);
00628 }
00629 }
00630
00631 template <typename T>
00632 void
00633 UT_ValArray<T>::fromStdVector(const std::vector<T> &vec)
00634 {
00635 entries(0);
00636 for (int i=0; i<vec.size(); ++i)
00637 append(vec[i]);
00638 }
00639
00640 template <typename T>
00641 void
00642 UT_ValArray<T>::toStdVector(std::vector<T> &vec) const
00643 {
00644 vec.clear();
00645 for (int i=0; i < entries(); ++i)
00646 vec.push_back((*this)(i));
00647 }
00648
00649
00650
00651
00652
00653
00654
00655 template <typename T>
00656 void
00657 UT_ValArray<T>::merge( const UT_ValArray<T> &other, int direction, bool allow_dups )
00658 {
00659 UT_ValArray<T> result;
00660 int our_item;
00661 int our_idx;
00662 int other_item;
00663 int other_idx;
00664 int item_dir;
00665
00666
00667 if (other.entries() == 0)
00668 return;
00669 if (entries() == 0)
00670 {
00671 concat(other);
00672 return;
00673 }
00674
00675 UT_ASSERT( direction == -1 || direction == +1 );
00676 direction = (direction > 0) ? +1 : -1;
00677
00678 our_idx = 0;
00679 other_idx = 0;
00680 while( our_idx < entries() && other_idx < other.entries() )
00681 {
00682 our_item = (*this)(our_idx);
00683 other_item = other(other_idx);
00684
00685 item_dir = our_item - other_item;
00686 if( item_dir != 0 )
00687 {
00688
00689
00690 item_dir = ( (item_dir > 0) ? +1 : -1 ) * direction;
00691 }
00692
00693 if( item_dir < 0 )
00694 {
00695 result.append( our_item );
00696 our_idx++;
00697 }
00698 else if( item_dir > 0 )
00699 {
00700 result.append( other_item );
00701 other_idx++;
00702 }
00703 else
00704 {
00705 result.append( our_item );
00706 our_idx++;
00707 if( allow_dups )
00708 result.append( other_item );
00709 other_idx++;
00710 }
00711 }
00712
00713 UT_ASSERT( our_idx == entries() || other_idx == other.entries() );
00714
00715 for( ; our_idx < entries(); our_idx++ )
00716 result.append( (*this)(our_idx) );
00717 for( ; other_idx < other.entries(); other_idx++ )
00718 result.append( other(other_idx) );
00719
00720
00721 swap( result );
00722 }
00723
00724 template <typename T>
00725 void
00726 UT_ValArray<T>::sortedUnion(const UT_ValArray<T> &other)
00727 {
00728 UT_ValArray<T> temp;
00729 sortedUnion( other, temp );
00730 swap( temp );
00731 }
00732
00733 template <typename T>
00734 void
00735 UT_ValArray<T>::sortedUnion(const UT_ValArray<T> &other,
00736 UT_ValArray<T> &result) const
00737 {
00738 T *first1 = arr;
00739 T *last1 = arr + nbrEntries;
00740 T *first2 = other.arr;
00741 T *last2 = other.arr + other.nbrEntries;
00742
00743
00744 UT_ASSERT(&result != this && &result != &other);
00745 UT_ASSERT(result.entries() == 0);
00746
00747 while( first1 != last1 && first2 != last2 )
00748 {
00749 if( *first1 < *first2 )
00750 {
00751 result.append( *first1 );
00752 ++first1;
00753 }
00754 else if( *first2 < *first1 )
00755 {
00756 result.append( *first2 );
00757 ++first2;
00758 }
00759 else
00760 {
00761 result.append( *first1 );
00762 ++first1;
00763 ++first2;
00764 }
00765 }
00766 while( first1 != last1 )
00767 {
00768 result.append( *first1 );
00769 ++first1;
00770 }
00771 while( first2 != last2 )
00772 {
00773 result.append( *first2 );
00774 ++first2;
00775 }
00776 }
00777
00778 template <typename T>
00779 void
00780 UT_ValArray<T>::sortedIntersection(const UT_ValArray<T> &other)
00781 {
00782 UT_ValArray<T> temp;
00783 sortedIntersection( other, temp );
00784 swap( temp );
00785 }
00786
00787 template <typename T>
00788 void
00789 UT_ValArray<T>::sortedIntersection( const UT_ValArray<T> &other,
00790 UT_ValArray<T> &result ) const
00791 {
00792 T *first1 = arr;
00793 T *last1 = arr + nbrEntries;
00794 T *first2 = other.arr;
00795 T *last2 = other.arr + other.nbrEntries;
00796
00797 while (first1 != last1 && first2 != last2)
00798 if( *first1 < *first2 )
00799 ++first1;
00800 else if( *first2 < *first1 )
00801 ++first2;
00802 else {
00803 result.append( *first1 );
00804 ++first1;
00805 ++first2;
00806 }
00807 }
00808
00809 template <typename T>
00810 void
00811 UT_ValArray<T>::sortedSetDifference(const UT_ValArray<T> &other)
00812 {
00813 UT_ValArray<T> temp;
00814 sortedSetDifference( other, temp );
00815 swap( temp );
00816 }
00817
00818 template <typename T>
00819 void
00820 UT_ValArray<T>::sortedSetDifference( const UT_ValArray<T> &other,
00821 UT_ValArray<T> &result ) const
00822 {
00823 T *first1 = arr;
00824 T *last1 = arr + nbrEntries;
00825 T *first2 = other.arr;
00826 T *last2 = other.arr + other.nbrEntries;
00827
00828 while (first1 != last1 && first2 != last2)
00829 {
00830 if( *first1 < *first2 )
00831 {
00832 result.append( *first1 );
00833 ++first1;
00834 }
00835 else if( *first2 < *first1 )
00836 ++first2;
00837 else
00838 {
00839 ++first1;
00840 ++first2;
00841 }
00842 }
00843 while( first1 != last1 )
00844 {
00845 result.append( *first1 );
00846 ++first1;
00847 }
00848 }
00849
00850 template <typename T>
00851 void
00852 UT_ValArray<T>::sortedRemoveDuplicates()
00853 {
00854 int src, dst, n;
00855 T cmp;
00856
00857 n = entries();
00858
00859
00860 if (n < 2)
00861 return;
00862
00863 dst = 1;
00864 cmp = (*this)(0);
00865 for (src = 1; src < n; src++)
00866 {
00867 if ((*this)(src) == cmp)
00868 {
00869
00870 }
00871 else
00872 {
00873 if (src != dst)
00874 {
00875 (*this)(dst) = (*this)(src);
00876 }
00877 dst++;
00878 }
00879 }
00880
00881
00882 entries(dst);
00883 }