@@ -151,6 +151,7 @@ The structure of a directory is shown in TDirectoryFile::TDirectoryFile
151
151
#include " TGlobal.h"
152
152
#include " ROOT/RConcurrentHashColl.hxx"
153
153
#include < memory>
154
+ #include < inttypes.h>
154
155
155
156
#ifdef R__FBSD
156
157
#include < sys/extattr.h>
@@ -1568,128 +1569,150 @@ void TFile::Map(Option_t *opt)
1568
1569
{
1569
1570
TString options (opt);
1570
1571
options.ToLower ();
1571
- bool forComp = options.Contains (" forcomp" );
1572
- bool extended = options.Contains (" extended" );
1572
+ const bool forComp = options.Contains (" forcomp" );
1573
+ const bool extended = options.Contains (" extended" );
1573
1574
1574
- Short_t keylen,cycle;
1575
- UInt_t datime;
1576
- Int_t nbytes,date,time,objlen;
1577
- date = 0 ;
1578
- time = 0 ;
1579
- Long64_t seekkey,seekpdir;
1580
- char *buffer;
1581
- char nwhc;
1582
- Long64_t idcur = fBEGIN ;
1575
+ const unsigned char nDigits = std::log10 (fEND ) + 1 ;
1576
+
1577
+ const auto tkeyInfos = WalkTKeys ();
1578
+ for (const auto &key : tkeyInfos) {
1579
+ switch (key.fType ) {
1580
+ case ROOT::Detail::TKeyMapNode::kError :
1581
+ Printf (" Address = %" PRIu64 " \t Nbytes = %u\t =====E R R O R=======" , key.fAddr , key.fLen );
1582
+ break ;
1583
+
1584
+ case ROOT::Detail::TKeyMapNode::kGap :
1585
+ Printf (" Address = %" PRIu64 " \t Nbytes = %d\t =====G A P===========" , key.fAddr , -key.fLen );
1586
+ break ;
1587
+
1588
+ case ROOT::Detail::TKeyMapNode::kKey :
1589
+ TString extrainfo;
1590
+ if (extended)
1591
+ extrainfo.Form (" name: %-16s title: %s" , key.fKeyName .c_str (), key.fKeyTitle .c_str ());
1592
+
1593
+ if (forComp) {
1594
+ // Printing to help compare two files.
1595
+ if (key.fObjLen != static_cast <Int_t>(key.fLen ) - key.fKeyLen ) {
1596
+ Float_t cx = static_cast <float >(key.fObjLen + key.fKeyLen ) / key.fLen ;
1597
+ Printf (" At:%-*" PRIu64 " N=%-8u K=%-3d O=%-8d %-14s CX = %5.2f %s" , nDigits + 1 , key.fAddr , key.fLen ,
1598
+ key.fKeyLen , key.fObjLen , key.fClassName .c_str (), cx, extrainfo.Data ());
1599
+ } else {
1600
+ Printf (" At:%-*" PRIu64 " N=%-8u K=%-3d O=%-8d %-14s CX = 1 %s" , nDigits + 1 , key.fAddr , key.fLen ,
1601
+ key.fKeyLen , key.fObjLen , key.fClassName .c_str (), extrainfo.Data ());
1602
+ }
1603
+ } else {
1604
+ Int_t date, time;
1605
+ TDatime::GetDateTime (key.fDatime , date, time);
1606
+ if (key.fObjLen != static_cast <Int_t>(key.fLen ) - key.fKeyLen ) {
1607
+ Float_t cx = static_cast <float >(key.fObjLen + key.fKeyLen ) / key.fLen ;
1608
+ Printf (" %d/%06d At:%-*" PRIu64 " N=%-8u %-14s CX = %5.2f %s" , date, time, nDigits + 1 , key.fAddr ,
1609
+ key.fLen , key.fClassName .c_str (), cx, extrainfo.Data ());
1610
+ } else {
1611
+ Printf (" %d/%06d At:%-*" PRIu64 " N=%-8u %-14s %s" , date, time, nDigits + 1 , key.fAddr ,
1612
+ key.fLen , key.fClassName .c_str (), extrainfo.Data ());
1613
+ }
1614
+ }
1615
+ }
1616
+ }
1583
1617
1584
- constexpr Int_t nwheader = 512 ;
1618
+ if (!forComp) {
1619
+ Int_t datime = tkeyInfos.empty () ? 0 : tkeyInfos.back ().fDatime ;
1620
+ Int_t date, time;
1621
+ TDatime::GetDateTime (datime, date, time);
1622
+ Printf (" %d/%06d At:%-*lld N=%-8d %-14s" , date, time, nDigits + 1 , fEND , 1 , " END" );
1623
+ } else {
1624
+ Printf (" At:%-*lld N=%-8d K= O= %-14s" , nDigits + 1 , fEND , 1 , " END" );
1625
+ }
1626
+ }
1585
1627
1586
- char header[nwheader];
1587
- char classname[512 ];
1588
- char keyname[512 ];
1589
- char keytitle[512 ];
1590
- TString extrainfo;
1628
+ std::vector<ROOT::Detail::TKeyMapNode> TFile::WalkTKeys ()
1629
+ {
1630
+ std::vector<ROOT::Detail::TKeyMapNode> res;
1591
1631
1592
- unsigned char nDigits = std::log10 ( fEND ) + 1 ;
1632
+ constexpr int headerSize = 512 ;
1593
1633
1594
- while (idcur < fEND ) {
1634
+ std::uint64_t idcur = fBEGIN ;
1635
+ const std::uint64_t end = fEND ;
1636
+ while (idcur < end) {
1595
1637
Seek (idcur);
1596
- Int_t nread = nwheader;
1597
- if (idcur+nread >= fEND ) nread = fEND -idcur-1 ;
1638
+ auto nread = headerSize;
1639
+ if (idcur + nread >= end)
1640
+ nread = fEND - idcur - 1 ;
1641
+
1642
+ char header[headerSize];
1598
1643
if (ReadBuffer (header, nread)) {
1599
1644
// ReadBuffer returns kTRUE in case of failure.
1600
- Warning (" Map" ," %s: failed to read the key data from disk at %lld." ,
1601
- GetName (),idcur);
1645
+ res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kError });
1602
1646
break ;
1603
1647
}
1604
1648
1605
- buffer=header;
1649
+ char *buffer = header;
1650
+ Int_t nbytes;
1606
1651
frombuf (buffer, &nbytes);
1607
1652
if (!nbytes) {
1608
- Printf (" Address = %lld\t Nbytes = %d\t =====E R R O R=======" , idcur, nbytes);
1609
- date = 0 ; time = 0 ;
1653
+ res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kError });
1610
1654
break ;
1611
1655
}
1612
1656
if (nbytes < 0 ) {
1613
- Printf (" Address = %lld\t Nbytes = %d\t =====G A P===========" , idcur, nbytes);
1657
+ // free slot
1658
+ res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kGap , static_cast <std::uint32_t >(-nbytes)});
1614
1659
idcur -= nbytes;
1615
- Seek (idcur);
1616
1660
continue ;
1617
1661
}
1618
- Version_t versionkey;
1619
- frombuf (buffer, &versionkey);
1620
- frombuf (buffer, &objlen);
1621
- frombuf (buffer, &datime);
1622
- frombuf (buffer, &keylen);
1623
- frombuf (buffer, &cycle);
1624
- if (versionkey > 1000 ) {
1625
- frombuf (buffer, &seekkey);
1626
- frombuf (buffer, &seekpdir);
1627
- } else {
1628
- Int_t skey,sdir;
1629
- frombuf (buffer, &skey); seekkey = (Long64_t)skey;
1630
- frombuf (buffer, &sdir); seekpdir = (Long64_t)sdir;
1631
- }
1632
- frombuf (buffer, &nwhc);
1633
- if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1634
- nwhc = nwheader - (buffer-header);
1635
- for (int i = 0 ;i < nwhc; i++) frombuf (buffer, &classname[i]);
1636
- classname[(int )nwhc] = ' \0 ' ; // cast to avoid warning with gcc3.4
1637
- if (idcur == fSeekFree ) strlcpy (classname," FreeSegments" ,512 );
1638
- if (idcur == fSeekInfo ) strlcpy (classname," StreamerInfo" ,512 );
1639
- if (idcur == fSeekKeys ) strlcpy (classname," KeysList" ,512 );
1640
-
1641
- if (extended) {
1642
- if ( (buffer-header) >= nwheader )
1643
- nwhc = 0 ;
1644
- else {
1645
- frombuf (buffer, &nwhc);
1646
- if (nwhc < 0 )
1647
- nwhc = 0 ;
1648
- else if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1649
- nwhc = nwheader - (buffer-header);
1650
- }
1651
- for (int i = 0 ;i < nwhc; i++) frombuf (buffer, &keyname[i]);
1652
- keyname[(int )nwhc] = ' \0 ' ; // cast to avoid warning with gcc3.4
1653
-
1654
- if ( (buffer-header) >= nwheader )
1655
- nwhc = 0 ;
1656
- else {
1657
- frombuf (buffer, &nwhc);
1658
- if (nwhc < 0 )
1659
- nwhc = 0 ;
1660
- else if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1661
- nwhc = nwheader - (buffer-header);
1662
- }
1663
- for (int i = 0 ;i < nwhc; i++) frombuf (buffer, &keytitle[i]);
1664
- keytitle[(int )nwhc] = ' \0 ' ; // cast to avoid warning with gcc3.4
1665
1662
1666
- extrainfo.Form (" name: %-16s title: %s" , keyname, keytitle);
1667
- }
1663
+ auto &node = res.emplace_back (idcur, ROOT::Detail::TKeyMapNode::kKey , nbytes);
1668
1664
1669
- TDatime::GetDateTime (datime, date, time);
1670
- if (!forComp) {
1671
- if (objlen != nbytes - keylen) {
1672
- Float_t cx = Float_t (objlen + keylen) / Float_t (nbytes);
1673
- Printf (" %d/%06d At:%-*lld N=%-8d %-14s CX = %5.2f %s" , date, time, nDigits + 1 , idcur, nbytes, classname,
1674
- cx, extrainfo.Data ());
1675
- } else {
1676
- Printf (" %d/%06d At:%-*lld N=%-8d %-14s %s" , date, time, nDigits + 1 , idcur, nbytes, classname, extrainfo.Data ());
1677
- }
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 );
1678
1673
} else {
1679
- // Printing to help compare two files.
1680
- if (objlen != nbytes - keylen) {
1681
- Float_t cx = Float_t (objlen + keylen) / Float_t (nbytes);
1682
- Printf (" At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = %5.2f %s" , nDigits+1 , idcur, nbytes, keylen, objlen, classname, cx, extrainfo.Data ());
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)) {
1685
+ stringLen = 0 ;
1683
1686
} else {
1684
- Printf (" At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = 1 %s" , nDigits+1 , idcur, nbytes, keylen, objlen, classname, extrainfo.Data ());
1687
+ frombuf (buffer, &stringLen);
1688
+ if (stringLen < 0 )
1689
+ stringLen = 0 ;
1690
+ else if ((buffer - header) + stringLen > headerSize)
1691
+ stringLen = headerSize - (buffer - header);
1685
1692
}
1686
- }
1693
+ for (int i = 0 ; i < stringLen; ++i)
1694
+ frombuf (buffer, &str[i]);
1695
+ str[static_cast <int >(stringLen)] = 0 ;
1696
+
1697
+ return std::string (str, stringLen);
1698
+ };
1699
+
1700
+ node.fClassName = readString (true );
1701
+
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" ;
1708
+
1709
+ node.fKeyName = readString ();
1710
+ node.fKeyTitle = readString ();
1711
+
1687
1712
idcur += nbytes;
1688
1713
}
1689
- if (!forComp)
1690
- Printf (" %d/%06d At:%-*lld N=%-8d %-14s" ,date,time, nDigits+1 , idcur,1 ," END" );
1691
- else
1692
- Printf (" At:%-*lld N=%-8d K= O= %-14s" , nDigits+1 , idcur,1 ," END" );
1714
+
1715
+ return res;
1693
1716
}
1694
1717
1695
1718
// //////////////////////////////////////////////////////////////////////////////
0 commit comments