@@ -1574,8 +1574,10 @@ void TFile::Map(Option_t *opt)
1574
1574
1575
1575
const unsigned char nDigits = std::log10 (fEND ) + 1 ;
1576
1576
1577
+ std::optional<ROOT::Detail::TKeyMapNode> lastNode;
1577
1578
const auto tkeyInfos = WalkTKeys ();
1578
1579
for (const auto &key : tkeyInfos) {
1580
+ lastNode = key;
1579
1581
switch (key.fType ) {
1580
1582
case ROOT::Detail::TKeyMapNode::kError :
1581
1583
Printf (" Address = %" PRIu64 " \t Nbytes = %u\t =====E R R O R=======" , key.fAddr , key.fLen );
@@ -1616,7 +1618,7 @@ void TFile::Map(Option_t *opt)
1616
1618
}
1617
1619
1618
1620
if (!forComp) {
1619
- Int_t datime = tkeyInfos. empty () ? 0 : tkeyInfos. back (). fDatime ;
1621
+ Int_t datime = lastNode ? lastNode-> fDatime : 0 ;
1620
1622
Int_t date, time;
1621
1623
TDatime::GetDateTime (datime, date, time);
1622
1624
Printf (" %d/%06d At:%-*lld N=%-8d %-14s" , date, time, nDigits + 1 , fEND , 1 , " END" );
@@ -1625,94 +1627,108 @@ void TFile::Map(Option_t *opt)
1625
1627
}
1626
1628
}
1627
1629
1628
- std::vector< ROOT::Detail::TKeyMapNode> TFile::WalkTKeys ()
1630
+ ROOT::Detail::TKeyMapIterable TFile::WalkTKeys ()
1629
1631
{
1630
- std::vector<ROOT::Detail::TKeyMapNode> res;
1631
-
1632
- constexpr int headerSize = 512 ;
1633
-
1634
- std::uint64_t idcur = fBEGIN ;
1635
- const std::uint64_t end = fEND ;
1636
- while (idcur < end) {
1637
- Seek (idcur);
1638
- auto nread = headerSize;
1639
- if (idcur + nread >= end)
1640
- nread = fEND - idcur - 1 ;
1641
-
1642
- char header[headerSize];
1643
- if (ReadBuffer (header, nread)) {
1644
- // ReadBuffer returns kTRUE in case of failure.
1645
- res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kError });
1646
- break ;
1647
- }
1632
+ return ROOT::Detail::TKeyMapIterable (this );
1633
+ }
1648
1634
1649
- char *buffer = header;
1650
- Int_t nbytes;
1651
- frombuf (buffer, &nbytes);
1652
- if (!nbytes) {
1653
- res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kError });
1654
- break ;
1655
- }
1656
- if (nbytes < 0 ) {
1657
- // free slot
1658
- res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kGap , static_cast <std::uint32_t >(-nbytes)});
1659
- idcur -= nbytes;
1660
- continue ;
1661
- }
1635
+ ROOT::Detail::TKeyMapIterable::TIterator::TIterator (TFile *file, std::uint64_t addr) : fFile(file), fCurAddr(addr)
1636
+ {
1637
+ if (addr == 0 )
1638
+ fCurAddr = fFile ->fBEGIN ;
1639
+ Advance ();
1640
+ }
1662
1641
1663
- auto &node = res.emplace_back (idcur, ROOT::Detail::TKeyMapNode::kKey , nbytes);
1642
+ std::optional<ROOT::Detail::TKeyMapNode> ROOT::Detail::TKeyMapIterable::TIterator::Next ()
1643
+ {
1644
+ constexpr int headerSize = 512 ;
1664
1645
1665
- frombuf (buffer, &node.fKeyVersion );
1666
- frombuf (buffer, &node.fObjLen );
1667
- frombuf (buffer, &node.fDatime );
1668
- frombuf (buffer, &node.fKeyLen );
1669
- frombuf (buffer, &node.fCycle );
1670
- if (node.fKeyVersion > 1000 ) {
1671
- frombuf (buffer, &node.fSeekKey );
1672
- frombuf (buffer, &node.fSeekPdir );
1646
+ const std::uint64_t idcur = fCurAddr ;
1647
+ const std::uint64_t end = fFile ->fEND ;
1648
+ if (idcur >= end)
1649
+ return std::nullopt;
1650
+
1651
+ fFile ->Seek (idcur);
1652
+ auto nread = headerSize;
1653
+ if (idcur + nread >= end)
1654
+ nread = end - idcur - 1 ;
1655
+
1656
+ char header[headerSize];
1657
+ if (fFile ->ReadBuffer (header, nread)) {
1658
+ // ReadBuffer returns kTRUE in case of failure.
1659
+ auto node = ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kError };
1660
+ fCurAddr = end;
1661
+ return node;
1662
+ }
1663
+
1664
+ char *buffer = header;
1665
+ Int_t nbytes;
1666
+ frombuf (buffer, &nbytes);
1667
+ if (!nbytes) {
1668
+ auto node = ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kError };
1669
+ fCurAddr = end;
1670
+ return node;
1671
+ }
1672
+
1673
+ if (nbytes < 0 ) {
1674
+ // free slot
1675
+ auto node =
1676
+ ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kGap , static_cast <std::uint32_t >(-nbytes)};
1677
+ fCurAddr -= nbytes;
1678
+ return node;
1679
+ }
1680
+
1681
+ auto node = ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kKey , static_cast <std::uint32_t >(nbytes)};
1682
+ frombuf (buffer, &node.fKeyVersion );
1683
+ frombuf (buffer, &node.fObjLen );
1684
+ frombuf (buffer, &node.fDatime );
1685
+ frombuf (buffer, &node.fKeyLen );
1686
+ frombuf (buffer, &node.fCycle );
1687
+ if (node.fKeyVersion > 1000 ) {
1688
+ frombuf (buffer, &node.fSeekKey );
1689
+ frombuf (buffer, &node.fSeekPdir );
1690
+ } else {
1691
+ Int_t skey, sdir;
1692
+ frombuf (buffer, &skey);
1693
+ frombuf (buffer, &sdir);
1694
+ node.fSeekKey = static_cast <Long64_t>(skey);
1695
+ node.fSeekPdir = static_cast <Long64_t>(sdir);
1696
+ }
1697
+
1698
+ const auto readString = [&buffer, &header](bool skipCheck = false ) {
1699
+ char stringLen;
1700
+ char str[256 ];
1701
+ if (!skipCheck && ((buffer - header) >= headerSize)) {
1702
+ stringLen = 0 ;
1673
1703
} else {
1674
- Int_t skey, sdir;
1675
- frombuf (buffer, &skey);
1676
- frombuf (buffer, &sdir);
1677
- node.fSeekKey = static_cast <Long64_t>(skey);
1678
- node.fSeekPdir = static_cast <Long64_t>(sdir);
1679
- }
1680
-
1681
- const auto readString = [&buffer, &header] (bool skipCheck = false ) {
1682
- char stringLen;
1683
- char str[256 ];
1684
- if (!skipCheck && ((buffer - header) >= headerSize)) {
1704
+ frombuf (buffer, &stringLen);
1705
+ if (stringLen < 0 )
1685
1706
stringLen = 0 ;
1686
- } else {
1687
- frombuf (buffer, &stringLen);
1688
- if (stringLen < 0 )
1689
- stringLen = 0 ;
1690
- else if ((buffer - header) + stringLen > headerSize)
1691
- stringLen = headerSize - (buffer - header);
1692
- }
1693
- for (int i = 0 ; i < stringLen; ++i)
1694
- frombuf (buffer, &str[i]);
1695
- str[static_cast <int >(stringLen)] = 0 ;
1707
+ else if ((buffer - header) + stringLen > headerSize)
1708
+ stringLen = headerSize - (buffer - header);
1709
+ }
1710
+ for (int i = 0 ; i < stringLen; ++i)
1711
+ frombuf (buffer, &str[i]);
1712
+ str[static_cast <int >(stringLen)] = 0 ;
1696
1713
1697
- return std::string (str, stringLen);
1698
- };
1714
+ return std::string (str, stringLen);
1715
+ };
1699
1716
1700
- node.fClassName = readString (true );
1717
+ node.fClassName = readString (true );
1701
1718
1702
- if (idcur == static_cast <std::uint64_t >(fSeekFree ))
1703
- node.fClassName = " FreeSegments" ;
1704
- else if (idcur == static_cast <std::uint64_t >(fSeekInfo ))
1705
- node.fClassName = " StreamerInfo" ;
1706
- else if (idcur == static_cast <std::uint64_t >(fSeekKeys ))
1707
- node.fClassName = " KeysList" ;
1719
+ if (idcur == static_cast <std::uint64_t >(fFile -> fSeekFree ))
1720
+ node.fClassName = " FreeSegments" ;
1721
+ else if (idcur == static_cast <std::uint64_t >(fFile -> fSeekInfo ))
1722
+ node.fClassName = " StreamerInfo" ;
1723
+ else if (idcur == static_cast <std::uint64_t >(fFile -> fSeekKeys ))
1724
+ node.fClassName = " KeysList" ;
1708
1725
1709
- node.fKeyName = readString ();
1710
- node.fKeyTitle = readString ();
1726
+ node.fKeyName = readString ();
1727
+ node.fKeyTitle = readString ();
1711
1728
1712
- idcur += nbytes;
1713
- }
1729
+ fCurAddr += nbytes;
1714
1730
1715
- return res ;
1731
+ return node ;
1716
1732
}
1717
1733
1718
1734
// //////////////////////////////////////////////////////////////////////////////
0 commit comments