Base class for a reader that wrap multiple readers, e.g., reading from multiple sources simultaneously.
| 517 | |
| 518 | |
| 519 | class CompositeReader(Reader): |
| 520 | """ |
| 521 | Base class for a reader that wrap multiple readers, e.g., reading from |
| 522 | multiple sources simultaneously. |
| 523 | """ |
| 524 | def __init__(self, names, readers): |
| 525 | """ |
| 526 | Args: |
| 527 | names: list[str] names of readers; used as schema keys |
| 528 | readers: list[Reader] Reader instances, must have schema |
| 529 | """ |
| 530 | assert len(names) == len(readers) |
| 531 | super().__init__(schema=Struct(*[ |
| 532 | (name, reader.schema()) for name, reader in zip(names, readers) |
| 533 | ])) |
| 534 | self._names = names |
| 535 | self._readers = readers |
| 536 | |
| 537 | def setup_ex(self, init_net, finish_net): |
| 538 | for reader in self._readers: |
| 539 | reader.setup_ex(init_net, finish_net) |
| 540 | |
| 541 | def read_ex(self, local_init_net, local_finish_net): |
| 542 | """ |
| 543 | Stops when one of the reader finished |
| 544 | """ |
| 545 | # First, instantiate all the reader nets |
| 546 | fields = [] |
| 547 | stop_blobs = [] |
| 548 | all_sub_read_nets = [] |
| 549 | for name, reader in zip(self._names, self._readers): |
| 550 | sub_read_nets, should_stop, record = reader.read_record_ex( |
| 551 | local_init_net, local_finish_net) |
| 552 | stop_blobs.append(should_stop) |
| 553 | all_sub_read_nets.append(sub_read_nets) |
| 554 | fields.extend(record.field_blobs()) |
| 555 | |
| 556 | read_nets = [] |
| 557 | # Use the stop blob of the last reader as stop blob of composite reader. |
| 558 | local_should_stop = stop_blobs[-1] |
| 559 | for name, sub_read_nets, stop_blob in zip(self._names, all_sub_read_nets, stop_blobs): |
| 560 | read_nets.extend(sub_read_nets) |
| 561 | if stop_blob == local_should_stop: |
| 562 | # Skip adding stop net because Or([A, A], A) doesn't pass operator |
| 563 | # schema check |
| 564 | continue |
| 565 | stop_net = core.Net("{}_stop".format(name)) |
| 566 | stop_net.Or([local_should_stop, stop_blob], local_should_stop) |
| 567 | read_nets.append(stop_net) |
| 568 | |
| 569 | return read_nets, local_should_stop, fields |
| 570 | |
| 571 | def reset(self, net): |
| 572 | for reader in self._readers: |
| 573 | reader.reset(net) |
| 574 | |
| 575 | |
| 576 | class CompositeReaderBuilder(ReaderBuilder): |
no outgoing calls
searching dependent graphs…