SheafSystem  0.0.0.0
dof_tuple_record_set.cc
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Implementation for class dof_tuple_record_set
19 
20 #include "SheafSystem/dof_tuple_record_set.h"
21 
22 #include "SheafSystem/assert_contract.h"
23 #include "SheafSystem/data_converter.h"
24 #include "SheafSystem/error_message.h"
25 #include "SheafSystem/poset_bounds.h"
26 #include "SheafSystem/poset_dof_iterator.h"
27 #include "SheafSystem/poset_scaffold.h"
28 #include "SheafSystem/preorder_member_iterator.h"
29 #include "SheafSystem/primitive_value.h"
30 #include "SheafSystem/sheaf_file.h"
31 #include "SheafSystem/std_iostream.h"
32 #include "SheafSystem/std_sstream.h"
33 #include "SheafSystem/std_string.h"
34 
35 using namespace std;
36 
37 //#define DIAGNOSTIC_OUTPUT
38 //#undef DIAGNOSTIC_OUTPUT
39 
40 namespace
41 {
42  //
43  // The rank of the dataspace for the data set.
44  //
45  const int DATASPACE_RANK = 1;
46 }
47 
48 
49 // PUBLIC MEMBER FUNCTIONS
50 
51 // CANONICAL MEMBERS
52 
53 
54 // Copy constructor
58  : record_set(xother),
59  _record_is_full(xother._record_is_full)
60 {
61 
62  // Preconditions:
63 
64 
65  // Body:
66 
67  not_implemented();
68 
69  // Postconditions:
70 
71  ensure(invariant());
72 }
73 
74 
75 
76 // Virtual constructor
80 clone() const
81 {
82  dof_tuple_record_set* result = 0;
83 
84  // Preconditions:
85 
86  // Body:
87 
88  not_implemented();
89 
90  // Postconditions:
91 
92  ensure(result != 0);
93  ensure(is_same_type(result));
94 
95  // Exit:
96 
97  return result;
98 }
99 
100 
101 // Destructor
105 {
106 
107  // Preconditions:
108 
109  // Body:
110 
111  delete [] _ext_dataspace_dims;
112 
113  if(_hdf_int_selection != 0)
114  {
115  delete [] _hdf_int_selection;
116  }
117 
118  if(_hdf_ext_selection != 0)
119  {
120  delete [] _hdf_ext_selection;
121  }
122 
123  delete [] _hdf_scratch_buf;
124 
125  if(_hdf_buf != 0)
126  {
127  delete [] static_cast<char*>(_hdf_buf);
128  }
129 
130 
131  // Postconditions:
132 
133  // Exit:
134 
135  return;
136 }
137 
138 
140 bool
142 invariant() const
143 {
144  bool result = true;
145 
146  // Preconditions:
147 
148  // Body:
149 
150  // Must satisfy base class invariant
151 
152  result = result && record_set::invariant();
153 
154  if(invariant_check())
155  {
156  // Prevent recursive calls to invariant
157 
159 
160  // Scratch buffer must be parge enough to hold any fixed length dof.
161 
162  invariance(_hdf_scratch_buf_ub >= type_map().max_size());
163 
164  // Finished, turn invariant checking back on.
165 
167  }
168 
169  // Postconditions:
170 
171  // Exit
172 
173  return result;
174 }
175 
177 bool
179 is_ancestor_of(const any* other) const
180 {
181 
182  // Preconditions:
183 
184  require(other != 0);
185 
186  // Body:
187 
188  // True if other conforms to this
189 
190  bool result = dynamic_cast<const dof_tuple_record_set*>(other) != 0;
191 
192  // Postconditions:
193 
194  return result;
195 
196 }
197 
198 
199 
200 // DOF_TUPLE_RECORD_SET INTERFACE
201 
202 
203 
204 // NEW HANDLE, NEW STATE CONSTRUCTORS
205 
206 
210  size_t xrecord_size,
211  int xrecord_buffer_ub,
212  const poset_scaffold& xscaffold)
213  : record_set(xfile, xrecord_buffer_ub, xscaffold),
214  _record_is_full(xrecord_buffer_ub) // Initialized to false by default
215 {
216 
217  // Preconditions:
218 
219  require(xfile.is_open());
220  require(xrecord_buffer_ub > 0);
221 
222  // Body:
223 
224  _ext_dataspace_rank = DATASPACE_RANK;
225  _ext_dataspace_dims = new hsize_t[DATASPACE_RANK];
226 
227  // _name has been initialized to poset name in record_set;
228  // add members dataset suffix to it.
229 
230  _name = data_set_name(scaffold().structure().name());
231  _alias = data_set_alias(scaffold().structure().name());
232 
233  // Create the HDF selection buffers
234 
236  _hdf_int_selection = _hdf_selection_ub > 0 ? new hsize_t[_hdf_selection_ub][DATASPACE_RANK] : 0;
237  _hdf_ext_selection = _hdf_selection_ub > 0 ? new hsize_t[_hdf_selection_ub][DATASPACE_RANK] : 0;
238  _hdf_selection_ct = 0;
239 
240  // Initialize the HDF data buffer to null.
241  // Will be allocated after opening the data set.
242  // May reset _record_size; see open().
243 
244  _record_size = xrecord_size;
245  // _record_dof_ct = 0;
246  _hdf_buf_ub = 0;
247  _hdf_buf = 0;
248 
249  // Create the scratch buffer.
250 
253 
254  // Create the internal dataspace to describe the HDF record buffer.
255 
256  hsize_t linit_dims[DATASPACE_RANK];
257  linit_dims[0] = _record_buffer_ub;
258 
259  _int_dataspace_hdf_id = H5Screate_simple(DATASPACE_RANK, linit_dims, NULL);
260  if(_int_dataspace_hdf_id < 0)
261  {
262  post_fatal_error_message("can't create interior data space");
263  }
264 
265  // Postconditions:
266 
267  ensure(invariant());
268  ensure(name() == data_set_name(scaffold().structure().name()));
269  ensure(alias() == data_set_alias(scaffold().structure().name()));
270  ensure(!is_open());
271  ensure(record_buffer_ub() == xrecord_buffer_ub);
272  ensure(record_buffer_ct() == 0);
273 }
274 
275 
276 const std::string&
278 suffix() const
279 {
280  // cout << endl << "Entering dof_tuple_record_set::suffix." << endl;
281 
282  // Preconditions:
283 
284 
285  // Body:
286 
287  static const string result(".dof_tuples");
288 
289  // Postconditions:
290 
291 
292  // Exit:
293 
294  // cout << "Leaving dof_tuple_record_set::suffix." << endl;
295  return result;
296 }
297 
298 
300 void
303 {
304  // Preconditions:
305 
306  require(file().is_open());
307 
308  // Body:
309 
310  // Open the record set.
311 
313 
314  // The HDF dataset is a rank 1 array of data elements.
315  // A record is one data element, so the record size must be
316  // the same as the size of the HDF data type.
317  // If this is a new file, the data type size has been set
318  // from _record_size in create_dataset and the following will not change
319  // the value of _record_size. If this is an existing file, the following
320  // will reset _record_size to the value from the file.
321 
322  _record_size = H5Tget_size(_int_data_type_hdf_id);
323  if(_record_size == 0)
324  {
325  post_fatal_error_message("Unable to get record size.");
326  }
327 
328  // Create the HDF data buffer.
329 
331  _hdf_buf = _hdf_buf_ub > 0 ? new char[_hdf_buf_ub] : 0;
332 
333  // Postconditions:
334 
335  ensure(invariant());
336  ensure(is_open());
337 
338  // Exit
339 
340  return;
341 }
342 
344 void
347 {
348 
349  // Preconditions:
350 
351  require(is_open());
352  require(scaffold().structure().state_is_read_write_accessible());
353 
354  // Body:
355 
356 #ifdef DIAGNOSTIC_OUTPUT
357  cout << "internalizing record set " << name() << endl;
358 #endif
359 
360  // This is a read operation.
361 
362  _writing = false;
363 
364  // Translate the column bounds for the external dof tuple
365  // from external ids to internal ids. Can not be done when read
366  // because subposet maps are not populated until members are read.
367 
369 
370  // Read all the dof tuples in the queue.
371 
372  read_records();
373 
374  // Now that all the dof tuples have been created,
375  // we can schematize the table and row dof subposet.
376 
377  schematize();
378 
379  // Postconditions:
380 
381  ensure(is_open());
382 
383  // Exit
384 
385  return;
386 }
387 
388 
390 void
393 {
394 
395  // Preconditions:
396 
397  require(is_open());
398  require(scaffold().structure().state_is_read_write_accessible());
399 
400  // See below for a discussion of the following precondition:
401 
402  require(unexecutable("all tuple schema are comparable to column bounds decomposition"));
403 
404  // Body:
405 
406  // Get a handle to the schema poset.
407 
408  poset_state_handle* lschema_poset = scaffold().structure().schema().host();
409 
410  _hdf_selection_ct = 0;
412 
413  _next_record_pod = 0;
414 
415  while(!_record_queue.is_empty())
416  {
417  // Get the next member off the queue
418 
419  pod_index_type ldof_tuple_ext_pod = _record_queue.dequeue();
420 
421  // Gather the dofs for this dof tuple from the file into the buffer.
422  // Because the dof tuple may contains variable length dofs,
423  // we must traverse the dofs in the order they were written,
424  // it's the only way we can tell which dof is which. This means
425  // we must traverse the dofs using the decomposition and schema
426  // they were written with. This means we have to iterate over the
427  // external column bounds and within each domain we must iterate
428  // over the dofs in the external schema and version.
429 
430  // On the other hand, the dof map has already been allocated
431  // in member_record::new_row_dof_tuple and we only want to
432  // transfer from the external dof tuple to the internal dof tuple
433  // the dofs indicated by the schema of the internal dof tuple.
434  // We can do this by transferring the enitre external dof tuple
435  // into a temporary dof map, then iterating over the internal
436  // dof map, transferring the dofs we need.
437 
438  const scoped_index& ltuple_id = scaffold().dof_tuple_ext_id(ldof_tuple_ext_pod);
439  poset_dof_map& lint_dof_map = scaffold().structure().row_dof_map(ltuple_id);
440 
441  pod_index_type lext_dof_tuple_schema_int_id =
442  scaffold().dof_tuple_schema_int_id(ldof_tuple_ext_pod);
443 
444  // Get the external dof tuple schema version
445 
446  int lext_dof_tuple_schema_ver =
447  scaffold().dof_tuple_schema_version(ldof_tuple_ext_pod);
448 
449  // Create and initialize the temporary dof map for the external dof tuple.
450  // Ensure its the right type by cloning the internal dof map.
451 
452  poset_dof_map& lext_dof_map = *lint_dof_map.clone();
453  lext_dof_map.init_row_dof_map(lint_dof_map.host(),
454  lext_dof_tuple_schema_int_id,
455  lext_dof_tuple_schema_ver);
456 
457  schema_poset_member& lext_dof_map_schema = lext_dof_map.schema();
458 
459  // Get the external column bounds.
460 
461  poset_bounds* lext_col_bounds =
462  new poset_bounds(scaffold().dof_tuple_col_bound(ldof_tuple_ext_pod));
463 
464  // Get an iterator for the column decomposition.
465 
470 
471  index_iterator* lcol_itr =
472  lext_dof_map_schema.bound_iterator(*lext_col_bounds, true);
473 
474  // Iterate over the members ("domains") of the col decomposition.
475 
476  while(!lcol_itr->is_done())
477  {
478  // We need to read the dofs in each domain in exactly the same order
479  // we wrote them, so we need a schema handle attached to the actual
480  // schema used to write each domain. The actual schema was the lesser
481  // of the dof tuple schema and the domain schema.
482 
483  attach_transfer_schema(lext_dof_map_schema, lcol_itr->index());
484 
485  schema_poset_member& lxfr_schema = scaffold().transfer_schema();
486 
487  // Get the offset for the current domain.
488  //
489  // Since the dof tuples in general have variable length dofs, we can not
490  // compute the offset from the schema, we have to store it in a map.
491  // The map must be keyed by unique, persistent ids for the dof tuple and
492  // domain schema member; which means their external ids. But we don't
493  // currently directly support external ids for product posets (i.e.
494  // section_space_schema_posets).
495 
498 
499  pod_index_type ldomain_key =
500  lxfr_schema.get_ext_id(scaffold().file_id_space_name());
501 
502  // Now lookup the offset in the domain offset map.
503 
504  pod_index_type ldom_ext_pod =
505  scaffold().dof_tuple_domain_offset(ldof_tuple_ext_pod, ldomain_key);
506 
507  // Get a pointer to the corresponding location in the record buffer.
508 
509  char* lbuf = get_first_record(ldom_ext_pod);
510 
511  size_t lbuf_remainder = _record_size - (ldom_ext_pod % _record_size);
512 
513  // Internalize all the dofs in the domain.
514 
515  internalize_all_dofs(lxfr_schema, lext_dof_map, lbuf, lbuf_remainder);
516 
517  lcol_itr->next();
518 
519  } // while(!lcol_itr->is_done())
520 
521  delete lcol_itr;
522  delete lext_col_bounds;
523 
524  // Now we're finished reading the external dofs.
525  // Populate the internal dof map from the external dof map.
526 
527  populate_internal_dof_map(lext_dof_map, lint_dof_map);
528 
529 
530  // We're finished with the external dof map; delete it.
531 
532  delete &lext_dof_map;
533 
534  } // while(!_record_queue.is_empty())
535 
536 
537  // Postconditions:
538 
539  ensure(is_open());
540 
541  // Exit
542 
543  return;
544 }
545 
547 void
550 {
551  // Preconditions:
552 
553  require(is_open());
554  require(scaffold().structure().state_is_read_accessible());
555 
556  // Body:
557 
558 #ifdef DIAGNOSTIC_OUTPUT
559  cout << "externalizing record set " << name() << endl;
560 #endif
561 
562  // This is a write operation
563 
564  _writing = true;
565 
566  // Initialize the record buffer.
567 
568  _hdf_selection_ct = 0;
570 
571  _next_record_pod = 0;
572 
573  pod_index_type lext_pod;
574 
575  // Externalize and write the record set.
576 
577  while(!_record_queue.is_empty())
578  {
579  // Get the next dof_tuple off the queue
580 
581  lext_pod = _record_queue.dequeue();
582 
583  const scoped_index& ltuple_id = scaffold().dof_tuple_ext_id(lext_pod);
584 
585  // Iterate over the column ("domain") decomposition.
586 
592 
593  poset_bounds& lcol_bnd = scaffold().col_bounds();
594  index_iterator* lcol_itr =
595  scaffold().external_schema().bound_iterator(lcol_bnd, true);
596 
597  while(!lcol_itr->is_done())
598  {
599  externalize_one_domain(ltuple_id, lcol_itr->index());
600 
601  lcol_itr->next();
602  }
603  delete lcol_itr;
604 
605  // Store the schema version in the scaffold;
606  // map should not already have an entry for lext_pod.
607 
608  assertion(scaffold().dof_tuple_schema_versions().find(lext_pod) ==
609  scaffold().dof_tuple_schema_versions().end());
610 
611  poset_dof_map& ldof_map = scaffold().structure().row_dof_map(ltuple_id);
612 
613  pair<pod_index_type, int> lmap_pair(lext_pod, ldof_map.schema().version());
614  scaffold().dof_tuple_schema_versions().insert(lmap_pair);
615 
616  // Store the schema and columns bounds in the scaffold:
617 
618  // What we really want when we read the dof tuples is:
619  // 1) The actual schema used to write each domain =
620  // {min(col bound, internal tuple schema) for each domain}
621  // Used to read the domains in the same order as written.
622  // This set is not necessarily describable using the current
623  // machinery so we have to write the requested column bounds instead.
624  // We can then recover the actual schema from the col blunds and the
625  // tuple schema
626  // 2) The actual dof tuple schema, which is the join of the actual domain schema.
627  // Used to instantiate a temporary external dof tuple into which
628  // we can read the dofs in the same order they were written.
629  // If the domain decomposition contains a single member, then the
630  // actual tuple schema = min(internal tuple schema, col bound).
631  // If not, we assume the column bounds form a decomposition, i.e.
632  // the join of the bounds is the schema of the host and hence
633  // the join of the actual domain schema must be the internal schema.
634 
635  // Compute the actual external tuple schema id and store it in the scaffold:
636 
637  // Compute the schema id.
638 
639  schema_poset_member& lint_tuple_schema = ldof_map.schema();
640  scoped_index lactual_tuple_schema_int_id = lint_tuple_schema.index();
641  if(lcol_bnd.ub_is_singleton())
642  {
643  // Actual tuple schema is min of internal and col bound.
644 
645  if(lint_tuple_schema.ge(lcol_bnd.ub_id()))
646  {
647  lactual_tuple_schema_int_id = lcol_bnd.ub_id();
648  }
649  else
650  {
651  lactual_tuple_schema_int_id = lint_tuple_schema.index();
652  }
653  }
654  else
655  {
656  // Actual tuple schema is internal schema.
657 
658  lactual_tuple_schema_int_id = lint_tuple_schema.index();
659  }
660 
664 
665  pod_index_type lactual_tuple_schema_ext_pod =
666  lint_tuple_schema.host()->get_ext_id(lactual_tuple_schema_int_id,
667  scaffold().file_id_space_name(),
668  false);
669 
670  // Map should not already have an entry for lext_pod.
671 
672  assertion(scaffold().dof_tuple_schema_ids().find(lext_pod) ==
673  scaffold().dof_tuple_schema_ids().end());
674 
675  // Insert the actual tuple schema id in the map.
676 
677  pair<pod_index_type, pod_index_type>
678  lid_pair(lext_pod, lactual_tuple_schema_ext_pod);
679  scaffold().dof_tuple_schema_ids().insert(lid_pair);
680 
681  // Store the column bounds in the bounds map, if it is not already there.
682 
683  scaffold().put_dof_tuple_col_bound(lext_pod);
684 
685  } // end while(!_record_queue.is_empty())
686 
687  // Flush the cache.
688 
689  _hdf_selection_ct = 0;
690  for(int i=0; i<_record_buffer_ub; i++)
691  {
692  if(_record_is_full[i])
693  {
697  _record_is_full.put(i, false);
698  }
699  }
700 
701  if(_hdf_selection_ct > 0)
702  {
703  write_selection();
704  _hdf_selection_ct = 0;
705 
706  _next_record_pod = 0;
707  }
708 
709  // Adjust the next external id.
710  // If this was a partial write and is to be followed by another write,
711  // the next write must begin on a new record, otherwise it will overwrite
712  // the part of the external record that has already been written with
713  // what ever junk is in the first part of the internal record. Advance
714  // the next external id to the nearest start of record. Doesn't change
715  // anything if already at start of record..
716 
717  lext_pod = scaffold().dof_tuple_scratch_id();
718  lext_pod = advance_to_start_of_record(lext_pod);
720 
721  // Postconditions:
722 
723  ensure(is_open());
724  ensure(_hdf_selection_ct == 0);
725  ensure(_next_record_pod == 0);
726  ensure((scaffold().dof_tuple_scratch_id() % record_size()) == 0);
727 
728  // Exit
729 
730  return;
731 }
732 
733 void
736  const scoped_index& xschema_id)
737 {
738  // Preconditions:
739 
740  require(is_open());
741  require(scaffold().structure().state_is_read_accessible());
742  require(xtuple_id.same_scope(scaffold().dof_tuple_id_space()));
743 
744  // Body:
745 
746  // This is a write operation
747 
748  _writing = true;
749 
750  // Initialize the record buffer.
751 
752  _hdf_selection_ct = 0;
754 
755  _next_record_pod = 0;
756 
757  // Externalize the domain.
758 
759  externalize_one_domain(xtuple_id, xschema_id);
760 
761  // Store the schema version in the scaffold; if its not already there.
762 
763  if(scaffold().dof_tuple_schema_versions().find(xtuple_id.pod()) ==
765  {
766  poset_dof_map& ldof_map = scaffold().structure().row_dof_map(xtuple_id);
767 
768  pair<pod_index_type, int> lmap_pair(xtuple_id.pod(),
769  ldof_map.schema().version());
770  scaffold().dof_tuple_schema_versions().insert(lmap_pair);
771  }
772 
773  // Store the schema id in the scaffold, if it's not already there.
774 
775  if(scaffold().dof_tuple_schema_ids().find(xtuple_id.pod()) ==
776  scaffold().dof_tuple_schema_ids().end())
777  {
778  poset_dof_map& ldof_map = scaffold().structure().row_dof_map(xtuple_id);
779 
783 
784  pod_index_type lschema_ext_pod =
785  ldof_map.schema().get_ext_id(scaffold().file_id_space_name());
786 
787  pair<pod_index_type, pod_index_type>
788  lid_pair(xtuple_id.pod(), lschema_ext_pod);
789  scaffold().dof_tuple_schema_ids().insert(lid_pair);
790  }
791 
792  // Store the column bounds in the bounds map, if it is not already there.
793 
794  scaffold().put_dof_tuple_col_bound(xtuple_id.pod());
795 
796  // Flush the cache.
797 
798  _hdf_selection_ct = 0;
799  for(int i=0; i<_record_buffer_ub; i++)
800  {
801  if(_record_is_full[i])
802  {
806  _record_is_full.put(i, false);
807  }
808  }
809 
810  if(_hdf_selection_ct > 0)
811  {
812  write_selection();
813  _hdf_selection_ct = 0;
814 
815  _next_record_pod = 0;
816  }
817 
818  // Adjust the next external id.
819  // If this was a partial write and is to be followed by another write,
820  // the next write must begin on a new record, otherwise it will overwrite
821  // the part of the external record that has already been written with
822  // what ever junk is in the first part of the internal record. Advance
823  // the next external id to the nearest start of record. Doesn't change
824  // anything if already at start of record..
825 
826  pod_index_type lext_pod;
827  lext_pod = scaffold().dof_tuple_scratch_id();
828  lext_pod = advance_to_start_of_record(lext_pod);
830 
831  // Postconditions:
832 
833  ensure(is_open());
834  ensure(_hdf_selection_ct == 0);
835  ensure(_next_record_pod == 0);
836  ensure((scaffold().dof_tuple_scratch_id() % record_size()) == 0);
837 
838  // Postconditions:
839 
840  // Exit
841 
842  return;
843 }
844 
848 record_size() const
849 {
850  size_type result;
851 
852  // Preconditions:
853 
854  // Body:
855 
856  result = _record_size;
857 
858  // Postconditions:
859 
860  // Exit
861 
862  return result;
863 }
864 
869 {
870  // Preconditions:
871 
872  // Body:
873 
874  record_queue& result = _record_queue;
875 
876  // Postconditions:
877 
878  // Exit
879 
880  return result;
881 }
882 
883 
884 
886 const sheaf::record_queue&
888 queue() const
889 {
890  // Preconditions:
891 
892  // Body:
893 
894  const record_queue& result = _record_queue;
895 
896  // Postconditions:
897 
898  // Exit
899 
900  return result;
901 }
902 
905 compute_ext_id(const scoped_index& xtuple_id)
906 {
907  // Preconditions:
908 
909  require(scaffold().structure().state_is_read_accessible());
910  require(scaffold().structure().contains_row_dof_tuple(xtuple_id));
911 
912  // Body:
913 
914  // The current scratch id fo the external dof tuple id space is the
915  // external id to use.
916 
919 
920  // Insert the result into the external dof tuple id space.
921 
922  ldof_tuple_space.insert(result, xtuple_id.hub_pod());
923 
924  // Compute the next external id.
925 
926  pod_index_type lnext_ext_id = result;
927 
928  // Get the dof map.
929 
930  poset_dof_map& lint_dof_map = scaffold().structure().row_dof_map(xtuple_id);
931 
932  schema_poset_member& lint_dof_map_schema = lint_dof_map.schema();
933 
934  // Iterate over the domains in the column decomposition,
935  // computing a cumulative offset.
936 
942 
943  index_iterator* lcol_itr =
944  scaffold().external_schema().bound_iterator(scaffold().col_bounds(), true);
945 
946  while(!lcol_itr->is_done())
947  {
948  // Get the transfer schema for the current domain.
949 
950  attach_transfer_schema(lint_dof_map_schema, lcol_itr->index());
951 
952  schema_poset_member& lxfr_schema = scaffold().transfer_schema();
953 
956 
957  pod_index_type litem_ext_id =
958  lxfr_schema.get_ext_id(scaffold().file_id_space_name());
959 
960  // Enter the offset of the current domain into the map.
961 
962  poset_scaffold::dof_tuple_domain_offsets_type::key_type
963  lkey(result, litem_ext_id);
964  poset_scaffold::dof_tuple_domain_offsets_type::value_type lval(lkey, lnext_ext_id);
965 
966  scaffold().dof_tuple_domain_offsets().insert(lval);
967 
968 #ifdef DIAGNOSTIC_OUTPUT
969  cout << "dof_tuple_record_set::compute_next_ext_id: offsets:" << endl;
970  cout << "xtuple_id= " << xtuple_id
971  << " lcol_itr->item= " << lcol_itr->item()
972  << " litem_ext_id= " << litem_ext_id
973  << " lnext_ext_id= " << lnext_ext_id
974  << endl;
975 #endif
976 
977  // Get the external size of the current domain.
978 
979  lnext_ext_id += compute_ext_domain_size(lint_dof_map, lxfr_schema);
980 
981  if(!scaffold().col_bounds().ub_is_singleton())
982  {
983  // Dof tuple is domain decomposed. Domains can not share
984  // records or they will over-write each other.
985  // Advance the offset to the beginning of the next record.
986 
987  lnext_ext_id = advance_to_start_of_record(lnext_ext_id);
988  }
989 
990  // Move on to the next domain.
991 
992  lcol_itr->next();
993 
994  } // end while(!lcol_itr->is_done())
995 
996  delete lcol_itr;
997 
998  // Set the scratch id of the external dof tuple map to the next external id.
999 
1000  scaffold().put_dof_tuple_scratch_id(lnext_ext_id);
1001 
1002  // Postconditions:
1003 
1004  // Exit
1005 
1006  return result;
1007 }
1008 
1009 
1013 compute_ext_domain_size(const poset_dof_map& xdof_map, const schema_poset_member& xfr_schema) const
1014 {
1015  size_type result = 0;
1016 
1017  // Preconditions:
1018 
1019  // Body:
1020 
1021  result = xfr_schema.ext_data_type_ct(false)*_record_size;
1022 
1023  // Postconditions:
1024 
1025  // Exit
1026 
1027  return result;
1028 }
1029 
1030 
1031 
1033 hid_t
1036 {
1037  hid_t result;
1038 
1039  // Preconditions:
1040 
1041  require(file().mode() == sheaf_file::READ_WRITE);
1042 
1043  // Body:
1044 
1045  // Create an extendible dataspace.
1046 
1047  // Initial guess at dimensions
1048 
1054 
1061 
1062  // Set initial dataset extent to 1 record;
1063  // will extend to actual size on first write; see write_selection();
1064 
1065  hsize_t linit_dims[DATASPACE_RANK];
1066  linit_dims[0] = 1;
1067 
1068  // Maximum dimensions.
1069 
1070  hsize_t lmax_dims[DATASPACE_RANK];
1071  lmax_dims[0] = H5S_UNLIMITED;
1072 
1073  _ext_dataspace_hdf_id = H5Screate_simple(DATASPACE_RANK, linit_dims, lmax_dims);
1074  if(_ext_dataspace_hdf_id < 0)
1075  {
1076  post_fatal_error_message("can't create data space");
1077  }
1078 
1079  // We'll need a chunked dataset.
1080  // Create the chunk dimensions.
1081  // A chunk is the unit of i/o, make it the same size as the record buffer.
1082 
1083  hsize_t lchunk_dims[DATASPACE_RANK];
1084  lchunk_dims[0] = _record_buffer_ub;
1085 
1086  // Create the property list for the chunked dataset
1087 
1088  hid_t lparms = H5Pcreate(H5P_DATASET_CREATE);
1089  herr_t status = H5Pset_chunk( lparms, DATASPACE_RANK, lchunk_dims);
1090  if(status < 0)
1091  {
1092  post_fatal_error_message("can't set chunk size");
1093  }
1094 
1095  // Create the dataset with the internal data type.
1096  // External data type will be set in record_set::open by querying the dataset.
1097 
1098  // result = H5Dcreate(file().hdf_id(),
1099  result = H5Dcreate1(file().hdf_id(),
1100  name().c_str(),
1103  lparms);
1104  if(result <0)
1105  {
1106  post_fatal_error_message("unable to create dataset.");
1107  }
1108 
1109  // Postconditions:
1110 
1111  ensure(result >= 0);
1112 
1113  // Exit
1114 
1115  return result;
1116 }
1117 
1118 
1119 
1121 void
1124 {
1125  // Preconditions:
1126 
1127  require(is_open());
1128 
1129  // Body:
1130 
1131 #ifdef DIAGNOSTIC_OUTPUT
1132  cout << "selection:" << endl;
1133  cout << setw(6) << "i" << setw(6) << "int" << setw(6) << "ext" << endl;
1134  for(int i= 0; i<_hdf_selection_ct; i++)
1135  {
1136  cout << setw(6) << i
1137  << setw(6) << _hdf_int_selection[i][0]
1138  << setw(6) << _hdf_ext_selection[i][0]
1139  << endl;
1140  }
1141  cout << endl;
1142 #endif
1143 
1144 
1145  // Set the selection for the internal data space.
1146  // The following cast is FM taken from HDF source. H5S_point_add immediately
1147  // casts arg to hsize_t*, which it thinks is pointing at the first element
1148  // in the array.
1149 
1150  // const hsize_t** lselect = reinterpret_cast<const hsize_t**>(_hdf_int_selection);
1151  const hsize_t* lselect = &(_hdf_int_selection[0][0]);
1152  herr_t status =
1153  H5Sselect_elements(_int_dataspace_hdf_id, H5S_SELECT_SET, _hdf_selection_ct, lselect);
1154  if(status < 0)
1155  {
1156  post_fatal_error_message("can't set dof tuple record write selection fro internal dataspace");
1157  }
1158 
1159  // Set the external selection.
1160  // The following cast is FM taken from HDF source. H5S_point_add immediately
1161  // casts arg to hsize_t*, which it thinks is pointing at the first element
1162  // in the array.
1163 
1164  // lselect = reinterpret_cast<const hsize_t**>(_hdf_ext_selection);
1165  lselect = &(_hdf_ext_selection[0][0]);
1166  status = H5Sselect_elements(_ext_dataspace_hdf_id, H5S_SELECT_SET, _hdf_selection_ct, lselect);
1167  if(status < 0)
1168  {
1169  post_fatal_error_message("can't set dof tuple record read selection");
1170  }
1171 
1172  // Read the selected records
1173 
1175  _ext_dataspace_hdf_id, H5P_DEFAULT, _hdf_buf);
1176  if(status < 0)
1177  {
1178  post_fatal_error_message("can't read dof tuple record selection");
1179  }
1180 
1181 #ifdef DIAGNOSTIC_OUTPUT
1182  cout << "in dof_tuple_record_set::read_selection: buffer is:";
1183  cout << setbase(16);
1184  cout << setfill('0');
1185  for(size_t i=0; i<_hdf_buf_ub; i++)
1186  {
1187  if((i % _record_size) == 0)
1188  {
1189  cout << endl;
1190  }
1191  cout << setw(2) << int(reinterpret_cast<unsigned char*>(_hdf_buf)[i]) << " ";
1192  }
1193  cout << endl << endl;
1194  cout << setbase(10) << setfill(' ');
1195 #endif
1196 
1197  // Postconditions:
1198 
1199  // Exit
1200 
1201  return;
1202 }
1203 
1204 
1206 void
1209 {
1210  // Preconditions:
1211 
1212  require(is_open());
1213  require(_hdf_selection_ct > 0);
1214 
1215  // Body:
1216 
1217 #ifdef DIAGNOSTIC_OUTPUT
1218  cout << "writing poset: " << scaffold().structure().name() << " int_selection:" << endl;
1219  for(int i= 0; i<_hdf_selection_ct; i++)
1220  {
1221  cout << i << " " << _hdf_int_selection[i][0] << endl;
1222  }
1223  cout << endl;
1224 #endif
1225 
1226  // Set the selection for the internal data space.
1227  // The following cast is FM taken from HDF source. H5S_point_add immediately
1228  // casts arg to hsize_t*, which it thinks is pointing at the first element
1229  // in the array.
1230 
1231  // const hsize_t** lselect = reinterpret_cast<const hsize_t**>(_hdf_int_selection);
1232  const hsize_t* lselect = &(_hdf_int_selection[0][0]);
1233  herr_t status = H5Sselect_elements(_int_dataspace_hdf_id, H5S_SELECT_SET, _hdf_selection_ct, lselect);
1234  if(status < 0)
1235  {
1236  post_fatal_error_message("can't set dof tuple record write selection for internal dataspace");
1237  }
1238 
1239  // Extend the dataset to include the external selection.
1240 
1242 
1243 #ifdef DIAGNOSTIC_OUTPUT
1244  cout << "dataspace extent:";
1245  for(int i=0; i<ext_dataspace_rank(); i++)
1246  {
1247  cout << " " << _ext_dataspace_dims[i];
1248  }
1249  cout << endl;
1250 #endif
1251 
1252  // Get size of dofs currently queued for output.
1253 
1254  size_t lq_size = scaffold().dof_tuple_scratch_id();
1255 
1256  // Find record number that contains lq_size.
1257 
1258  hsize_t ldims[DATASPACE_RANK];
1259  ldims[0] = ((lq_size + _record_size - 1)/_record_size);
1260 
1261  // Extend the data set.
1262 
1263  extend_dataset(ldims, DATASPACE_RANK);
1264 
1265 #ifdef DIAGNOSTIC_OUTPUT
1266  cout << "ext_selection:" << endl;
1267  for(int i= 0; i<_hdf_selection_ct; i++)
1268  {
1269  cout << i << " " << _hdf_ext_selection[i][0] << endl;
1270  }
1271  cout << endl;
1272 #endif
1273 
1274  // Set the external selection.
1275  // The following cast is FM taken from HDF source. H5S_point_add immediately
1276  // casts arg to hsize_t*, which it thinks is pointing at the first element
1277  // in the array.
1278 
1279  // lselect = reinterpret_cast<const hsize_t**>(_hdf_ext_selection);
1280  lselect = &(_hdf_ext_selection[0][0]);
1281  status = H5Sselect_elements(_ext_dataspace_hdf_id, H5S_SELECT_SET, _hdf_selection_ct, lselect);
1282  if(status < 0)
1283  {
1284  post_fatal_error_message("can't set dof tuple record write selection");
1285  }
1286 
1287 #ifdef DIAGNOSTIC_OUTPUT
1288  cout << "in dof_tuple_record_set::write_selection: buffer is:";
1289  cout << setbase(16);
1290  cout << setfill('0');
1291  for(size_t i=0; i<_hdf_buf_ub; i++)
1292  {
1293  if((i % _record_size) == 0)
1294  {
1295  cout << endl;
1296  }
1297  cout << setw(2) << int(reinterpret_cast<unsigned char*>(_hdf_buf)[i]) << " ";
1298  }
1299  cout << endl << endl;
1300  cout << setbase(10) << setfill(' ');
1301 #endif
1302 
1303  // Write the selected records
1304 
1306  _ext_dataspace_hdf_id, H5P_DEFAULT, _hdf_buf);
1307  if(status < 0)
1308  {
1309  post_fatal_error_message("can't write dof tuple record selection");
1310  }
1311 
1312  // Postconditions:
1313 
1314  // Exit
1315 
1316  return;
1317 }
1318 
1319 
1320 // PROTECTED MEMBER FUNCTIONS
1321 
1322 void
1325 {
1326  // Preconditions:
1327 
1328  // Body:
1329 
1330  // Attach the dof subposet handles in the poset.
1331 
1332  poset_state_handle& lposet = scaffold().structure();
1333 
1334  string ltable_dof_sp_name = schema_poset_member::table_dof_subposet_name("top");
1335  if(lposet.includes_subposet(ltable_dof_sp_name))
1336  {
1337  lposet.table_dof_subposet().attach_to_state(&lposet, ltable_dof_sp_name);
1338 
1339  if(!lposet.table_dof_subposet().has_id_space())
1340  {
1342  }
1343 
1344  }
1345 
1346  string lrow_dof_sp_name = schema_poset_member::row_dof_subposet_name("top");
1347  if(lposet.includes_subposet(lrow_dof_sp_name))
1348  {
1349  lposet.row_dof_subposet().attach_to_state(&lposet, lrow_dof_sp_name);
1350 
1351  if(!lposet.row_dof_subposet().has_id_space())
1352  {
1353  lposet.initialize_dof_id_space(lposet.row_dof_subposet());
1354  }
1355  }
1356 
1357  // Postconditions:
1358 
1359  // Exit
1360 
1361  return;
1362 }
1363 
1365 void
1368  const poset_dof_map& xint_dof_map,
1369  char*& xbuf,
1370  size_t& xbuf_remainder)
1371 {
1372  // Preconditions:
1373 
1374  require(xbuf_remainder == _record_size); // The tranparency hack.
1375 
1376  // Body:
1377 
1378  // char* lbuf = const_cast<char*&>(xbuf);
1379  char* lbuf = xbuf;
1380  int ldof_tuple_type;
1381  int lrecord_dof_index = 0;
1382  dof_descriptor_array& ldof_descriptors = *xxfr_schema.ext_data_type_schema().dof_descriptors(false);
1383 
1384 
1385  if(xint_dof_map.supports_xfr_opt() &&
1386  xxfr_schema.is_same_state(&xint_dof_map.schema()) &&
1387  (xxfr_schema.version() == xint_dof_map.schema().version()) &&
1388  is_primitive_index(ldof_tuple_type = xxfr_schema.row_dof_tuple_type()))
1389  {
1390  // Section dof tuple and same schema and version and homogeneous dof tuple.
1391  // Don't need to gather/scatter, more efficient to just iterate over sequence id.
1392 
1393  // post_information_message("iterating over sequence id");
1394 
1395  data_converter* dc = type_map()[ldof_tuple_type];
1396 
1397  bool lis_nrmi_type = dc->is_namespace_relative_member_index_type();
1398  bool lis_nrsi_type = dc->is_namespace_relative_subposet_index_type();
1399  bool lid_needs_conversion = lis_nrmi_type || lis_nrsi_type;
1400 
1401  int ldof_ct = xxfr_schema.row_dof_ct();
1402 
1403 
1404  for(int i=0; i<ldof_ct; ++i)
1405  {
1406  if(xbuf_remainder == 0)
1407  {
1408  lbuf = get_next_record(xbuf);
1409  lrecord_dof_index = 0;
1410  xbuf = lbuf;
1411  xbuf_remainder = _record_size;
1412  }
1413 
1414  // Gather the dof to the hdf buffer.
1415 
1416  xint_dof_map.get_dof(i, xbuf, xbuf_remainder);
1417 
1418  if(lid_needs_conversion)
1419  {
1420  // This is a namespace relative index type;
1421  // need to convert internal id to external id.
1422 
1423  if(lis_nrmi_type)
1424  {
1425  // This is a member index type.
1426 
1428  }
1429  else
1430  {
1431  // Must be a subposet index type.
1432 
1434  }
1435  }
1436 
1437  // Move on to the next dof.
1438 
1439  ++lrecord_dof_index;
1440  size_t loffset = ldof_descriptors[lrecord_dof_index].offset;
1441  xbuf = lbuf + loffset;
1442  xbuf_remainder = _record_size - loffset;
1443  }
1444 
1445  }
1446  else
1447  {
1448  // Different schema or version or inhomogeneous dof tuple;
1449  // use iterator to gather/scatter.
1450 
1451  // post_information_message("iterating over schema");
1452 
1453  poset_dof_iterator* lxfr_itr = xxfr_schema.row_dof_iterator();
1454  while(!lxfr_itr->is_done())
1455  {
1456  if(xbuf_remainder == 0)
1457  {
1458  lbuf = get_next_record(xbuf);
1459  lrecord_dof_index = 0;
1460  xbuf = lbuf;
1461  xbuf_remainder = _record_size;
1462  }
1463 
1464 #ifdef DIAGNOSTIC_OUTPUT
1465  cout << "dof: " << lxfr_itr->item().name();
1466  cout << " xbuf: " << static_cast<void*>(xbuf)
1467  << " xbuf_remainder: " << xbuf_remainder
1468  << endl;
1469 #endif
1470 
1471  // Gather dof to the hdf buffer.
1472 
1473  xint_dof_map.get_dof(lxfr_itr->index(), xbuf, xbuf_remainder);
1474 
1475  // If this is a namespace relative index type;
1476  // need to convert internal id to external id.
1477 
1478  data_converter* dc = type_map()[lxfr_itr->item().type()];
1480  {
1482  }
1484  {
1486  }
1487 
1488  // Move on to the next dof.
1489 
1490  ++lrecord_dof_index;
1491  size_t loffset = ldof_descriptors[lrecord_dof_index].offset;
1492  xbuf = lbuf + loffset;
1493  xbuf_remainder = _record_size - loffset;
1494 
1495  lxfr_itr->next();
1496  }
1497  delete lxfr_itr;
1498  }
1499 
1500 
1501  // Postconditions:
1502 
1503 
1504  // Exit:
1505 
1506  return;
1507 }
1508 
1509 
1511 void
1514  poset_dof_map& xext_dof_map,
1515  char* xbuf,
1516  size_t xbuf_remainder)
1517 {
1518  // Preconditions:
1519 
1520  require(xbuf_remainder == _record_size); // The tranparency hack.
1521 
1522  // Body:
1523 
1524  char* lbuf = xbuf;
1525  int ldof_tuple_type;
1526  int lrecord_dof_index = 0;
1527  dof_descriptor_array& ldof_descriptors = *xxfr_schema.ext_data_type_schema().dof_descriptors(false);
1528 
1529  if(xext_dof_map.supports_xfr_opt() &&
1530  xxfr_schema.is_same_state(&xext_dof_map.schema()) &&
1531  (xxfr_schema.version() == xext_dof_map.schema().version()) &&
1532  is_primitive_index(ldof_tuple_type = xxfr_schema.row_dof_tuple_type()))
1533  {
1534  // Section dof tuple and same schema and version and homogeneous dof tuple.
1535  // Don't need to gather/scatter, more efficient to just iterate over sequence id.
1536 
1537 
1538 #ifdef DIAGNOSTIC_OUTPUT
1539  post_information_message("iterating over sequence id");
1540  primitive_value lprim(primitive_value::prototype(ldof_tuple_type));
1541 #endif
1542 
1543  data_converter* dc = type_map()[ldof_tuple_type];
1544  int ldof_ct = xxfr_schema.row_dof_ct();
1545 
1546 
1547  for(pod_index_type i=0; i<ldof_ct; ++i)
1548  {
1549  if(xbuf_remainder == 0)
1550  {
1551  lbuf = get_next_record(xbuf);
1552  lrecord_dof_index = 0;
1553  xbuf = lbuf;
1554  xbuf_remainder = _record_size;
1555  }
1556 
1557  // Convert internal id to external id, if needed.
1558 
1560  {
1562  }
1564  {
1566  }
1567 
1568  // Copy the dof into the dof tuple.
1569 
1570  xext_dof_map.put_dof(i, xbuf, xbuf_remainder);
1571 
1572 #ifdef DIAGNOSTIC_OUTPUT
1573  lprim.value() = *reinterpret_cast<primitive_buffer_type*>(xbuf);
1574  cout << " " << lprim.to_string();
1575 #endif
1576 
1577  // Move on to the next dof.
1578 
1579  ++lrecord_dof_index;
1580  size_t loffset = ldof_descriptors[lrecord_dof_index].offset;
1581  xbuf = lbuf + loffset;
1582  xbuf_remainder = _record_size - loffset;
1583  }
1584 
1585 #ifdef DIAGNOSTIC_OUTPUT
1586  cout << endl;
1587 #endif
1588 
1589  }
1590  else
1591  {
1592  // Different schema or version or inhomogeneous dof tuple;
1593  // use iterator to gather/scatter.
1594 
1595 #ifdef DIAGNOSTIC_OUTPUT
1596  post_information_message("iterating over schema");
1597 #endif
1598 
1599  poset_dof_iterator* xfr_itr =
1600  xxfr_schema.row_dof_iterator(xext_dof_map.version());
1601 
1602  while(!xfr_itr->is_done())
1603  {
1604  if(xbuf_remainder == 0)
1605  {
1606  lbuf = get_next_record(xbuf);
1607  lrecord_dof_index = 0;
1608  xbuf = lbuf;
1609  xbuf_remainder = _record_size;
1610  }
1611 
1612  // Convert internal id to external id, if needed.
1613 
1614  data_converter* dc = type_map()[xfr_itr->item().type()];
1616  {
1618  }
1620  {
1622  }
1623 
1624  // Copy the dof into the dof tuple.
1625 
1626  xext_dof_map.put_dof(xfr_itr->index(), xbuf, xbuf_remainder);
1627 
1628 #ifdef DIAGNOSTIC_OUTPUT
1629  primitive_value lprim(xfr_itr->item().type(), xbuf);
1630  cout << " " << lprim.to_string();
1631 #endif
1632 
1633  // Move on to the next dof.
1634 
1635  ++lrecord_dof_index;
1636  size_t loffset = ldof_descriptors[lrecord_dof_index].offset;
1637  xbuf = lbuf + loffset;
1638  xbuf_remainder = _record_size - loffset;
1639  xfr_itr->next();
1640  }
1641  delete xfr_itr;
1642 
1643 #ifdef DIAGNOSTIC_OUTPUT
1644  cout << endl;
1645 #endif
1646  }
1647 
1648 
1649  // Postconditions:
1650 
1651 
1652  // Exit:
1653 
1654  return;
1655 }
1656 
1658 void
1660 populate_internal_dof_map(const poset_dof_map& xext_dof_map, poset_dof_map& xint_dof_map)
1661 {
1662  // Preconditions:
1663 
1664 
1665  // Body:
1666 
1668 
1669  if(xext_dof_map.supports_xfr_opt() &&
1670  xint_dof_map.schema().is_same_state(&xext_dof_map.schema()) &&
1671  (xint_dof_map.schema().version() == xext_dof_map.schema().version()))
1672  {
1673  // Section dof tuple amd same schema and version;
1674  // don't need to gather/scatter, more efficient to just copy
1675 
1676  // post_information_message("copying dof tuple");
1677 
1678  xint_dof_map.put_dof_tuple(xext_dof_map.dof_tuple(), xext_dof_map.dof_tuple_ub());
1679  }
1680  else
1681  {
1682  // Different schema or version or sparse_field_dof_map;
1683  // use iterator to gather/scatter.
1684 
1685  // post_information_message("iterating over schema");
1686 
1687  poset_dof_iterator* lint_dof_itr = xint_dof_map.schema().row_dof_iterator();
1688  while(!lint_dof_itr->is_done())
1689  {
1690  primitive_buffer_type pbuf;
1691  scoped_index ldof_id = lint_dof_itr->index();
1692 
1693  xext_dof_map.get_dof(ldof_id, &pbuf, sizeof(pbuf));
1694  xint_dof_map.put_dof(ldof_id, &pbuf, sizeof(pbuf));
1695 
1696  lint_dof_itr->next();
1697  }
1698  delete lint_dof_itr;
1699  }
1700 
1701  // Postconditions:
1702 
1703 
1704  // Exit:
1705 
1706  return;
1707 }
1708 
1709 
1711 char*
1713 get_next_record(char* xbuf)
1714 {
1715  char* result;
1716 
1717  // Preconditions:
1718 
1719  // This routine doesn't deal with initial case xbuf == _hdf_buf.
1720 
1721  require(_hdf_buf < xbuf);
1722  require(xbuf <= (_hdf_buf + _hdf_buf_ub));
1723  require( ((xbuf - _hdf_buf) % _record_size) == 0 );
1724 
1725  // Body:
1726 
1727  // This routine gets called when a buffer record has been used up;
1728  // xbuf is always pointing 1 byte past the end of the current record.
1729 
1730  int lcur_int_rec_id = (xbuf - 1 - _hdf_buf)/_record_size;
1731 
1732  // Translate the internal buffer pointer to an external record id.
1733 
1734  int lcur_ext_rec_id = _hdf_buf_record_map.external_id(lcur_int_rec_id);
1735 
1736  // Because a dof tuple is written into contiguous storage in the dataset,
1737  // the record we want is the next external record.
1738 
1739  int lnext_ext_rec_id = lcur_ext_rec_id + 1;
1740 
1741  // Get the internal id of the record;
1742  // brings the record into the buffer if it is not already there.
1743 
1744  int lnext_int_rec_id = get_internal_record(lnext_ext_rec_id);
1745 
1746  // Now the record is in memory and we have its internal id.
1747 
1748  result = _hdf_buf + lnext_int_rec_id*_record_size;
1749 
1750  // Postconditions:
1751 
1752  ensure(result >= _hdf_buf);
1753  ensure(result < (_hdf_buf + _hdf_buf_ub));
1754  require( ((result - _hdf_buf) % _record_size) == 0 );
1755 
1756  // Exit
1757 
1758  return result;
1759 }
1760 
1761 
1763 char*
1766 {
1767  char* result;
1768 
1769  // Preconditions:
1770 
1771  // Body:
1772 
1773  // Translate the external dataset offset to an external record id.
1774 
1775  pod_index_type lext_rec_pod = xext_pod/_record_size;
1776  size_t lrec_rel_offset = xext_pod % _record_size;
1777 
1778  // Get the internal id of the record;
1779  // brings the record into the buffer if it is not already there.
1780 
1781  pod_index_type lint_rec_pod = get_internal_record(lext_rec_pod);
1782 
1783  // Now record is in memory and we have its internal id.
1784 
1785  result = _hdf_buf + lint_rec_pod*_record_size + lrec_rel_offset;
1786 
1787  // Postconditions:
1788 
1789  ensure(result >= _hdf_buf);
1790  ensure(result < _hdf_buf + _hdf_buf_ub);
1791 
1792  // Exit
1793 
1794  return result;
1795 }
1796 
1801 {
1802  pod_index_type result;
1803 
1804  // Preconditions:
1805 
1806  // Body:
1807 
1808  // Translate external record id to internal record id, if it exists.
1809 
1810  pod_index_type lint_rec_pod = _hdf_buf_record_map.internal_id(xext_rec_pod);
1811 
1812  if(!is_valid(lint_rec_pod))
1813  {
1814  // Record is not in memory; deal with it.
1815 
1821 
1822  lint_rec_pod = _next_record_pod;
1823  ++_next_record_pod;
1825  _next_record_pod = lpod;
1826 
1827  if(_writing)
1828  {
1829  // This is a write operation.
1830 
1831  if(_record_is_full[lint_rec_pod])
1832  {
1833  // Internal record is full; write it out.
1834 
1835  // Get the external id of internal record;
1836  // must be in the record buffer index map
1837 
1838  assertion(_hdf_buf_record_map.contains_internal_id(lint_rec_pod));
1839  pod_index_type lext_rec_pod =
1840  _hdf_buf_record_map.external_id(lint_rec_pod);
1841 
1842  _hdf_int_selection[0][0] = lint_rec_pod;
1843  _hdf_ext_selection[0][0] = lext_rec_pod;
1844  _hdf_selection_ct = 1;
1845 
1846  write_selection();
1847 
1848  _hdf_selection_ct = 0;
1849  }
1850  }
1851  else
1852  {
1853  // This is a read operation.
1854 
1855  _hdf_int_selection[0][0] = lint_rec_pod;
1856  _hdf_ext_selection[0][0] = xext_rec_pod;
1857  _hdf_selection_ct = 1;
1858 
1859  read_selection();
1860 
1861  _hdf_selection_ct = 0;
1862  }
1863 
1864  // Update the record buffer index map.
1865 
1867  _hdf_buf_record_map.put_ids(lint_rec_pod, xext_rec_pod);
1868 
1869  // Internal record is now either full or allocated to be filled;
1870  // mark it as full.
1871 
1872  _record_is_full.put(lint_rec_pod, true);
1873  }
1874 
1875  // Now record is in memory and we have its internal id.
1876 
1877  result = lint_rec_pod;
1878 
1879  // Postconditions:
1880 
1881  ensure(result >= 0);
1882  ensure(result < record_buffer_ub());
1883 
1884  // Exit
1885 
1886  return result;
1887 }
1888 
1889 
1894 {
1895  return ((xoffset + _record_size - 1)/_record_size)*_record_size;
1896 }
1897 
1898 void
1901  const scoped_index& xschema_id)
1902 {
1903  // Preconditions:
1904 
1905  require(is_open());
1906  require(scaffold().structure().state_is_read_accessible());
1907  require(xtuple_id.same_scope(scaffold().dof_tuple_id_space()));
1908 
1909  // Body:
1910 
1911  // Get the dof map.
1912 
1913  poset_dof_map& lint_dof_map = scaffold().structure().row_dof_map(xtuple_id);
1914  schema_poset_member& lint_dof_map_schema = lint_dof_map.schema();
1915 
1916  // Set the transfer schema for this domain.
1917 
1918  attach_transfer_schema(lint_dof_map_schema, xschema_id);
1919  schema_poset_member& lxfr_schema = scaffold().transfer_schema();
1920 
1921  // Get the external id for the transfer schema.
1922 
1925 
1926  pod_index_type lxfr_schema_ext_pod =
1927  lxfr_schema.get_ext_id(scaffold().file_id_space_name());
1928 
1929  // Get the offset for this domain.
1930 
1931  poset_scaffold::dof_tuple_domain_offsets_type::key_type
1932  lkey(xtuple_id.pod(), lxfr_schema_ext_pod);
1933  poset_scaffold::dof_tuple_domain_offsets_type::iterator loffsets_itr =
1934  scaffold().dof_tuple_domain_offsets().find(lkey);
1935 
1936  assertion(loffsets_itr != scaffold().dof_tuple_domain_offsets().end());
1937 
1938  pod_index_type ldom_ext_pod = loffsets_itr->second;
1939 
1940  // Get a pointer to the corresponding location in the record buffer.
1941 
1942  char* lbuf = get_first_record(ldom_ext_pod);
1943  size_t lbuf_remainder =
1944  _record_size - (static_cast<size_t>(ldom_ext_pod) % _record_size);
1945 
1946  assertion(lbuf_remainder == _record_size); // The transparency hack.
1947 
1948  // Externalize all the dofs in the domain.
1949 
1950  externalize_all_dofs(lxfr_schema, lint_dof_map, lbuf, lbuf_remainder);
1951 
1952  // Just to be tidy, clear the remainder of the record.
1953 
1954  for(size_t i=0; i<lbuf_remainder; i++)
1955  {
1956  *lbuf++ = 0;
1957  }
1958 
1959  // Postconditions:
1960 
1961  // Exit
1962 
1963  return;
1964 }
1965 
1967 void
1970  const scoped_index& xdomain_schema_id)
1971 {
1972  // Preconditions:
1973 
1974  require(scaffold().transfer_schema().is_attached());
1975 
1976  // Body:
1977 
1978  // The transfer schema should be the lesser of the
1979  // domain schema and the dof map schema and
1980  // use the same version as the dof map.
1981 
1982  schema_poset_member& lxfr_schema = scaffold().transfer_schema();
1983  if(xdof_map_schema.le(xdomain_schema_id))
1984  {
1985  lxfr_schema.attach_to_state(xdof_map_schema.index());
1986  }
1987  else
1988  {
1989  lxfr_schema.attach_to_state(xdomain_schema_id);
1990  }
1991  lxfr_schema.put_version(xdof_map_schema.version());
1992 
1993  // Postconditions:
1994 
1995  // Exit:
1996 
1997  return;
1998 }
1999 
2001 void
2004 {
2005  // Preconditions:
2006 
2007  require(file().is_open());
2008 
2009  // Body:
2010 
2011  // The io system attempts to use the sheaf table metaphor to map the
2012  // dof tuples to a file structure. For simple cases, this leads one
2013  // to think of the dof tuple data set as a table, i.e. a single index
2014  // array of records, which the record type defined by the dof tuple schema.
2015  // The record type would be implemented by an HDF compund type with one
2016  // data member for each dof defined by the schema.
2017  // For ordinary posets we can us this simple approach, but two issues
2018  // spoil this simple picture for section spaces:
2019  //
2020  // 1) A typical section schema would contain 1000's of data members,
2021  // which would likely break the compound data type mechanism,
2022  // or at least be very inefficient.
2023  // 2) We want to support partial sections, which means the
2024  // record type would be different for different records.
2025  //
2026  // So for section spaces we need some smaller data type that can serve
2027  // as a least common denominator for partial sections. A suitable candidate
2028  // is the fiber schema. Currently we only support partial sections as
2029  // restrictions of the base space, so all sections, partial or total,
2030  // share the same fiber schema.
2031  //
2032  // So for ordinary posets the record type is the defined by the schema
2033  // and for section spaces the record type is defined by the fiber schema.
2034  // This polymorphism is encapsulated by the virtual function
2035  // schema_poset_member::ext_data_type_dof_iterator().
2036  //
2037  // One further optimization is possible, for either ordinary posets or
2038  // section spaces. If all the dofs are the same primitive type, then
2039  // we can use that type as the record type and dispense with the
2040  // compound data type altogether.
2041  //
2042  // Note that the HDF type for character strings is H5T_C_S1 with
2043  // H5T_VARIABLE set. Using this type, we can treat strings almost
2044  // as if they were fixed length types, except for garbage collection.
2045  // See file_data_type_map::create_internal_hdf_types()
2046 
2047  schema_poset_member& ldt_schema =
2049  int ldof_tuple_type = ldt_schema.row_dof_tuple_type();
2050 
2051  if(is_primitive_index(ldof_tuple_type))
2052  {
2053  // The dof tuple is homogeneous.
2054 
2055  size_t lrecord_dof_ct = ldt_schema.row_dof_ct();
2056 
2057  if(lrecord_dof_ct == 1)
2058  {
2059  // Single dof per record, can use predefined type.
2060  // Copy the type so we can handle all types the same in record_set::close().
2061 
2062  _int_data_type_hdf_id = H5Tcopy(type_map()[ldof_tuple_type]->internal_type());
2063  if(_int_data_type_hdf_id < 0)
2064  {
2065  post_fatal_error_message("Can't create internal data type");
2066  }
2067  }
2068  else
2069  {
2070  // Multiple dofs per record, but all same type; use array type.
2071 
2072  hsize_t larray_dims = lrecord_dof_ct;
2074  // H5Tarray_create(type_map()[ldof_tuple_type]->internal_type(),
2075  H5Tarray_create1(type_map()[ldof_tuple_type]->internal_type(),
2076  1,
2077  &larray_dims,
2078  NULL);
2079  if(_int_data_type_hdf_id < 0)
2080  {
2081  post_fatal_error_message("Can't create internal data type");
2082  }
2083  }
2084  }
2085  else
2086  {
2087  // The dof tuple is inhomogeneous; need to construct a compound type.
2088 
2089  // Note that this data type is used to describe the internal memory layout
2090  // of the record buffer. On write, this same data type is used for the
2091  // layout on disk, so the internal and external are the same.
2092  // But on read, the external data type is whatever is in the file,
2093  // which may have been written on some other hw platform and hence may
2094  // be different than the internal laayout. HDF will do the translation.
2095 
2096  poset_dof_iterator* ldof_itr = ldt_schema.row_dof_iterator();
2097 
2098  dof_descriptor_array& ldof_descriptors = *ldt_schema.dof_descriptors(false);
2099  ldof_descriptors.add_reference();
2100 
2101  size_t ldt_size = ldt_schema.row_dof_tuple_ub();
2102 
2103  // Create a transient compound data type;
2104  // no need to share the data type, so it doesn't have to be named.
2105 
2106  _int_data_type_hdf_id = H5Tcreate(H5T_COMPOUND, ldt_size);
2107  if(_int_data_type_hdf_id < 0)
2108  {
2109  post_fatal_error_message("Can't create internal data type");
2110  }
2111 
2112  size_t lseq_id = 0;
2113  while(!ldof_itr->is_done())
2114  {
2115  dof_descriptor_array::dof_descriptor ldesc = ldof_descriptors[lseq_id];
2116  data_converter* ldof_dc = type_map()[ldesc.type];
2117 
2118  string ldof_name = ldof_itr->item().name();
2119  size_t loffset = ldesc.offset;
2120  hid_t lhdf_type = ldof_dc->internal_type();
2121 
2122 #ifdef DIAGNOSTIC_OUTPUT
2123  cout << "create_int_data_type: "
2124  << " dof_name: " << ldof_name
2125  << " offset: " << loffset
2126  << endl;
2127 #endif
2128 
2129  herr_t lstatus =
2130  H5Tinsert(_int_data_type_hdf_id, ldof_name.c_str(), loffset, lhdf_type);
2131  if(lstatus <0)
2132  {
2133  post_fatal_error_message("Unable to insert member in HDF5 compound data type.");
2134  }
2135 
2136  ldof_itr->next();
2137  ++lseq_id;
2138  }
2139 
2140  // Clean up.
2141 
2142  ldof_descriptors.remove_reference();
2143  delete ldof_itr;
2144  }
2145 
2146  // Set the record size.
2147 
2148  _record_size = H5Tget_size(_int_data_type_hdf_id);
2149 
2150  // Postconditions:
2151 
2152  ensure(int_data_type_hdf_id() >= 0);
2153 
2154  // Exit:
2155 
2156  return;
2157 }
An implementation of class scattered_insertion_index_space_handle that has a interval id space state...
void populate_internal_dof_map(const poset_dof_map &xext_dof_map, poset_dof_map &xint_dof_map)
Gathers dofs from xext_dof_map and puts them into xint_dof_map.
An encapsulation of an HDF file containing sheaf data.
Definition: sheaf_file.h:49
primitive_type row_dof_tuple_type() const
The type of row dofs defined by this. Synonym for dof_tuple_type(false).
virtual void put_version(int xversion, bool xunalias=false)
Sets version to (possibly aliased) xversion. If unalias == true, set version to the actual version al...
pod_index_type ub_id() const
The index of the upper bound member, if the upper bound contains a single member. ...
int _ext_dataspace_rank
The rank of the dataspace for the record_set.
Definition: record_set.h:420
poset_state_handle * host() const
The poset which this is a handle to a component of.
internal_index_type internal_id(external_index_type xexternal_id) const
The internal id corresponding to xexternal_id.
virtual void open()
Opens the record_set.
Definition: record_set.cc:450
hsize_t * _ext_dataspace_dims
The current dimensions of the external dataspace.
Definition: record_set.h:425
void reset_record_buffer_ct()
The set the number of active records in record buffer to 0.
Definition: record_set.cc:662
int version(bool xunalias=true) const
The (possibly aliased) version of this component. The version of the host used when evaluating proper...
virtual hid_t create_dataset()
Creates the HDF dataset associated with this.
const pod_type & pod() const
The "plain old data" storage of this; the value in the external id space.
Definition: scoped_index.h:672
virtual void next()
Makes this the next member of the subset.
void initialize_dof_id_space(subposet &xdof_subposet)
Initialize the id space for the dof subposet, xdof_subposet.
pod_index_type get_internal_record(pod_index_type xext_rec_pod)
Brings external record identified by xext_rec_pod into memory, if necessary, and returns its internal...
pod_index_type dof_tuple_schema_int_id(pod_index_type xdof_tuple_ext_id) const
The internal schema id for the dof tuple with external id xdof_tuple_ext_id.
virtual bool supports_xfr_opt() const
True if this dof map type supports dof tuple transfer optimization. /.
std::string data_set_alias(const std::string &xname) const
The data set alias for a poset with name xname.
Definition: record_set.cc:340
void translate_dof_tuple_col_bounds()
Translate the dof tuple column bounds from external ids to internal ids.
pod_index_type dof_tuple_scratch_id() const
The scratch id for the dof tuple id space.
void convert_record_id_to_subposet_id(void *xbuf)
Converts namespace relative record id at location xbuf to namespace relative subposet id at location ...
size_type _record_size
The size in bytes of a record.
external_index_type external_id(internal_index_type xinternal_id) const
The external id corresponding to xinternal_id.
virtual bool has_id_space() const
True if this already has an id space.
Definition: subposet.cc:622
poset_dof_iterator * row_dof_iterator(int xversion=CURRENT_MEMBER_VERSION) const
A postorder iterator over the row dofs defined by this.
void internalize()
Internalize the members of scafold().structure() from disk.
char * _hdf_buf
The HDF buffer.
schema_poset_member & item()
The current member of the iteration (mutable version).
char * get_next_record(char *xbuf)
The next record to use in the record buffer.
virtual schema_poset_member & schema()
The schema on which this is allocated (mutable version).
virtual bool is_ancestor_of(const any *other) const
Conformance test; true if other conforms to this.
int version() const
The version of the host of the schema this is defined on.
scoped_index dof_tuple_ext_id(const scoped_index &xid) const
An id in the dof tuple external id space with pod mapped from xid.
bool is_empty() const
True if the record queue is empty.
A client handle for a general, abstract partially order set.
int record_buffer_ct() const
The number of active records in record buffer.
Definition: record_set.cc:635
virtual bool includes_subposet(pod_index_type xsubposet_hub_id, bool xauto_access=true) const
True if this poset includes subposet with hub id xsubposet_hub_id.
void extend_dataset(const hsize_t *xdims, int xdims_ub)
Extends the dataset dimensions to at least the dimensions given xdims, an array of length xdims_ub...
Definition: record_set.cc:764
virtual void get_dof(pod_index_type xdof_id, void *xdof, size_type xdof_size) const
Copies the dof referred to by xdof_id into xdof.
const scoped_index & index() const
The current item in the subset.
virtual void * dof_tuple()=0
The dof tuple (mutable version).
int item()
OBSOLETE: use index(). The current item in the subset.
dof_descriptor_array * dof_descriptors(bool xis_table_dof) const
The dof_descriptors_array for the table dof tuple (xis_table_dof true) or row dof tuple defined by th...
void write_selection()
Write the records specified by the selection into the file.
STL namespace.
bool is_same_state(const poset_state_handle *xhost, pod_index_type xhub_id) const
True is this is attached to state with hub id xhub_id in host xhost.
void put(int i, bool value)
Sets i-th member to value.
Definition: zn_to_bool.cc:537
int _record_buffer_ub
The maximum number of records the buffer can hold.
Definition: record_set.h:441
bool is_open() const
True if this record_set is open.
Definition: record_set.cc:567
virtual pod_index_type get_ext_id(const std::string &xid_space_name) const
Gets an external id corresponding to index() in the id space with name xid_space_name.
std::string row_dof_subposet_name() const
The standard name for the row dof subposet associated with this schema member. Synonym for dof_subpos...
virtual bool is_done() const
True if iteration finished.
A (lower, upper) bounds pair for a poset. Specifies a portion of a poset for a bounded i/o operation...
Definition: poset_bounds.h:50
pod_index_type _next_record_pod
The index of the next buffer record to allocate for a read or write operation.
bool is_namespace_relative_member_index_type() const
True if this is a converter for a naemspace_relative_member_index type.
const scoped_index & index() const
The index of the component state this handle is attached to.
The general, abstract map from dof ids to dof values.
Definition: poset_dof_map.h:59
record_queue & queue()
The queue of dof tuple record requests.
record_map< pod_index_type, pod_index_type > _hdf_buf_record_map
The record id map for the hdf buffer.
virtual primitive_type type() const
The primitive type index of the dof defined by this.
bool contains_internal_id(internal_index_type xint_id) const
True if this map contains an entry for internal index xint_id.
virtual schema_poset_member & ext_data_type_schema()
The schema for the external data type associated with this schema.
int dof_tuple_schema_version(pod_index_type xext_id) const
The external schema version for the dof tuple with external id xdof_tuple_ext_id. ...
void internalize_all_dofs(schema_poset_member &xxfr_schema, poset_dof_map &xext_dof_map, char *xbuf, size_t xbuf_remainder)
Internalizes all the dofs in the domain described by xxfr_schema.
hid_t int_data_type_hdf_id()
The HDF internal data type id for this record set.
Definition: record_set.cc:989
std::string alias() const
The standard alias for this data set.
Definition: record_set.cc:247
virtual void create_int_data_type()
Creates a new HDF internal data type.
void next()
Makes item the next member of the subset.
bool same_scope(const scoped_index &xother) const
True if and only if this is in the same id space as xother.
Definition: scoped_index.h:464
void attach_to_state(const poset_state_handle *xhost, pod_index_type xhub_id)
Attach this handle to the state with hub id xhub_id in the current version of host xhost...
hid_t _hdf_id
The HDF id for this record set.
Definition: record_set.h:405
hsize_t(* _hdf_int_selection)[1]
The HDF internal record selection buffer.
virtual bool invariant() const
Class invariant.
Definition: record_set.cc:71
Abstract base class with useful features for all objects.
Definition: any.h:39
std::string _alias
The standard alias for this record_set.
Definition: record_set.h:395
virtual dof_tuple_record_set * clone() const
Virtual constructor; makes a new instance of the same type as this.
std::string to_string() const
Converts this to a string (for stream insertion).
virtual schema_poset_member & schema()
The schema for this poset (mutable version).
dof_tuple_index_space_type & dof_tuple_id_space()
External to internal dof_tuple index space for table() (mutable version).
pod_index_type dequeue()
Removes and returns the index at the front of the record queue.
hid_t _int_data_type_hdf_id
The HDF internal data type id for this record set.
Definition: record_set.h:452
void attach_transfer_schema(schema_poset_member &xdof_map_schema, const scoped_index &xdomain_schema_id)
Attaches the transfer schema to the lesser of the dof map schema or the domain schema.
subposet & row_dof_subposet()
The row dof subposet when this poset is used as a schema (mutable version).
virtual pod_index_type get_ext_id(pod_index_type xint_id, const std::string &xid_space_name, bool xauto_access) const
Translates xint_id to an external id using the equivalence map with name xid_space_name.
record_queue _record_queue
The record queue.
void read_selection()
Read the records specified by the selection into the record buffer.
bool is_open() const
True if this file is open.
Definition: sheaf_file.cc:306
Type of buffer large enough to hold any primitive type.
size_t dof_tuple_ub() const
The size of the dof tuple in bytes.
pod_index_type advance_to_start_of_record(pod_index_type xext_pod)
Advances the offset xoffset to the smallest offset which is less than or equal to xoffset and which i...
std::string _name
The name of this record_set.
Definition: record_set.h:390
hid_t hdf_id()
The HDF id for this record set.
Definition: record_set.cc:929
An index within the external ("client") scope of a given id space.
Definition: scoped_index.h:116
int record_buffer_ub() const
The maximum number of records the buffer can hold.
Definition: record_set.cc:685
int ext_dataspace_rank()
The rank of the dataspace for the record_set.
Definition: record_set.cc:950
void convert_record_id_to_member_id(void *buf)
Converts namespace relative record id at location xbuf to namespace relative member id at location xb...
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
size_type compute_ext_domain_size(const poset_dof_map &xdof_map, const schema_poset_member &xschema) const
Computes the external size for the portion of the dof tuple xdof_map which is described by schema xsc...
An abstract, indexed collection of records on secondary storage.
Definition: record_set.h:150
std::string data_set_name(const std::string &xname) const
The data set name for a poset with name xname.
Definition: record_set.cc:308
dof_tuple_domain_offsets_type & dof_tuple_domain_offsets()
Dof tuple domain offsets accessor (mutable version).
size_type record_size() const
The size in bytes of data transfers to disk.
virtual void init_row_dof_map(const poset_state_handle *xhost, pod_index_type xschema_mbr_id, int xschema_version)
Initializes this as a map for row dofs in host xhost, with schema member specified by xschema_mbr_id ...
schema_poset_member & external_schema()
The schema of the poset in external namespace (mutable version).
void put_dof_tuple_scratch_id(pod_index_type xid)
Set the scratch id for the dof tuple id space.
std::string name(pod_index_type xdof_id, bool xis_table_dof) const
The name of the table dof (xis_table_dof true) or row dof referred to by xdof_id in the schema define...
bool le(pod_index_type xother_index) const
True if this is less than or equal to the member with index xother_index.
void insert(pod_type xid, const scoped_index &xhub_id)
Make id xid in this id space equivalent to xhub_id in the hub id space. synonym for insert(xid...
SHEAF_DLL_SPEC bool is_primitive_index(pod_index_type xindex)
True if xindex is a valid primitive index.
poset_bounds & col_bounds()
The bounds for the columns in this transaction (mutable version).
int _hdf_selection_ct
The number of records selected.
void externalize_domain(const scoped_index &xtuple_ext_id, const scoped_index &xschema_id)
Externalize the domain specified by the schema member with index xschema_id.
bool ub_is_singleton() const
True if the upper bound contains a single member.
size_t _hdf_buf_ub
The HDF buffer upper bound.
An array for storing structs which describe the size, alignment, and offset of dofs within a dof tupl...
static int row_dof_ct(const namespace_poset &xns, const poset_path &xpath, bool xauto_access=true)
The number of row dofs defined by the schema specified by xns and xpath. Synonym for dof_ct(xns...
poset_scaffold & scaffold()
Scaffold for constructing poset associated with this record set (mutable version).
Definition: record_set.cc:416
hsize_t(* _hdf_ext_selection)[1]
The HDF external record selection buffer.
virtual std::string name() const
The name of this poset.
void disable_invariant_check() const
Disable invariant check. Intended for preventing recursive calls to invariant and for suppressing inv...
Definition: any.h:97
dof_tuple_record_set(const dof_tuple_record_set &xother)
Copy constructor.
void externalize_one_domain(const scoped_index &xtuple_id, const scoped_index &xschema_id)
Externalize the domain specified by the schema member with index xschema_id. Does not initialize reco...
int _hdf_selection_ub
The HDF record selection buffers upper bound.
virtual size_t ext_data_type_ct(bool xis_table_schema) const
The number of instances of the external data type needed to represent this schema.
void externalize()
Externalize the members of scafold().structure() to disk.
void put_dof_tuple_col_bound(pod_index_type xdof_tuple_ext_id)
Insets the descriptor for the column bound for the dof tuple with external id xdof_tuple_ext_id into ...
index_iterator * bound_iterator(const poset_bounds &xbnd_id, bool xis_ub) const
An iterator for the upper bound (xis_ub == true) or the lower bound (xis_ub == false) for xbounds...
A record_set which contains dof tuple records. Supports both record selection and record restriction ...
poset_state_handle & structure()
The handle for the poset being transferred. (Name chosen to void name conflict with class poset...
virtual const scoped_index & index()
The index of the current member of the iteration.
bool is_namespace_relative_subposet_index_type() const
True if this is a converter for a namespace_relative_subposet_index type.
Iterates over the subset of Zn defined by the characteristic function host().
std::string name() const
The name of this data set.
Definition: record_set.cc:224
primitive_buffer_type & value()
The value of this.
virtual poset_dof_map & row_dof_map(pod_index_type xtuple_hub_id, bool xrequire_write_access=false) const
The map from row dof client_ids to row dof values for dof tuple hub id xtuple_hub_id.
bool ge(pod_index_type xother_index) const
True if this is greater than or equal to the member with index xother_index.
void schematize()
Schematize the table and row dof subposets.
zn_to_bool _record_is_full
True if i-th record is full and should be written out.
dof_tuple_schema_versions_type & dof_tuple_schema_versions()
Dof tuple schema versions (mutable version).
size_t _hdf_scratch_buf_ub
The size of the scratch buffer in bytes.
void remove_reference()
Remove a reference from this.
void remove_internal_id(internal_index_type xinternal_id)
Removes xinternal_id and its external image from the map.
virtual poset_state_handle * host() const
The poset which owns this.
size_t row_dof_tuple_ub() const
The size in bytes of the row dof tuple defined by this schema. Synonym for dof_tuple_ub(false).
bool invariant_check() const
True if invariant checking is enabled.
Definition: any.h:79
dof_tuple_schema_ids_type & dof_tuple_schema_ids()
Dof tuple schema ids (mutable version).
Iterates in postorder over dofs of a schema member anchor. Attaches a handle of type schema_poset_mem...
pod_index_type compute_ext_id(const scoped_index &xtuple_id)
Computes the external id for the dof tuple dof tuple with id xtuple_id.
const sheaf_file & file() const
The file this record_set belongs to.
Definition: record_set.cc:213
A queue for record read requests.
Definition: record_queue.h:50
void put_dof(pod_index_type xdof_id, const primitive_value &xdof)
Sets the dof referred to by xdof_id to xdof.
bool _writing
True if current operation is a write operation.
subposet & table_dof_subposet()
The table dof subposet when this poset is used as a schema (mutable version).
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
void add_reference()
Add a reference to this.
bool is_done() const
True if iteration finished.
Function object to convert between internal and external data formats.
poset_data_type_map & type_map()
Data type map for records in this record set (mutable version)
Definition: record_set.cc:432
A poset specific collection of data converters, various buffers and other data used while transferrin...
schema_poset_member & transfer_schema()
The schema for the restriction that is being read or written (mutable version)
virtual void open()
Opens the record_set.
virtual void put_dof_tuple(const void *xbuf, size_t xbuflen)=0
Copies the entire dof tuple from xbuf into internal storage.
hid_t internal_type() const
The HDF type identifier for the internal type.
void attach_to_state(const namespace_poset *xns, const poset_path &xpath, bool xauto_access=true)
Attach to the state specified by path xpath in the namespace xns.
void put_ids(internal_index_type xinternal_id, external_index_type xexternal_id)
Defines the mapping between xinternal_id and xexternal_id.
Abstract object wrapper for an instance of a primitive type.
static const primitive_value & prototype(pod_index_type xid)
The prototype for the primitive value of the type associated with xid.
virtual ~dof_tuple_record_set()
Destructor.
size_t max_size() const
The maximum size, internal or external, of any fixed length type.
void convert_subposet_id_to_record_id(void *xbuf)
Converts namespace relative subposet id at location xbuf to namespace relative record id at location ...
void read_records()
Read and internalizes all the records.
virtual bool invariant() const
Class invariant.
virtual const std::string & suffix() const
The name suffix for this data set.
virtual schema_poset_member & schema()
The schema for this member (mutable version).
SHEAF_DLL_SPEC bool is_valid(pod_index_type xpod_index)
True if an only if xpod_index is valid.
Definition: pod_types.cc:37
bool is_same_type(const any *other) const
True if other is the same type as this.
Definition: any.cc:79
hid_t _ext_dataspace_hdf_id
The HDF id for the external dataspace of this record set.
Definition: record_set.h:410
void enable_invariant_check() const
Enable invariant checking.
Definition: any.h:87
void externalize_all_dofs(schema_poset_member &xxfr_schema, const poset_dof_map &xint_dof_map, char *&xbuf, size_t &xbuf_remainder)
Externalizes all the dofs in the domain described by xxfr_schema.
std::string table_dof_subposet_name() const
The standard name for the table dof subposet associated with this schema member. Synonym for dof_subp...
virtual poset_dof_map * clone() const =0
Virtual default constructor.
char * get_first_record(pod_index_type xext_pod)
The first record associated with the dof tuple with external id xext_pod.
pod_index_type dof_tuple_domain_offset(pod_index_type xdof_tuple_ext_id, pod_index_type xdomain_key) const
The offset for domain xdomain_key in tuple xdof_tuple_ext_id.
A client handle for a poset member which has been prepared for use as a schema.
hid_t _int_dataspace_hdf_id
The hdf5 id of the dataspace associated with the record buffer.
Definition: record_set.h:447
char * _hdf_scratch_buf
Scratch buffer for internalizing dofs that span record boundaries.
pod_type hub_pod() const
The pod value of this mapped to the unglued hub id space.
Definition: scoped_index.h:710
void convert_member_id_to_record_id(void *buf)
Converts namespace relative member id at location xbuf to namespace relative record id at location xb...