/** * Locate each unexpanded Structure|Sequence and: 1. check that none of its fields is referenced * => do not expand 2. add all of its fields as leaves Note that #2 may end up adding additional * leaf structs &/or seqs */ public void expand() { // Create a queue of unprocessed leaf compounds Queue<DapVariable> queue = new ArrayDeque<DapVariable>(); for (int i = 0; i < variables.size(); i++) { DapVariable var = variables.get(i); if (!var.isTopLevel()) continue; // prime the queue if (var.getSort() == DapSort.STRUCTURE || var.getSort() == DapSort.SEQUENCE) { DapStructure struct = (DapStructure) var; // remember Sequence subclass Structure if (expansionCount(struct) == 0) queue.add(var); } } // Process the queue in prefix order while (queue.size() > 0) { DapVariable vvstruct = queue.remove(); DapStructure dstruct = (DapStructure) vvstruct; for (DapVariable field : dstruct.getFields()) { if (findVariableIndex(field) < 0) { // Add field as leaf this.segments.add(new Segment(field)); this.variables.add(field); } if (field.getSort() == DapSort.STRUCTURE || field.getSort() == DapSort.SEQUENCE) { if (expansionCount((DapStructure) field) == 0) queue.add(field); } } } this.expansion = Expand.EXPANDED; }
/** * Locate each Structure|Sequence and: 1. check that all of its fields are referenced recursively * and not constrained, otherwise ignore 2. contract by removing all of the fields of the * Structure or Sequence. This is intended to be (not quite) the dual of expand(); */ public void contract() { // Create a set of contracted compounds Set<DapStructure> contracted = new HashSet<>(); for (int i = 0; i < variables.size(); i++) { DapVariable var = variables.get(i); if (var.isTopLevel()) { if (var.getSort() == DapSort.STRUCTURE || var.getSort() == DapSort.SEQUENCE) { contractR((DapStructure) var, contracted); } } } this.expansion = Expand.CONTRACTED; }
/** * Recursive helper * * @param dstruct to contract * @param contracted set of already contracted compounds * @return true if this structure was contracted, false otherwise */ protected boolean contractR(DapStructure dstruct, Set<DapStructure> contracted) { if (contracted.contains(dstruct)) return true; int processed = 0; List<DapVariable> fields = dstruct.getFields(); for (DapVariable field : fields) { if (findVariableIndex(field) < 0) break; // this compound cannot be contracted if ((field.getSort() == DapSort.STRUCTURE || field.getSort() == DapSort.SEQUENCE) && !contracted.contains((DapStructure) field)) { if (!contractR((DapStructure) field, contracted)) break; // this compound cannot be contracted } processed++; } if (processed < fields.size()) return false; contracted.add(dstruct); // all compound fields were successfully contracted. return true; }
/** Walk all the included variables and accumulate the referenced enums */ protected void computeenums() { for (int i = 0; i < variables.size(); i++) { DapVariable var = variables.get(i); if (var.getSort() != DapSort.ATOMICVARIABLE) continue; DapType daptype = var.getBaseType(); if (!daptype.isEnumType()) continue; if (!this.enums.contains((DapEnum) daptype)) this.enums.add((DapEnum) daptype); } }
/** * See if a structure is "whole", which means that none of its fields is missing from the * constraint, all of fields use default (non-constrained) dimension), and all of its fields are * also whole. This must be done recursively. * * @param dstruct to test * @return true if this structure is whole. */ protected boolean isWholeCompound(DapStructure dstruct) { int processed = 0; List<DapVariable> fields = dstruct.getFields(); for (DapVariable field : fields) { // not contractable if this field has non-original dimensions Segment seg = findSegment(field); if (seg == null) break; // this compound is not whole List<Slice> slices = seg.slices; if (slices != null) { for (Slice slice : slices) { if (slice.isConstrained()) break; } } if (field.getSort() == DapSort.STRUCTURE || field.getSort() == DapSort.SEQUENCE) { if (!isWholeCompound((DapStructure) field)) break; // this compound is not whole } processed++; } return (processed == fields.size()); }
protected static Object fieldValue(DapSequence seq, DataRecord record, String field) throws DapException { DapVariable dapv = seq.findByName(field); if (dapv == null) throw new DapException("Unknown variable in filter: " + field); if (dapv.getSort() != DapSort.ATOMICVARIABLE) throw new DapException("Non-atomic variable in filter: " + field); if (dapv.getRank() > 0) throw new DapException("Non-scalar variable in filter: " + field); DataAtomic da = (DataAtomic) (record.readfield(field)); if (da == null) throw new DapException("No such field: " + field); return da.read(0); }