void LFS::clean(unsigned numToClean) { unsigned numCleaned = 0; unsigned numFull = 0; while (numCleaned < numToClean || numFull == numToClean - 1) { unsigned emptyCount = 0; unsigned mostEmptyIdx = 0; for (unsigned i = 0; i < segments.size(); i++) { unsigned currentDeadCount = countDeadBlocksForSegmentAtIndex(i); if (emptyCount < currentDeadCount) { emptyCount = currentDeadCount; mostEmptyIdx = i; } } unsigned fillCount = 1024; unsigned mostFullIdx = 1; for (unsigned i = 0; i < segments.size(); i++) { unsigned currentDeadCount = countDeadBlocksForSegmentAtIndex(i); if (fillCount < currentDeadCount) { fillCount = currentDeadCount; mostFullIdx = i; } } combineSegments(mostFullIdx, mostEmptyIdx); if (segments[mostEmptyIdx]->isEmpty()) { segments.erase(segments.begin() + mostEmptyIdx); numCleaned++; } if (segments[mostFullIdx]->emptyBlockCount() == 0) { numFull++; } } }
void ScanLineSegmenter::segment(const Image<uint8_t>& image, std::vector<LineSegment> & segmented) { std::vector<LineSegment>& lineSegments = segmented; lineSegments.clear(); auto it = image.data().begin(); for (int y = 0; y < image.height(); ++y) { LineSegment currentSegment{ y, 0, 0, -1 }; short length = 0; for (int x = 0; x < image.width(); ++x) { if (*it) { ++length; } else { if (length) { currentSegment.xRight = currentSegment.xLeft + length - 1; lineSegments.push_back(currentSegment); length = 0; } currentSegment.xLeft = x + 1; } ++it; } if (length) { currentSegment.xRight = currentSegment.xLeft + length - 1; lineSegments.push_back(currentSegment); } } std::vector<short> mapping; { auto lineEnd = begin(lineSegments); auto previousLineBegin = begin(lineSegments); auto previousLineEnd = begin(lineSegments); const auto last = end(lineSegments); do { lineEnd = std::adjacent_find(previousLineEnd, last, [](const LineSegment& lhs, const LineSegment& rhs) { return lhs.y != rhs.y; }); lineEnd += lineEnd != last; combineSegments(previousLineBegin, previousLineEnd, previousLineEnd, lineEnd, mapping); previousLineBegin = previousLineEnd; previousLineEnd = lineEnd; } while (lineEnd != last); for (auto& line : lineSegments) { while (mapping[line.blobId] != line.blobId) { line.blobId = mapping[line.blobId]; } } } std::stable_sort(begin(lineSegments), end(lineSegments), byBlobId); }