|
1386 | 1386 | type: 0, // keep type identifier |
1387 | 1387 | curr_entry: -1, // last processed entry |
1388 | 1388 | raw : null, // raw buffer for reading |
| 1389 | + basket : null, // current basket object |
1389 | 1390 | curr_basket: 0, // number of basket used for processing |
1390 | 1391 | read_entry: -1, // last entry which is already read |
1391 | 1392 | staged_entry: -1, // entry which is staged for reading |
|
1399 | 1400 | staged_prev: 0, // entry limit of previous I/O request |
1400 | 1401 | staged_now: 0, // entry limit of current I/O request |
1401 | 1402 | progress_showtm: 0, // last time when progress was showed |
| 1403 | + have_to_read_empty_stl_branch: false, // by default splitted container branch read version if empty container |
1402 | 1404 | GetBasketEntry : function(k) { |
1403 | 1405 | if (!this.branch || (k > this.branch.fMaxBaskets)) return 0; |
1404 | 1406 | var res = (k < this.branch.fMaxBaskets) ? this.branch.fBasketEntry[k] : 0; |
1405 | 1407 | if (res) return res; |
1406 | 1408 | var bskt = (k>0) ? this.branch.fBaskets.arr[k-1] : null; |
1407 | 1409 | return bskt ? (this.branch.fBasketEntry[k-1] + bskt.fNevBuf) : 0; |
1408 | 1410 | }, |
| 1411 | + LocateBuffer : function(entry) { |
| 1412 | + // locate buffer at proper position |
| 1413 | + var shift = entry - this.first_entry, off; |
| 1414 | + if (this.basket.fEntryOffset) { |
| 1415 | + off = this.basket.fEntryOffset[shift]; |
| 1416 | + } else { |
| 1417 | + off = this.basket.fNevBufSize * shift; |
| 1418 | + } |
| 1419 | + this.raw.locate((this.raw.entry_shift || 0) + off); |
| 1420 | + }, |
1409 | 1421 | GetTarget : function(tgtobj) { |
1410 | 1422 | if (!this.tgt) return tgtobj; |
1411 | 1423 | for (var k=0;k<this.tgt.length;++k) { |
|
1415 | 1427 | } |
1416 | 1428 | return tgtobj; |
1417 | 1429 | } |
1418 | | - |
1419 | 1430 | }; |
1420 | 1431 |
|
1421 | 1432 | // last basket can be stored directly with the branch |
|
1630 | 1641 | } else |
1631 | 1642 | if (is_brelem && (nb_leaves <= 1)) { |
1632 | 1643 |
|
| 1644 | + item.have_to_read_empty_stl_branch = (branch.fType === JSROOT.BranchType.kClonesMemberNode); |
| 1645 | + |
1633 | 1646 | elem = JSROOT.IO.FindBrachStreamerElement(branch, handle.file); |
1634 | 1647 |
|
| 1648 | + if (elem) |
| 1649 | + console.log('ELEMENT', elem.fName, elem.fType, elem.fTypeName, 'READ_EMPTY', item.have_to_read_empty_stl_branch); |
| 1650 | + |
1635 | 1651 | // this is basic type - can try to solve problem differently |
1636 | 1652 | if (!elem && branch.fStreamerType && (branch.fStreamerType < 20)) { |
1637 | 1653 | elem = JSROOT.IO.CreateStreamerElement(target_name, branch.fStreamerType); |
|
1747 | 1763 | // STL branch provides special function for the reading |
1748 | 1764 | member.func = member.objs_branch_func; |
1749 | 1765 |
|
| 1766 | + member.read_empty_stl_version = item.have_to_read_empty_stl_branch; |
| 1767 | + |
1750 | 1768 | } else { |
1751 | 1769 | member.func0 = member.func; |
1752 | 1770 |
|
|
1822 | 1840 | // function provided by normal I/O |
1823 | 1841 | member.func = member.branch_func; |
1824 | 1842 | member.stl_size = item_cnt.name; |
| 1843 | + member.read_empty_stl_version = item.have_to_read_empty_stl_branch; |
| 1844 | + |
1825 | 1845 | } else |
1826 | 1846 | if ((elem.fType === JSROOT.IO.kStreamLoop) || (elem.fType === JSROOT.IO.kOffsetL+JSROOT.IO.kStreamLoop)) { |
1827 | 1847 | if (item_cnt2) { |
1828 | 1848 | // special solution for kStreamLoop |
1829 | 1849 | member.stl_size = item_cnt.name; |
1830 | 1850 | member.cntname = item_cnt2.name; |
1831 | 1851 | member.func = member.branch_func; // this is special function, provided by base I/O |
| 1852 | + member.read_empty_stl_version = item.have_to_read_empty_stl_branch; |
1832 | 1853 | } else { |
1833 | 1854 | member.cntname = item_cnt.name; |
1834 | 1855 | } |
|
1939 | 1960 | if (!isNaN(args.firstentry) && (args.firstentry>handle.firstentry) && (args.firstentry < handle.lastentry)) |
1940 | 1961 | handle.process_min = args.firstentry; |
1941 | 1962 |
|
1942 | | - handle.staged_now = handle.process_min; |
| 1963 | + handle.current_entry = handle.staged_now = handle.process_min; |
1943 | 1964 |
|
1944 | 1965 | if (!isNaN(args.numentries) && (args.numentries>0)) { |
1945 | 1966 | var max = handle.process_min + args.numentries; |
|
2021 | 2042 | handle.selector.ShowProgress(portion); |
2022 | 2043 | } |
2023 | 2044 |
|
| 2045 | + function ReadBasketEntryOffset(branch, basket, buf) { |
| 2046 | + if (branch.fEntryOffsetLen <= 0) return; |
| 2047 | + |
| 2048 | + // ready entry offest len when necessary |
| 2049 | + |
| 2050 | + buf.locate(basket.fLast - buf.raw_shift); |
| 2051 | + |
| 2052 | + basket.fEntryOffset = buf.ReadFastArray(buf.ntoi4(), JSROOT.IO.kInt); |
| 2053 | + if (!basket.fEntryOffset) basket.fEntryOffset = [ basket.fKeylen ]; |
| 2054 | + |
| 2055 | + if (buf.remain() > 0) |
| 2056 | + basket.fDisplacement = buf.ReadFastArray(buf.ntoi4(), JSROOT.IO.kInt); |
| 2057 | + |
| 2058 | + // rollback buffer - not needed in the future |
| 2059 | + buf.locate(buf.raw_shift); |
| 2060 | + } |
| 2061 | + |
2024 | 2062 | function ProcessBlobs(blobs) { |
2025 | 2063 | if (!blobs || ((places.length>2) && (blobs.length*2 !== places.length))) |
2026 | 2064 | return JSROOT.CallBack(baskets_call_back, null); |
|
2042 | 2080 |
|
2043 | 2081 | // items[k].obj = basket; // keep basket object itself if necessary |
2044 | 2082 |
|
2045 | | - bitems[k].fNevBuf = basket.fNevBuf; // only number of entries in the basket are relevant for the moment |
| 2083 | + bitems[k].bskt_obj = basket; // only number of entries in the basket are relevant for the moment |
| 2084 | + |
| 2085 | + console.log('CHECK', basket.fKeylen, basket.fObjlen, basket.fNbytes); |
2046 | 2086 |
|
2047 | 2087 | if (basket.fKeylen + basket.fObjlen === basket.fNbytes) { |
2048 | 2088 | // use data from original blob |
2049 | | - bitems[k].raw = buf; |
| 2089 | + buf.raw_shift = 0; |
| 2090 | + buf.entry_shift = basket.fKeylen; |
| 2091 | + |
2050 | 2092 | } else { |
2051 | 2093 | // unpack data and create new blob |
2052 | 2094 | var objblob = JSROOT.R__unzip(blob, basket.fObjlen, false, buf.o); |
2053 | 2095 |
|
2054 | | - if (objblob) bitems[k].raw = JSROOT.CreateTBuffer(objblob, 0, handle.file); |
2055 | | - |
2056 | | - if (bitems[k].raw) bitems[k].raw.fTagOffset = basket.fKeylen; |
| 2096 | + if (objblob) { |
| 2097 | + buf = JSROOT.CreateTBuffer(objblob, 0, handle.file); |
| 2098 | + buf.raw_shift = basket.fKeylen; |
| 2099 | + buf.fTagOffset = basket.fKeylen; |
| 2100 | + } else { |
| 2101 | + throw new Error('FAIL TO UNPACK'); |
| 2102 | + } |
2057 | 2103 | } |
| 2104 | + |
| 2105 | + bitems[k].raw = buf; // here already unpacket buffer |
| 2106 | + |
| 2107 | + console.log('BUFFER', buf.remain()); |
| 2108 | + |
| 2109 | + ReadBasketEntryOffset(bitems[k].branch, basket, buf); |
| 2110 | + |
| 2111 | + console.log('Extract RAW ', buf.remain(), 'last', basket.fLast - basket.fKeylen, 'objlen', basket.fObjlen); |
2058 | 2112 | } |
2059 | 2113 |
|
2060 | 2114 | if (ExtractPlaces()) |
|
2093 | 2147 | var lmt = elem.GetBasketEntry(k+1), |
2094 | 2148 | not_needed = (lmt <= handle.process_min); |
2095 | 2149 |
|
2096 | | - for (var d=0;d<elem.ascounter.length;++d) { |
2097 | | - var dep = handle.arr[elem.ascounter[d]]; // dependent element |
2098 | | - if (dep.first_readentry < lmt) not_needed = false; // check that counter provide required data |
2099 | | - } |
| 2150 | + //for (var d=0;d<elem.ascounter.length;++d) { |
| 2151 | + // var dep = handle.arr[elem.ascounter[d]]; // dependent element |
| 2152 | + // if (dep.first_readentry < lmt) not_needed = false; // check that counter provide required data |
| 2153 | + //} |
2100 | 2154 |
|
2101 | 2155 | if (not_needed) continue; // if that basket not required, check next |
2102 | 2156 |
|
|
2121 | 2175 | bitem.raw.locate(0); // reset pointer - same branch may be read several times |
2122 | 2176 | else |
2123 | 2177 | bitem.raw = JSROOT.CreateTBuffer(null, 0, handle.file); // create dummy buffer - basket has no data |
2124 | | - bitem.fNevBuf = bskt.fNevBuf; |
| 2178 | + bitem.raw.raw_shift = 0; |
| 2179 | + |
| 2180 | + if (bskt.fBufferRef) |
| 2181 | + ReadBasketEntryOffset(elem.branch, bskt, bitem.raw); |
| 2182 | + |
| 2183 | + bitem.bskt_obj = bskt; |
2125 | 2184 | is_direct = true; |
2126 | 2185 | elem.baskets[k] = bitem; |
2127 | 2186 | } else { |
|
2183 | 2242 |
|
2184 | 2243 | elem = handle.arr[n]; |
2185 | 2244 |
|
2186 | | - if (!elem.raw) { |
| 2245 | + if (!elem.raw || !elem.basket || (elem.first_entry + elem.basket.fNevBuf <= handle.current_entry)) { |
| 2246 | + delete elem.raw; |
| 2247 | + delete elem.basket; |
| 2248 | + |
2187 | 2249 | if ((elem.curr_basket >= elem.numbaskets)) { |
2188 | 2250 | if (n==0) return handle.selector.Terminate(true); |
2189 | 2251 | continue; // ignore non-master branch |
|
2205 | 2267 | } |
2206 | 2268 |
|
2207 | 2269 | elem.raw = bitem.raw; |
2208 | | - elem.nev = bitem.fNevBuf; // number of entries in raw buffer |
2209 | | - elem.current_entry = elem.GetBasketEntry(bitem.basket); |
| 2270 | + elem.basket = bitem.bskt_obj; |
| 2271 | + // elem.nev = bitem.fNevBuf; // number of entries in raw buffer |
| 2272 | + elem.first_entry = elem.GetBasketEntry(bitem.basket); |
2210 | 2273 |
|
2211 | 2274 | bitem.raw = null; // remove reference on raw buffer |
2212 | 2275 | bitem.branch = null; // remove reference on the branch |
| 2276 | + bitem.bskt_obj = null; // remove reference on the branch |
2213 | 2277 | elem.baskets[elem.curr_basket++] = undefined; // remove from array |
2214 | 2278 | } |
2215 | 2279 |
|
2216 | | - min_curr = Math.min(min_curr, elem.current_entry); |
2217 | | - loopentries = Math.min(loopentries, elem.nev); // define how much entries can be processed before next raw buffer will be finished |
| 2280 | + // define how much entries can be processed before next raw buffer will be finished |
| 2281 | + loopentries = Math.min(loopentries, elem.first_entry + elem.basket.fNevBuf - handle.current_entry); |
2218 | 2282 | } |
2219 | 2283 |
|
2220 | | - // assign first entry which can be analyzed |
2221 | | - if (handle.current_entry < 0) handle.current_entry = min_curr; |
2222 | | - |
2223 | 2284 | // second loop extracts all required data |
2224 | 2285 |
|
2225 | 2286 | // do not read too much |
|
2233 | 2294 | elem = handle.arr[n]; |
2234 | 2295 | elem.arrmember.arrlength = loopentries; |
2235 | 2296 | elem.arrmember.func(elem.raw, handle.selector.tgtarr); |
2236 | | - elem.current_entry += loopentries; |
2237 | 2297 |
|
2238 | 2298 | elem.raw = null; |
2239 | 2299 | } |
|
2250 | 2310 | for (n=0;n<handle.arr.length;++n) { |
2251 | 2311 | elem = handle.arr[n]; |
2252 | 2312 |
|
2253 | | - if (handle.current_entry === elem.current_entry) { |
2254 | | - // read only element where entry id matches |
2255 | | - |
2256 | | - elem.member.func(elem.raw, elem.GetTarget(handle.selector.tgtobj)); |
| 2313 | + // locate buffer offest at proper place |
| 2314 | + elem.LocateBuffer(handle.current_entry); |
2257 | 2315 |
|
2258 | | - elem.current_entry++; |
2259 | | - |
2260 | | - if (--elem.nev <= 0) elem.raw = null; |
2261 | | - } |
| 2316 | + // read only element where entry id matches |
| 2317 | + elem.member.func(elem.raw, elem.GetTarget(handle.selector.tgtobj)); |
2262 | 2318 | } |
2263 | 2319 |
|
2264 | | - if (handle.current_entry >= handle.process_min) |
2265 | | - handle.selector.Process(handle.current_entry); |
| 2320 | + handle.selector.Process(handle.current_entry); |
2266 | 2321 |
|
2267 | 2322 | handle.current_entry++; |
2268 | 2323 |
|
|
0 commit comments