void sinksocket_i::createByteSwappedVector(const std::vector<T, U> &original, unsigned short byteSwap) { unsigned int numSwap = byteSwap; size_t dataSize = sizeof(T); // If 1 is requested, use the word size associated with the data if (numSwap == 1) { numSwap = dataSize; } size_t numBytes = original.size() * dataSize; size_t oldLeftoverSize = leftovers[typeid(T).name()][byteSwap].size(); size_t totalSize = numBytes + oldLeftoverSize; size_t newLeftoverSize; // Create the vector to hold the swapped data std::vector<char> newData; // Make sure to send an exact multiple of numSwap if it's greater than 1 if (numSwap > 1) { newLeftoverSize = totalSize % numSwap; if (numSwap != dataSize) { LOG_WARN(sinksocket_i, "Data size of " << dataSize << " is not equal to byte swap size of " << numSwap <<"."); } } else { newLeftoverSize = 0; } //Don't have to deal with leftover data. This should be the typical case if (newLeftoverSize == 0 && oldLeftoverSize == 0) { if (numSwap > 1) { newData.resize(numBytes); vectorSwap(reinterpret_cast<const char *>(original.data()), newData, numSwap); byteSwapped[typeid(T).name()][byteSwap] = newData; } } else { LOG_WARN(sinksocket_i, "Byte swapping and packet sizes are not compatible. Swapping bytes over adjacent packets"); newData.reserve(totalSize - newLeftoverSize); newData.insert(newData.begin(), leftovers[typeid(T).name()][byteSwap].begin(), leftovers[typeid(T).name()][byteSwap].end()); newData.insert(newData.begin() + oldLeftoverSize, reinterpret_cast<const char *>(original.data()), reinterpret_cast<const char *>(original.data()) + numBytes - newLeftoverSize); if (numSwap > 1) { vectorSwap(newData, numSwap); } byteSwapped[typeid(T).name()][byteSwap] = newData; leftovers[typeid(T).name()][byteSwap].clear(); // If we have new leftovers, populate it now if (newLeftoverSize != 0) { leftovers[typeid(T).name()][byteSwap].insert(leftovers[typeid(T).name()][byteSwap].begin(), reinterpret_cast<const char *>(original.data()) + numBytes - newLeftoverSize, reinterpret_cast<const char *>(original.data()) + numBytes); } } }
bool description::deleteChapter(const chapter & c) { int k = find(c, 0, chapters_.size() - 1); if (k == -1) return false; delete chapters_[k]; chapters_[k] = nullptr; vectorSwap(k, chapters_.size() - 1); chapters_.pop_back(); isSorted_ = false; fullSort(); return true; }
unsigned int description::partition(unsigned int low, unsigned int high) { chapter * pivot = chapters_[low]; unsigned int i = low; unsigned int j = high + 1; while (true) { do { ++i; } while (*chapters_[i] < *pivot); do { --j; } while (*chapters_[j] < *pivot); if (i >= j) return j; vectorSwap(i, j); } }
/** * Ternary partitioning of buckets with Lomuto's scheme. * Subbuckets of size 2 and 3 are directly sorted and * partitions smaller than a given threshold are sorted by insertion sort. * @param leftPtr points to the leftmost position of the current bucket. * @param rightPtr points to the rightmost position of the current bucket. * @param offset is the length of the common prefix of the suffixes (a multiple of q). * @param q is the initial prefix length used for the bucket sort. It also determines the increase of offset. * @param sufPtrMap at position i points to the rightmost position of the bucket that contains suffix i (bptr). */ static void partitionUpdateRecurse_SaBucket(Kbs_Ulong *const leftPtr, register Kbs_Ulong *const rightPtr, register const Kbs_Ulong offset, register const Kbs_Ulong q, Kbs_Ulong **const sufPtrMap) { register Kbs_Ulong *pivot; Kbs_Ulong tmpSize = rightPtr-leftPtr; if (tmpSize < 10000) { tmpSize = tmpSize/4; pivot = sufPtrMap[*(leftPtr + tmpSize) + offset]; register const Kbs_Ulong *const pivotb = sufPtrMap[*(leftPtr+ 2*tmpSize) + offset]; register const Kbs_Ulong *const pivotc = sufPtrMap[*(rightPtr-tmpSize) + offset]; register const Kbs_Int medNumber = medianOfThreeUlong(pivot, pivotb, pivotc); register Kbs_Ulong *pivotPtr = leftPtr + tmpSize; if (medNumber > 0){ pivotPtr = (medNumber == 1) ? (leftPtr+ 2*tmpSize) : (rightPtr-tmpSize); pivot = (medNumber == 1) ? pivotb : pivotc; } register const Kbs_Ulong swapTmp = *pivotPtr; *pivotPtr = *leftPtr; *leftPtr = swapTmp; } else { Kbs_Ulong *keyPtrList[9]; tmpSize = tmpSize/10; int i; for (i=0; i<9; i++) { keyPtrList[i] = leftPtr + (i+1)*tmpSize; } /* insertion sort */ for (i=1; i<9; i++) { register const Kbs_Ulong *tempValue = keyPtrList[i]; register const Kbs_Ulong *const tempHashValue = sufPtrMap[(*tempValue)+offset]; int j = i-1; while(j >= 0 && sufPtrMap[*(keyPtrList[j])+offset] > tempHashValue) { keyPtrList[j+1] = keyPtrList[j]; j--; } keyPtrList[j+1] = tempValue; } register const Kbs_Ulong swapTmp = *(keyPtrList[4]); *(keyPtrList[4]) = *leftPtr; *leftPtr = swapTmp; pivot = sufPtrMap[*leftPtr + offset]; } register Kbs_Ulong *pivotRightPtr = leftPtr+1; while (pivotRightPtr <= rightPtr && sufPtrMap[*pivotRightPtr + offset] == pivot) { ++pivotRightPtr; } register Kbs_Ulong *smallerPivotPtr = pivotRightPtr; while (smallerPivotPtr <= rightPtr && sufPtrMap[*smallerPivotPtr + offset] < pivot) { smallerPivotPtr++; } register Kbs_Ulong *frontPtr = smallerPivotPtr-1; while (frontPtr++ < rightPtr) { register Kbs_Ulong *const sortkey = sufPtrMap[*frontPtr + offset]; if (sortkey <= pivot) { register const Kbs_Ulong swapTmp = *frontPtr; *frontPtr = *smallerPivotPtr; *smallerPivotPtr = swapTmp; if (sortkey == pivot) { *smallerPivotPtr = *pivotRightPtr; *(pivotRightPtr++) = swapTmp; } smallerPivotPtr++; } } /* vector swap the pivot elements*/ const Kbs_Ulong numberSmaller = smallerPivotPtr-pivotRightPtr; if (numberSmaller > 0) { register const Kbs_Ulong swapsize = MIN((Kbs_Ulong)(pivotRightPtr-leftPtr), numberSmaller); Kbs_Ulong *pivotRightTmpPtr = leftPtr + swapsize-1; vectorSwap(leftPtr, pivotRightTmpPtr, smallerPivotPtr-1); /* recursively sort < partition*/ if (numberSmaller == 1) { sufPtrMap[*leftPtr] = leftPtr; } else { if (numberSmaller == 2) { computeBucketSize2_SaBucket(leftPtr, leftPtr+1, offset, q, sufPtrMap); } else { if (numberSmaller == 3) computeBucketSize3_SaBucket(leftPtr, leftPtr+2, offset, q, sufPtrMap); else partitionUpdateRecurse_SaBucket(leftPtr, leftPtr+numberSmaller-1, offset, q, sufPtrMap); } } } /* update pivots and recursively sort = partition*/ Kbs_Ulong *leftTmpPtr = leftPtr+numberSmaller; smallerPivotPtr--; if (leftTmpPtr == smallerPivotPtr) { sufPtrMap[*leftTmpPtr] = leftTmpPtr; if (leftTmpPtr == rightPtr) return; } else { Kbs_Ulong newOffset = (pivot == rightPtr)? (2*offset) : offset+q; if (leftTmpPtr+1 == smallerPivotPtr) { computeBucketSize2_SaBucket(leftTmpPtr, smallerPivotPtr, newOffset, q, sufPtrMap); if (rightPtr == smallerPivotPtr) return; } else { if (leftTmpPtr+2 == smallerPivotPtr) { computeBucketSize3_SaBucket(leftTmpPtr, smallerPivotPtr, newOffset, q, sufPtrMap); if (rightPtr == smallerPivotPtr) return; } else { if (rightPtr == smallerPivotPtr) { newOffset = computeDiffDepthBucket_SaBucket(leftPtr+numberSmaller, rightPtr, newOffset, q, sufPtrMap); partitionUpdateRecurse_SaBucket(leftTmpPtr, rightPtr, newOffset, q, sufPtrMap); return; } while(leftTmpPtr <= smallerPivotPtr) { sufPtrMap[*leftTmpPtr] = smallerPivotPtr; leftTmpPtr++; } if (smallerPivotPtr < leftPtr+numberSmaller + INSSORT_LIMIT) { insSortUpdateRecurse_SaBucket(leftPtr+numberSmaller, smallerPivotPtr, newOffset, q, sufPtrMap); } else partitionUpdateRecurse_SaBucket(leftPtr+numberSmaller, smallerPivotPtr, newOffset, q, sufPtrMap); } } } /* recursively sort > partition*/ ++smallerPivotPtr; if (smallerPivotPtr == rightPtr) { sufPtrMap[*rightPtr] = rightPtr; return; } if (smallerPivotPtr+1 == rightPtr) { computeBucketSize2_SaBucket(smallerPivotPtr, rightPtr, offset, q, sufPtrMap); return; } if (smallerPivotPtr+2 == rightPtr) { computeBucketSize3_SaBucket(smallerPivotPtr, rightPtr, offset, q, sufPtrMap); return; } partitionUpdateRecurse_SaBucket(smallerPivotPtr, rightPtr, offset, q, sufPtrMap); }