Skip to main content

The FilterCache Class Reference

Declaration

class FilterCache { ... }

Private Member Typedefs Index

usingLineOffsets = std::vector< size_t >

Private Constructors Index

FilterCache ()

Public Member Functions Index

boolgetFileContents (const QCString &fileName, size_t startLine, size_t endLine, std::string &str)

Private Member Functions Index

boolgetFileContentsPipe (const QCString &fileName, const QCString &filter, size_t startLine, size_t endLine, std::string &str)
boolgetFileContentsDisk (const QCString &fileName, size_t startLine, size_t endLine, std::string &str)
voidcompileLineOffsets (const QCString &fileName, const std::string &str)
std::tuple< size_t, size_t >getFragmentLocation (const LineOffsets &lineOffsets, size_t startLine, size_t endLine)
voidshrinkBuffer (std::string &str, const QCString &fileName, size_t startLine, size_t endLine)
voidreadFragmentFromFile (std::string &str, const QCString &fileName, size_t startOffset, size_t size=0)

Private Member Attributes Index

std::unordered_map< std::string, FilterCacheItem >m_cache
std::unordered_map< std::string, LineOffsets >m_lineOffsets
std::mutexm_mutex
size_tm_endPos

Public Static Functions Index

static FilterCache &instance ()

Description

Cache for storing the result of filtering a file

Definition at line 530 of file definition.cpp.

Private Member Typedefs

LineOffsets

using FilterCache::LineOffsets = std::vector<size_t>

Definition at line 538 of file definition.cpp.

538 using LineOffsets = std::vector<size_t>;

Private Constructors

FilterCache()

FilterCache::FilterCache ()
inline

Definition at line 722 of file definition.cpp.

Reference m_endPos.

Referenced by instance.

Public Member Functions

getFileContents()

bool FilterCache::getFileContents (const QCString & fileName, size_t startLine, size_t endLine, std::string & str)
inline

collects the part of file fileName starting at startLine and ending at endLine into buffer str. Applies filtering if FILTER_SOURCE_FILES is enabled and the file extension matches a filter. Caches file information so that subsequent extraction of blocks from the same file can be performed efficiently

Definition at line 547 of file definition.cpp.

547 bool getFileContents(const QCString &fileName,size_t startLine,size_t endLine, std::string &str)
548 {
549 bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
550 QCString filter = getFileFilter(fileName,TRUE);
551 bool usePipe = !filter.isEmpty() && filterSourceFiles;
552 return usePipe ? getFileContentsPipe(fileName,filter,startLine,endLine,str)
553 : getFileContentsDisk(fileName,startLine,endLine,str);
554 }

References Config_getBool, getFileContentsDisk, getFileContentsPipe, getFileFilter, QCString::isEmpty and TRUE.

Referenced by readCodeFragment.

Private Member Functions

compileLineOffsets()

void FilterCache::compileLineOffsets (const QCString & fileName, const std::string & str)
inline

computes the starting offset for each line for file fileName, whose contents should already be stored in buffer str.

Definition at line 666 of file definition.cpp.

666 void compileLineOffsets(const QCString &fileName,const std::string &str)
667 {
668 // line 1 (index 0) is at offset 0
669 auto it = m_lineOffsets.emplace(fileName.data(),LineOffsets{0}).first;
670 const char *p=str.data();
671 while (*p)
672 {
673 char c=0;
674 while ((c=*p)!='\n' && c!=0) p++; // search until end of the line
675 if (c!=0) p++;
676 it->second.push_back(p-str.data());
677 }
678 }

References QCString::data and m_lineOffsets.

Referenced by shrinkBuffer.

getFileContentsDisk()

bool FilterCache::getFileContentsDisk (const QCString & fileName, size_t startLine, size_t endLine, std::string & str)
inline

reads the fragment start at startLine and ending at endLine from file fileName into buffer str

Definition at line 640 of file definition.cpp.

640 bool getFileContentsDisk(const QCString &fileName,size_t startLine,size_t endLine,std::string &str)
641 {
642 std::unique_lock<std::mutex> lock(m_mutex);
643 // normal file
644 //printf("getFileContents(%s): no filter\n",qPrint(fileName));
645 auto it = m_lineOffsets.find(fileName.str());
646 if (it == m_lineOffsets.end()) // new file
647 {
648 // read file completely into str buffer
649 readFragmentFromFile(str,fileName,0);
650 // shrink buffer to [startLine..endLine] part
651 shrinkBuffer(str,fileName,startLine,endLine);
652 }
653 else // file already processed before
654 {
655 lock.unlock();
656 auto [ startLineOffset, fragmentSize] = getFragmentLocation(it->second,startLine,endLine);
657 //printf("%s: existing file [%zu-%zu] -> start=%zu size=%zu\n",
658 // qPrint(fileName),startLine,endLine,startLineOffset,fragmentSize);
659 readFragmentFromFile(str,fileName,startLineOffset,fragmentSize);
660 }
661 return true;
662 }

References getFragmentLocation, m_lineOffsets, m_mutex, readFragmentFromFile, shrinkBuffer and QCString::str.

Referenced by getFileContents.

getFileContentsPipe()

bool FilterCache::getFileContentsPipe (const QCString & fileName, const QCString & filter, size_t startLine, size_t endLine, std::string & str)
inline

Definition at line 556 of file definition.cpp.

556 bool getFileContentsPipe(const QCString &fileName,const QCString &filter,
557 size_t startLine,size_t endLine,std::string &str)
558 {
559 std::unique_lock<std::mutex> lock(m_mutex);
560 auto it = m_cache.find(fileName.str());
561 if (it!=m_cache.end()) // cache hit: reuse stored result
562 {
563 lock.unlock();
564 auto item = it->second;
565 //printf("getFileContents(%s): cache hit\n",qPrint(fileName));
566 // file already processed, get the results after filtering from the tmp file
567 Debug::print(Debug::FilterOutput,0,"Reusing filter result for {} from {} at offset={} size={}\n",
568 fileName,Doxygen::filterDBFileName,item.filePos,item.fileSize);
569
570 auto it_off = m_lineOffsets.find(fileName.str());
571 assert(it_off!=m_lineOffsets.end());
572 auto [ startLineOffset, fragmentSize] = getFragmentLocation(it_off->second,startLine,endLine);
573 //printf("%s: existing file [%zu-%zu]->[%zu-%zu] size=%zu\n",
574 // qPrint(fileName),startLine,endLine,startLineOffset,endLineOffset,fragmentSize);
576 item.filePos+startLineOffset, fragmentSize);
577 return true;
578 }
579 else // cache miss: filter active but file not previously processed
580 {
581 //printf("getFileContents(%s): cache miss\n",qPrint(fileName));
582 // filter file
583 QCString cmd=filter+" \""+fileName+"\"";
584 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
585 FILE *f = Portable::popen(cmd,"r");
586 if (f==nullptr)
587 {
588 // handle error
589 err("Error opening filter pipe command '{}'\n",cmd);
590 return false;
591 }
593 FilterCacheItem item;
594 item.filePos = m_endPos;
595 if (bf==nullptr)
596 {
597 // handle error
598 err("Error opening filter database file {}\n",Doxygen::filterDBFileName);
600 return false;
601 }
602 // append the filtered output to the database file
603 size_t size=0;
604 while (!feof(f))
605 {
606 const int blockSize = 4096;
607 char buf[blockSize];
608 size_t bytesRead = fread(buf,1,blockSize,f);
609 size_t bytesWritten = fwrite(buf,1,bytesRead,bf);
610 if (bytesRead!=bytesWritten)
611 {
612 // handle error
613 err("Failed to write to filter database {}. Wrote {} out of {} bytes\n",
614 Doxygen::filterDBFileName,bytesWritten,bytesRead);
616 fclose(bf);
617 return false;
618 }
619 size+=bytesWritten;
620 str+=std::string_view(buf,bytesWritten);
621 }
622 item.fileSize = size;
623 // add location entry to the dictionary
624 m_cache.emplace(fileName.str(),item);
625 Debug::print(Debug::FilterOutput,0,"Storing new filter result for {} in {} at offset={} size={}\n",
626 fileName,Doxygen::filterDBFileName,item.filePos,item.fileSize);
627 // update end of file position
628 m_endPos += size;
630 fclose(bf);
631
632 // shrink buffer to [startLine..endLine] part
633 shrinkBuffer(str,fileName,startLine,endLine);
634 }
635 return true;
636 }

References err, Debug::ExtCmd, FilterCache::FilterCacheItem::filePos, FilterCache::FilterCacheItem::fileSize, Doxygen::filterDBFileName, Debug::FilterOutput, Portable::fopen, getFragmentLocation, m_cache, m_endPos, m_lineOffsets, m_mutex, Portable::pclose, Portable::popen, Debug::print, readFragmentFromFile, shrinkBuffer and QCString::str.

Referenced by getFileContents.

getFragmentLocation()

std::tuple< size_t, size_t > FilterCache::getFragmentLocation (const LineOffsets & lineOffsets, size_t startLine, size_t endLine)
inline

Returns the byte offset and size within a file of a fragment given the array of line offsets and the start and end line of the fragment.

Definition at line 682 of file definition.cpp.

682 auto getFragmentLocation(const LineOffsets &lineOffsets,
683 size_t startLine,size_t endLine) -> std::tuple<size_t,size_t>
684 {
685 assert(startLine > 0);
686 assert(startLine <= endLine);
687 const size_t startLineOffset = lineOffsets[std::min(startLine-1,lineOffsets.size()-1)];
688 const size_t endLineOffset = lineOffsets[std::min(endLine, lineOffsets.size()-1)];
689 assert(startLineOffset <= endLineOffset);
690 const size_t fragmentSize = endLineOffset-startLineOffset;
691 return std::tie(startLineOffset,fragmentSize);
692 };

Referenced by getFileContentsDisk, getFileContentsPipe and shrinkBuffer.

readFragmentFromFile()

void FilterCache::readFragmentFromFile (std::string & str, const QCString & fileName, size_t startOffset, size_t size=0)
inline

Reads the fragment start at byte offset startOffset of file fileName into buffer str. Result will be a null terminated. If size==0 the whole file will be read and startOffset is ignored. If size>0, size bytes will be read.

Definition at line 713 of file definition.cpp.

713 void readFragmentFromFile(std::string &str,const QCString &fileName,size_t startOffset,size_t size=0)
714 {
715 std::ifstream ifs = Portable::openInputStream(fileName,true,true);
716 if (size==0) { startOffset=0; size = static_cast<size_t>(ifs.tellg()); }
717 ifs.seekg(startOffset, std::ios::beg);
718 str.resize(size);
719 ifs.read(str.data(), size);
720 }

Reference Portable::openInputStream.

Referenced by getFileContentsDisk and getFileContentsPipe.

shrinkBuffer()

void FilterCache::shrinkBuffer (std::string & str, const QCString & fileName, size_t startLine, size_t endLine)
inline

Shrinks buffer str which should hold the contents of fileName to the fragment starting a line startLine and ending at line endLine

Definition at line 696 of file definition.cpp.

696 void shrinkBuffer(std::string &str,const QCString &fileName,size_t startLine,size_t endLine)
697 {
698 // compute offsets from start for each line
699 compileLineOffsets(fileName,str);
700 auto it = m_lineOffsets.find(fileName.str());
701 assert(it!=m_lineOffsets.end());
702 const LineOffsets &lineOffsets = it->second;
703 auto [ startLineOffset, fragmentSize] = getFragmentLocation(lineOffsets,startLine,endLine);
704 //printf("%s: new file [%zu-%zu]->[%zu-%zu] size=%zu\n",
705 // qPrint(fileName),startLine,endLine,startLineOffset,endLineOffset,fragmentSize);
706 str.erase(0,startLineOffset);
707 str.resize(fragmentSize);
708 }

References compileLineOffsets, getFragmentLocation, m_lineOffsets and QCString::str.

Referenced by getFileContentsDisk and getFileContentsPipe.

Private Member Attributes

m_cache

std::unordered_map<std::string,FilterCacheItem> FilterCache::m_cache

Definition at line 723 of file definition.cpp.

723 std::unordered_map<std::string,FilterCacheItem> m_cache;

Referenced by getFileContentsPipe.

m_endPos

size_t FilterCache::m_endPos

Definition at line 726 of file definition.cpp.

726 size_t m_endPos;

Referenced by FilterCache and getFileContentsPipe.

m_lineOffsets

std::unordered_map<std::string,LineOffsets> FilterCache::m_lineOffsets

Definition at line 724 of file definition.cpp.

724 std::unordered_map<std::string,LineOffsets> m_lineOffsets;

Referenced by compileLineOffsets, getFileContentsDisk, getFileContentsPipe and shrinkBuffer.

m_mutex

std::mutex FilterCache::m_mutex

Definition at line 725 of file definition.cpp.

725 std::mutex m_mutex;

Referenced by getFileContentsDisk and getFileContentsPipe.

Public Static Functions

instance()

FilterCache & FilterCache::instance ()
static

Definition at line 541 of file definition.cpp.

730{
731 static FilterCache theInstance;
732 return theInstance;
733}

Reference FilterCache.

Referenced by readCodeFragment.


The documentation for this class was generated from the following file:


Generated via doxygen2docusaurus by Doxygen 1.14.0.