Skip to content

Commit 52eadad

Browse files
committed
Build with double vector support
1 parent 569f575 commit 52eadad

File tree

1 file changed

+111
-28
lines changed

1 file changed

+111
-28
lines changed

build/jsroot.js

Lines changed: 111 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -126542,7 +126542,7 @@ class TDrawSelector extends TSelector {
126542126542
this.leaf = args.leaf;
126543126543

126544126544
// branch object remains, therefore we need to copy fields to see them all
126545-
this.copy_fields = ((args.branch.fLeaves?.arr.length > 1) || args.branch.fBranches?.arr.length) && !args.leaf;
126545+
this.copy_fields = args.copy_fields ?? (((args.branch.fLeaves?.arr.length > 1) || args.branch.fBranches?.arr.length) && !args.leaf);
126546126546

126547126547
this.addBranch(branch, 'br0', args.direct_branch); // add branch
126548126548

@@ -178256,9 +178256,20 @@ class RNTupleDescriptorBuilder {
178256178256
}
178257178257
}
178258178258

178259+
/** @summary Return all childs of specified field */
178260+
findChildFields(field) {
178261+
const indx = this.fieldDescriptors.indexOf(field), res = [];
178262+
for (let n = 0; n < this.fieldDescriptors.length; ++n) {
178263+
const fld = this.fieldDescriptors[n];
178264+
if ((fld !== field) && (fld.parentFieldId === indx))
178265+
res.push(fld);
178266+
}
178267+
return res;
178268+
}
178269+
178259178270
/** @summary Return array of columns for specified field */
178260-
findColumns(name) {
178261-
const res = [], field = this.findField(name);
178271+
findColumns(field) {
178272+
const res = [];
178262178273
if (!field)
178263178274
return res;
178264178275
for (const colDesc of this.columnDescriptors) {
@@ -178268,6 +178279,7 @@ class RNTupleDescriptorBuilder {
178268178279
return res;
178269178280
}
178270178281

178282+
178271178283
} // class RNTupleDescriptorBuilder
178272178284

178273178285

@@ -178359,11 +178371,13 @@ class ReaderItem {
178359178371
this.page = -1; // current page for the reading
178360178372
this.name = name;
178361178373
this.sz = 0;
178374+
this.simple = true;
178362178375

178363178376
// special handling of split types
178364178377
if ((this.coltype >= ENTupleColumnType.kSplitInt16) && (this.coltype <= ENTupleColumnType.kSplitIndex64)) {
178365178378
this.splittype = this.coltype;
178366178379
this.coltype -= (ENTupleColumnType.kSplitInt16 - ENTupleColumnType.kInt16);
178380+
this.simple = false;
178367178381
}
178368178382
}
178369178383

@@ -178403,8 +178417,13 @@ class ReaderItem {
178403178417
}
178404178418
}
178405178419

178406-
/** @summary Simple column which fixed element size */
178407-
is_simple() { return this.sz > 0; }
178420+
/** @summary Simple column with fixed element size - no vectors, no strings */
178421+
is_simple() { return this.sz > 0 && this.simple; }
178422+
178423+
set_simple(flag) {
178424+
this.simple = flag;
178425+
this.item1?.set_simple(flag);
178426+
}
178408178427

178409178428
assignReadFunc() {
178410178429
switch (this.coltype) {
@@ -178508,13 +178527,17 @@ class ReaderItem {
178508178527
}
178509178528

178510178529
/** @summary identify if this item used as offset for std::string or similar */
178511-
is_offset_item() { return this.item1; }
178530+
is_offset_item() { return (this.func0 && this.shift0) || (this.shiftn && this.funcn); }
178512178531

178532+
/** @summary implements reading of std::string where item1 provides offsets */
178513178533
assignStringReader(item1) {
178514178534
this.item1 = item1;
178515178535
this.off0 = 0;
178516178536
this.$tgt = {};
178517178537

178538+
this.simple = false;
178539+
// for plain string one can read offsets
178540+
178518178541
item1.func0 = item1.func;
178519178542
item1.shift0 = item1.shift;
178520178543

@@ -178535,14 +178558,55 @@ class ReaderItem {
178535178558

178536178559
this.shift = function(entries) {
178537178560
if (entries > 0) {
178538-
this.item1.shift0(entries);
178561+
this.item1.shift0(entries - 1);
178539178562
this.item1.func0(this.$tgt);
178540178563
this.off0 = Number(this.$tgt[this.name]);
178541178564
this.shift_o(this.off0);
178542178565
}
178543178566
};
178544178567
}
178545178568

178569+
/** @summary implement reading of std::vector where itemv provides element reading */
178570+
assignVectorReader(itemv) {
178571+
this.itemv = itemv;
178572+
this.offv0 = 0;
178573+
178574+
itemv.funcv = itemv.func;
178575+
itemv.shiftv = itemv.shift;
178576+
// assign noop
178577+
itemv.func = itemv.shift = () => {};
178578+
178579+
// item itself can remain simple
178580+
itemv.set_simple(false);
178581+
178582+
// remember own read function - they need to be used
178583+
this.funcn = this.func;
178584+
this.shiftn = this.shift;
178585+
178586+
this.func = function(tgtobj) {
178587+
const arr = [], tmp = {};
178588+
this.funcn(tmp);
178589+
const offv = Number(tmp[this.name]);
178590+
let len = offv - this.offv0;
178591+
while (len-- > 0) {
178592+
this.itemv.funcv(tmp);
178593+
arr.push(tmp[this.name]);
178594+
}
178595+
tgtobj[this.name] = arr;
178596+
this.offv0 = offv;
178597+
};
178598+
178599+
this.shift = function(entries) {
178600+
if (entries > 0) {
178601+
const tmp = {};
178602+
this.shiftn(entries - 1);
178603+
this.funcn(tmp);
178604+
this.offv0 = Number(tmp[this.name]);
178605+
this.itemv.shiftv(this.offv0);
178606+
}
178607+
};
178608+
}
178609+
178546178610
collectPages(cluster_locations, dataToRead, itemsToRead, pagesToRead, emin, emax, elist) {
178547178611
const pages = cluster_locations[this.id].pages;
178548178612

@@ -178552,13 +178616,13 @@ class ReaderItem {
178552178616
for (let p = 0; p < pages.length; ++p) {
178553178617
const page = pages[p],
178554178618
e1 = e0 + Number(page.numElements),
178555-
margin = this.is_offset_item() ? 1 : 0; // offset for previous entry has to be read as well
178556-
178619+
margin = this.is_offset_item() ? 1 : 0, // offset for previous entry has to be read as well
178620+
is_inside = (e, beg, end) => (e >= beg) && (e < end + margin);
178557178621
let is_entries_inside = false;
178558178622
if (elist?.length)
178559-
elist.forEach(e => { is_entries_inside ||= (e >= e0) && (e - margin < e1); });
178623+
elist.forEach(e => { is_entries_inside ||= is_inside(e, e0, e1); });
178560178624
else
178561-
is_entries_inside = ((e0 >= emin - margin) && (e0 < emax)) || ((e1 > emin - margin) && (e1 <= emax));
178625+
is_entries_inside = is_inside(e0, emin, emax) || is_inside(e1, emin, emax) || is_inside(emin, e0, e1) || is_inside(emax, e0, e1);
178562178626

178563178627
if (!this.is_simple() || is_entries_inside) {
178564178628
itemsToRead.push(this);
@@ -178707,29 +178771,46 @@ async function rntupleProcess(rntuple, selector, args = {}) {
178707178771
});
178708178772
}
178709178773

178774+
function addFieldReading(field, tgtname) {
178775+
const columns = rntuple.builder.findColumns(field);
178776+
if (!columns?.length)
178777+
throw new Error(`No columns found for field '${field.fieldName}' in RNTuple`);
178778+
178779+
let item = new ReaderItem(columns[0], tgtname);
178780+
item.assignReadFunc();
178781+
handle.arr.push(item);
178782+
178783+
if ((columns.length === 2) && (field.typeName === 'std::string')) {
178784+
const items = new ReaderItem(columns[1], tgtname);
178785+
items.assignStringReader(item);
178786+
handle.arr.push(items);
178787+
item = items; // second item performs complete reading of the string
178788+
}
178789+
178790+
const childs = rntuple.builder.findChildFields(field);
178791+
if ((childs.length === 1) && (field.typeName.indexOf('std::vector') === 0)) {
178792+
const itemv = addFieldReading(childs[0], tgtname);
178793+
item.assignVectorReader(itemv);
178794+
}
178795+
178796+
return item;
178797+
}
178798+
178710178799
return readHeaderFooter(rntuple).then(res => {
178711178800
if (!res)
178712178801
throw new Error('Not able to read header for the RNtuple');
178713178802

178714178803
for (let i = 0; i < selector.numBranches(); ++i) {
178715-
const name = getSelectorFieldName(selector, i);
178804+
const name = getSelectorFieldName(selector, i),
178805+
tgtname = selector.nameOfBranch(i);
178716178806
if (!name)
178717178807
throw new Error(`Not able to extract name for field ${i}`);
178718178808

178719-
const columns = rntuple.builder.findColumns(name);
178720-
if (!columns?.length)
178721-
throw new Error(`No columns found for field '${name}' in RNTuple`);
178722-
178723-
const tgtname = selector.nameOfBranch(i),
178724-
item = new ReaderItem(columns[0], tgtname);
178725-
item.assignReadFunc();
178726-
handle.arr.push(item);
178809+
const field = rntuple.builder.findField(name);
178810+
if (!field)
178811+
throw new Error(`Field ${name} not found`);
178727178812

178728-
if (columns.length === 2) {
178729-
const item2 = new ReaderItem(columns[1], tgtname);
178730-
item2.assignStringReader(item);
178731-
handle.arr.push(item2);
178732-
}
178813+
addFieldReading(field, tgtname);
178733178814
}
178734178815

178735178816
// calculate number of entries
@@ -178877,13 +178958,15 @@ async function drawRNTuple(dom, obj, opt) {
178877178958
const args = {};
178878178959
let tuple;
178879178960

178880-
if (obj?.$tuple) {
178961+
if (obj?.$tuple && obj.$field) {
178881178962
// case of fictional ROOT::RNTupleField
178882178963
tuple = obj.$tuple;
178883178964
args.expr = obj._name;
178884-
if (isStr(opt) && opt.indexOf('dump') === 0)
178965+
if (isStr(opt) && opt.indexOf('dump') === 0) {
178885178966
args.expr += '>>' + opt;
178886-
else if (opt)
178967+
args.branch = obj.$field;
178968+
args.copy_fields = false; // no need to copy fields, reading is simple
178969+
} else if (opt)
178887178970
args.expr += opt;
178888178971
} else {
178889178972
tuple = obj;

0 commit comments

Comments
 (0)