Less back and forths by returning semi count in page

This commit is contained in:
Thomas Krijnen
2025-10-25 15:08:21 +02:00
parent 5910b39766
commit e82ca0e932
3 changed files with 33 additions and 3 deletions
@@ -138,6 +138,8 @@ class StatsCollector:
counters: list
num_semis: int = 0
def __init__(self):
self.streamer = ifcopenshell_wrapper.InstanceStreamer()
self.needs_data = True
@@ -151,17 +153,19 @@ class StatsCollector:
def feed(self, data: str):
self.streamer.pushPage(data)
self.needs_data = False
self.num_semis = self.streamer.semicolonCount()
@staticmethod
def fromFilePath(fn, page_size: int = 4096):
def fromFilePath(fn, page_size: int = 102400):
collector = StatsCollector()
collector.page_size = page_size
collector.feedFromFile(open(str(fn), encoding="ascii"))
return collector
def next(self):
if self.streamer.hasSemicolon():
if self.num_semis > 0:
if inst := self.streamer.readInstancePy(True):
self.num_semis -= 1
return inst["type"], dict(list(inst.items())[2:])
else:
self.finalized = True
+3 -1
View File
@@ -139,7 +139,9 @@ private:
bool hasSemicolon() const;
void pushPage(const std::string& page);
size_t semicolonCount() const;
void pushPage(const std::string& page);
InstanceStreamer();
+24
View File
@@ -1371,6 +1371,30 @@ bool IfcParse::InstanceStreamer::hasSemicolon() const {
return false;
}
size_t IfcParse::InstanceStreamer::semicolonCount() const {
auto local_stream = stream_->clone();
auto local_lexer = IfcSpfLexer(&local_stream);
Token t;
size_t count = 0;
try {
t = local_lexer.Next();
} catch (const std::out_of_range&) {
return false;
}
while (t.type != Token_NONE) {
if (TokenFunc::isOperator(t, ';')) {
count++;
}
try {
t = local_lexer.Next();
} catch (const std::out_of_range&) {
// This most likely happens when a page boundary is contained within a string
break;
}
}
return count;
}
void IfcParse::InstanceStreamer::pushPage(const std::string& page)
{
stream_->pushNextPage(page);