text:
package org.apache.drill.exec.physical.impl.xsort;

import io.netty.buffer.DrillBuf;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.expression.ErrorCollector;
import org.apache.drill.common.expression.ErrorCollectorImpl;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.logical.data.Order.Ordering;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.compile.sig.GeneratorMapping;
import org.apache.drill.exec.compile.sig.MappingSet;
import org.apache.drill.exec.exception.ClassTransformationException;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.expr.ClassGenerator;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
import org.apache.drill.exec.expr.CodeGenerator;
import org.apache.drill.exec.expr.ExpressionTreeMaterializer;
import org.apache.drill.exec.expr.TypeHelper;
import org.apache.drill.exec.expr.fn.FunctionGenerationHelper;
import org.apache.drill.exec.memory.BufferAllocator;
import org.apache.drill.exec.memory.OutOfMemoryException;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.config.ExternalSort;
import org.apache.drill.exec.physical.impl.sort.RecordBatchData;
import org.apache.drill.exec.physical.impl.sort.SortRecordBatchBuilder;
import org.apache.drill.exec.record.AbstractRecordBatch;
import org.apache.drill.exec.record.BatchSchema;
import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
import org.apache.drill.exec.record.MaterializedField;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.record.VectorAccessible;
import org.apache.drill.exec.record.VectorContainer;
import org.apache.drill.exec.record.VectorWrapper;
import org.apache.drill.exec.record.WritableBatch;
import org.apache.drill.exec.record.selection.SelectionVector2;
import org.apache.drill.exec.record.selection.SelectionVector4;
import org.apache.drill.exec.util.Utilities;
import org.apache.drill.exec.vector.CopyUtil;
import org.apache.drill.exec.vector.ValueVector;
import org.apache.drill.exec.vector.allocator.VectorAllocator;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.eigenbase.rel.RelFieldCollation.Direction;

import com.google.common.base.Stopwatch;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.sun.codemodel.JConditional;
import com.sun.codemodel.JExpr;

public class ExternalSortBatch extends AbstractRecordBatch<ExternalSort> {
  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ExternalSortBatch.class);

  private static final long MAX_SORT_BYTES = 1L * 1024 * 1024 * 1024;
  public static int SPILL_TARGET_RECORD_COUNT;
  public static int TARGET_RECORD_COUNT;
  public static int SPILL_BATCH_GROUP_SIZE;
  public static int SPILL_THRESHOLD;
  public static List<String> SPILL_DIRECTORIES;
  private Iterator<String> dirs;

  public final MappingSet MAIN_MAPPING = new MappingSet( (String) null, null, ClassGenerator.DEFAULT_SCALAR_MAP, ClassGenerator.DEFAULT_SCALAR_MAP);
  public final MappingSet LEFT_MAPPING = new MappingSet("leftIndex", null, ClassGenerator.DEFAULT_SCALAR_MAP, ClassGenerator.DEFAULT_SCALAR_MAP);
  public final MappingSet RIGHT_MAPPING = new MappingSet("rightIndex", null, ClassGenerator.DEFAULT_SCALAR_MAP, ClassGenerator.DEFAULT_SCALAR_MAP);
  GeneratorMapping COPIER_MAPPING = new GeneratorMapping("doSetup", "doCopy", null, null);
  public final MappingSet COPIER_MAPPING_SET = new MappingSet(COPIER_MAPPING, COPIER_MAPPING);

  private final RecordBatch incoming;
  private BatchSchema schema;
  private SingleBatchSorter sorter;
  private SortRecordBatchBuilder builder;
  private MSorter mSorter;
  private PriorityQueueCopier copier;
  private BufferAllocator copierAllocator;
  private LinkedList<BatchGroup> batchGroups = Lists.newLinkedList();
  private LinkedList<BatchGroup> spilledBatchGroups = Lists.newLinkedList();
  private SelectionVector4 sv4;
  private FileSystem fs;
  private int spillCount = 0;
  private int batchesSinceLastSpill = 0;
  private long uid;//used for spill files to ensure multiple sorts within same fragment don't clobber each others' files
  private boolean useIncomingSchema = false;
  private boolean first = true;
  private long totalSizeInMemory = 0;
  private long highWaterMark = Long.MAX_VALUE;
  private int targetRecordCount;

  public ExternalSortBatch(ExternalSort popConfig, FragmentContext context, RecordBatch incoming) throws OutOfMemoryException {
    super(popConfig, context);
    this.incoming = incoming;
    DrillConfig config = context.getConfig();
    Configuration conf = new Configuration();
    conf.set("fs.default.name", config.getString(ExecConstants.EXTERNAL_SORT_SPILL_FILESYSTEM));
    try {
      this.fs = FileSystem.get(conf);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    SPILL_TARGET_RECORD_COUNT = config.getInt(ExecConstants.EXTERNAL_SORT_TARGET_SPILL_BATCH_SIZE);
    TARGET_RECORD_COUNT = config.getInt(ExecConstants.EXTERNAL_SORT_TARGET_BATCH_SIZE);
    SPILL_BATCH_GROUP_SIZE = config.getInt(ExecConstants.EXTERNAL_SORT_SPILL_GROUP_SIZE);
    SPILL_THRESHOLD = config.getInt(ExecConstants.EXTERNAL_SORT_SPILL_THRESHOLD);
    SPILL_DIRECTORIES = config.getStringList(ExecConstants.EXTERNAL_SORT_SPILL_DIRS);
    dirs = Iterators.cycle(Lists.newArrayList(SPILL_DIRECTORIES));
    uid = System.nanoTime();
    copierAllocator = oContext.getAllocator().getChildAllocator(context.getHandle(), 10000000, 20000000);
  }

  @Override
  public int getRecordCount() {
    if (sv4 != null) {
      return sv4.getCount();
    } else {
      return container.getRecordCount();
    }
  }

  @Override
  public void kill(boolean sendUpstream) {
    incoming.kill(sendUpstream);
  }

  @Override
  public SelectionVector2 getSelectionVector2() {
    throw new UnsupportedOperationException();
  }

  @Override
  public SelectionVector4 getSelectionVector4() {
    return this.sv4;
  }

  @Override
  public BatchSchema getSchema() {
    if (useIncomingSchema) {
      List<MaterializedField> fields = Lists.newArrayList();
      for (MaterializedField field : incoming.getSchema()) {
        fields.add(field);
      }
      return BatchSchema.newBuilder().addFields(fields).setSelectionVectorMode(SelectionVectorMode.FOUR_BYTE).build();
    }
    return super.getSchema();
  }

  @Override
  public void cleanup() {
    if (batchGroups != null) {
      for (BatchGroup group: batchGroups) {
        try {
          group.cleanup();
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    }
    if (builder != null) {
      builder.clear();
    }
    if (sv4 != null) {
      sv4.clear();
    }
    copierAllocator.close();
    super.cleanup();
    incoming.cleanup();
  }

  @Override
  public IterOutcome innerNext() {
    if(schema != null){
      if (spillCount == 0) {
        if(schema != null){
          if(getSelectionVector4().next()){
            return IterOutcome.OK;
          }else{
            return IterOutcome.NONE;
          }
        }
      } else {
        Stopwatch w = new Stopwatch();
        w.start();
//        int count = selector.next();
        int count = copier.next(targetRecordCount);
        if(count > 0){
          long t = w.elapsed(TimeUnit.MICROSECONDS);
          logger.debug("Took {} us to merge {} records", t, count);
          container.setRecordCount(count);
          return IterOutcome.OK;
        }else{
          logger.debug("copier returned 0 records");
          return IterOutcome.NONE;
        }
      }
    }

    long totalcount = 0;

    try{
      outer: while (true) {
        Stopwatch watch = new Stopwatch();
        watch.start();
        IterOutcome upstream = incoming.next();
//        logger.debug("Took {} us to get next", watch.elapsed(TimeUnit.MICROSECONDS));
        switch (upstream) {
        case NONE:
          assert !first;
          break outer;
        case NOT_YET:
          throw new UnsupportedOperationException();
        case STOP:
          return upstream;
        case OK_NEW_SCHEMA:
          // only change in the case that the schema truly changes.  Artificial schema changes are ignored.
          if(!incoming.getSchema().equals(schema)){
            if (schema != null) throw new UnsupportedOperationException("Sort doesn't currently support sorts with changing schemas.");
            this.schema = incoming.getSchema();
            this.sorter = createNewSorter(context, incoming);
          }
          // fall through.
        case OK:
          if (!first && incoming.getRecordCount() == 0) {
            for (VectorWrapper w : incoming) {
              w.clear();
            }
            break;
          }
          if (first) first = false;
          totalSizeInMemory += getBufferSize(incoming);
          SelectionVector2 sv2;
          if (incoming.getSchema().getSelectionVectorMode() == BatchSchema.SelectionVectorMode.TWO_BYTE) {
            sv2 = incoming.getSelectionVector2();
            if (sv2.getBuffer(false).isRootBuffer()) {
              oContext.getAllocator().takeOwnership(sv2.getBuffer(false));
            }
          } else {
            try {
              sv2 = newSV2();
            } catch (OutOfMemoryException e) {
              throw new RuntimeException(e);
            }
          }
          int count = sv2.getCount();
          totalcount += count;
//          if (count == 0) {
//            break outer;
//          }
          sorter.setup(context, sv2, incoming);
          Stopwatch w = new Stopwatch();
          w.start();
          sorter.sort(sv2);
//          logger.debug("Took {} us to sort {} records", w.elapsed(TimeUnit.MICROSECONDS), count);
          RecordBatchData rbd = new RecordBatchData(incoming);
          if (incoming.getSchema().getSelectionVectorMode() == SelectionVectorMode.NONE) {
            rbd.setSv2(sv2);
          }
          batchGroups.add(new BatchGroup(rbd.getContainer(), rbd.getSv2()));
          batchesSinceLastSpill++;
          if ((spillCount > 0 && totalSizeInMemory > .75 * highWaterMark) ||
                  (totalSizeInMemory > .95 * popConfig.getMaxAllocation()) ||
                  (batchGroups.size() > SPILL_THRESHOLD && batchesSinceLastSpill >= SPILL_BATCH_GROUP_SIZE)) {
            mergeAndSpill();
            batchesSinceLastSpill = 0;
          }
          long t = w.elapsed(TimeUnit.MICROSECONDS);
//          logger.debug("Took {} us to sort {} records", t, count);
          break;
        case OUT_OF_MEMORY:
          highWaterMark = totalSizeInMemory;
          if (batchesSinceLastSpill > 2) mergeAndSpill();
          batchesSinceLastSpill = 0;
          break;
        default:
          throw new UnsupportedOperationException();
        }
      }

      if (spillCount == 0) {
        Stopwatch watch = new Stopwatch();
        watch.start();

        builder = new SortRecordBatchBuilder(oContext.getAllocator(), MAX_SORT_BYTES);

        for (BatchGroup group : batchGroups) {
          RecordBatchData rbd = new RecordBatchData(group.getContainer());
          rbd.setSv2(group.getSv2());
          builder.add(rbd);
        }

        builder.build(context, container);
        sv4 = builder.getSv4();
        mSorter = createNewMSorter();
        mSorter.setup(context, oContext.getAllocator(), getSelectionVector4(), this.container);
        mSorter.sort(this.container);

        sv4 = mSorter.getSV4();

        long t = watch.elapsed(TimeUnit.MICROSECONDS);
//        logger.debug("Took {} us to sort {} records", t, sv4.getTotalCount());
        container.buildSchema(SelectionVectorMode.FOUR_BYTE);
      } else {
        mergeAndSpill();
        batchGroups.addAll(spilledBatchGroups);
        logger.warn("Starting to merge. {} batch groups. Current allocated memory: {}", batchGroups.size(), oContext.getAllocator().getAllocatedMemory());
        VectorContainer hyperBatch = constructHyperBatch(batchGroups);
        createCopier(hyperBatch, batchGroups, container);
        int inMemoryRecordCount = 0;
        for (BatchGroup g : batchGroups) {
          inMemoryRecordCount += g.getRecordCount();
        }
        int estimatedRecordSize = 0;
        for (VectorWrapper w : batchGroups.get(0)) {
          try {
            estimatedRecordSize += TypeHelper.getSize(w.getField().getType());
          } catch (UnsupportedOperationException e) {
            estimatedRecordSize += 50;
          }
        }
        targetRecordCount = (int) Math.max(1, 250 * 1000 / estimatedRecordSize);
        int count = copier.next(targetRecordCount);
        container.buildSchema(SelectionVectorMode.NONE);
        container.setRecordCount(count);
      }

      return IterOutcome.OK_NEW_SCHEMA;

    }catch(SchemaChangeException | ClassTransformationException | IOException ex){
      kill(false);
      logger.error("Failure during query", ex);
      context.fail(ex);
      return IterOutcome.STOP;
    } catch (UnsupportedOperationException e) {
      throw new RuntimeException(e);
    }
  }

  public void mergeAndSpill() throws SchemaChangeException {
    logger.debug("Copier allocator current allocation {}", copierAllocator.getAllocatedMemory());
    VectorContainer outputContainer = new VectorContainer();
    List<BatchGroup> batchGroupList = Lists.newArrayList();
    int batchCount = batchGroups.size();
    for (int i = 0; i < batchCount / 2; i++) {
      if (batchGroups.size() == 0) {
        break;
      }
      if (batchGroups.peekLast().getSv2() == null) {
        break;
      }
      BatchGroup batch = batchGroups.pollLast();
      batchGroupList.add(batch);
      long bufferSize = getBufferSize(batch);
      totalSizeInMemory -= bufferSize;
    }
    if (batchGroupList.size() == 0) {
      return;
    }
    int estimatedRecordSize = 0;
    for (VectorWrapper w : batchGroups.get(0)) {
      try {
        estimatedRecordSize += TypeHelper.getSize(w.getField().getType());
      } catch (UnsupportedOperationException e) {
        estimatedRecordSize += 50;
      }
    }
    int targetRecordCount = Math.max(1, 250 * 1000 / estimatedRecordSize);
    VectorContainer hyperBatch = constructHyperBatch(batchGroupList);
    createCopier(hyperBatch, batchGroupList, outputContainer);

    int count = copier.next(targetRecordCount);
    assert count > 0;

    VectorContainer c1 = VectorContainer.getTransferClone(outputContainer);
    c1.buildSchema(BatchSchema.SelectionVectorMode.NONE);
    c1.setRecordCount(count);

    String outputFile = String.format(Utilities.getFileNameForQueryFragment(context, dirs.next(), "spill" + uid + "_" + spillCount++));
    BatchGroup newGroup = new BatchGroup(c1, fs, outputFile, oContext.getAllocator());

    try {
      while ((count = copier.next(targetRecordCount)) > 0) {
        outputContainer.buildSchema(BatchSchema.SelectionVectorMode.NONE);
        outputContainer.setRecordCount(count);
        newGroup.addBatch(outputContainer);
      }
      newGroup.closeOutputStream();
      spilledBatchGroups.add(newGroup);
      for (BatchGroup group : batchGroupList) {
        group.cleanup();
      }
      hyperBatch.clear();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    takeOwnership(c1);
    totalSizeInMemory += getBufferSize(c1);
  }

  private void takeOwnership(VectorAccessible batch) {
    for (VectorWrapper w : batch) {
      DrillBuf[] bufs = w.getValueVector().getBuffers(false);
      for (DrillBuf buf : bufs) {
        if (buf.isRootBuffer()) {
          oContext.getAllocator().takeOwnership(buf);
        }
      }
    }
  }

  private long getBufferSize(VectorAccessible batch) {
    long size = 0;
    for (VectorWrapper w : batch) {
      DrillBuf[] bufs = w.getValueVector().getBuffers(false);
      for (DrillBuf buf : bufs) {
        if (buf.isRootBuffer()) {
          size += buf.capacity();
        }
      }
    }
    return size;
  }

  private SelectionVector2 newSV2() throws OutOfMemoryException {
    SelectionVector2 sv2 = new SelectionVector2(oContext.getAllocator());
    if (!sv2.allocateNew(incoming.getRecordCount())) {
      try {
        mergeAndSpill();
      } catch (SchemaChangeException e) {
        throw new RuntimeException();
      }
      batchesSinceLastSpill = 0;
      int waitTime = 1;
      while (true) {
        try {
          Thread.sleep(waitTime * 1000);
        } catch (InterruptedException e) {
          throw new OutOfMemoryException(e);
        }
        waitTime *= 2;
        if (sv2.allocateNew(incoming.getRecordCount())) {
          break;
        }
        if (waitTime >= 32) {
          throw new OutOfMemoryException("Unable to allocate sv2 buffer after repeated attempts");
        }
      }
    }
    for (int i = 0; i < incoming.getRecordCount(); i++) {
      sv2.setIndex(i, (char) i);
    }
    sv2.setRecordCount(incoming.getRecordCount());
    return sv2;
  }

  private VectorContainer constructHyperBatch(List<BatchGroup> batchGroupList) {
    VectorContainer cont = new VectorContainer();
    for (MaterializedField field : schema) {
      ValueVector[] vectors = new ValueVector[batchGroupList.size()];
      int i = 0;
      for (BatchGroup group : batchGroupList) {
        vectors[i++] = group.getValueAccessorById(
            field.getValueClass(),
            group.getValueVectorId(field.getPath()).getFieldIds())
            .getValueVector();
      }
      cont.add(vectors);
    }
    cont.buildSchema(BatchSchema.SelectionVectorMode.FOUR_BYTE);
    return cont;
  }

  private MSorter createNewMSorter() throws ClassTransformationException, IOException, SchemaChangeException {
    return createNewMSorter(this.context, this.popConfig.getOrderings(), this, MAIN_MAPPING, LEFT_MAPPING, RIGHT_MAPPING);
  }

  private MSorter createNewMSorter(FragmentContext context, List<Ordering> orderings, VectorAccessible batch, MappingSet mainMapping, MappingSet leftMapping, MappingSet rightMapping)
          throws ClassTransformationException, IOException, SchemaChangeException{
    CodeGenerator<MSorter> cg = CodeGenerator.get(MSorter.TEMPLATE_DEFINITION, context.getFunctionRegistry());
    ClassGenerator<MSorter> g = cg.getRoot();
    g.setMappingSet(mainMapping);

    for(Ordering od : orderings){
      // first, we rewrite the evaluation stack for each side of the comparison.
      ErrorCollector collector = new ErrorCollectorImpl();
      final LogicalExpression expr = ExpressionTreeMaterializer.materialize(od.getExpr(), batch, collector, context.getFunctionRegistry());
      if(collector.hasErrors()) throw new SchemaChangeException("Failure while materializing expression. " + collector.toErrorString());
      g.setMappingSet(leftMapping);
      HoldingContainer left = g.addExpr(expr, false);
      g.setMappingSet(rightMapping);
      HoldingContainer right = g.addExpr(expr, false);
      g.setMappingSet(mainMapping);

      // next we wrap the two comparison sides and add the expression block for the comparison.
      LogicalExpression fh = FunctionGenerationHelper.getComparator(left, right, context.getFunctionRegistry());
      HoldingContainer out = g.addExpr(fh, false);
      JConditional jc = g.getEvalBlock()._if(out.getValue().ne(JExpr.lit(0)));

      if(od.getDirection() == Direction.ASCENDING){
        jc._then()._return(out.getValue());
      }else{
        jc._then()._return(out.getValue().minus());
      }
      g.rotateBlock();
    }

    g.rotateBlock();
    g.getEvalBlock()._return(JExpr.lit(0));

    return context.getImplementationClass(cg);

  }

  public SingleBatchSorter createNewSorter(FragmentContext context, VectorAccessible batch)
          throws ClassTransformationException, IOException, SchemaChangeException{
    CodeGenerator<SingleBatchSorter> cg = CodeGenerator.get(SingleBatchSorter.TEMPLATE_DEFINITION, context.getFunctionRegistry());
    ClassGenerator<SingleBatchSorter> g = cg.getRoot();

    generateComparisons(g, batch);

    return context.getImplementationClass(cg);
  }

  private void generateComparisons(ClassGenerator g, VectorAccessible batch) throws SchemaChangeException {
    g.setMappingSet(MAIN_MAPPING);

    for(Ordering od : popConfig.getOrderings()){
      // first, we rewrite the evaluation stack for each side of the comparison.
      ErrorCollector collector = new ErrorCollectorImpl();
      final LogicalExpression expr = ExpressionTreeMaterializer.materialize(od.getExpr(), batch, collector,context.getFunctionRegistry());
      if(collector.hasErrors()) throw new SchemaChangeException("Failure while materializing expression. " + collector.toErrorString());
      g.setMappingSet(LEFT_MAPPING);
      HoldingContainer left = g.addExpr(expr, false);
      g.setMappingSet(RIGHT_MAPPING);
      HoldingContainer right = g.addExpr(expr, false);
      g.setMappingSet(MAIN_MAPPING);

      // next we wrap the two comparison sides and add the expression block for the comparison.
      LogicalExpression fh = FunctionGenerationHelper.getComparator(left, right, context.getFunctionRegistry());
      HoldingContainer out = g.addExpr(fh, false);
      JConditional jc = g.getEvalBlock()._if(out.getValue().ne(JExpr.lit(0)));

      if(od.getDirection() == Direction.ASCENDING){
        jc._then()._return(out.getValue());
      }else{
        jc._then()._return(out.getValue().minus());
      }
      g.rotateBlock();
    }

    g.rotateBlock();
    g.getEvalBlock()._return(JExpr.lit(0));
  }

  private void createCopier(VectorAccessible batch, List<BatchGroup> batchGroupList, VectorContainer outputContainer) throws SchemaChangeException {
    try {
      if (copier == null) {
        CodeGenerator<PriorityQueueCopier> cg = CodeGenerator.get(PriorityQueueCopier.TEMPLATE_DEFINITION, context.getFunctionRegistry());
        ClassGenerator<PriorityQueueCopier> g = cg.getRoot();

        generateComparisons(g, batch);

        g.setMappingSet(COPIER_MAPPING_SET);
        CopyUtil.generateCopies(g, batch, true);
        g.setMappingSet(MAIN_MAPPING);
        copier = context.getImplementationClass(cg);
      }

      List<VectorAllocator> allocators = Lists.newArrayList();
      for(VectorWrapper<?> i : batch){
        ValueVector v = TypeHelper.getNewVector(i.getField(), copierAllocator);
        outputContainer.add(v);
        allocators.add(VectorAllocator.getAllocator(v, 110));
      }
      copier.setup(context, copierAllocator, batch, batchGroupList, outputContainer, allocators);
    } catch (ClassTransformationException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public WritableBatch getWritableBatch() {
    throw new UnsupportedOperationException("A sort batch is not writable.");
  }

  @Override
  protected void killIncoming(boolean sendUpstream) {
    incoming.kill(sendUpstream);
  }

}


text:
module Tour
  # Picks the winning parent from the pair
  #
  # @param pop [Array]      population of individuals
  # @return    [Individual] the winning parent
  def self.pick_one(pop)
    pair = pick_two(pop)
    winner(*pair)
  end

  class << self
    private

    # Randomly picks to individuals from the population
    #
    # @param pop [Array]                 population of individuals
    # @return    [Individual, Indiviual] picked individuals
    def pick_two(pop)
      op1 = pop[rand(pop.size)]
      op2 = pop[rand(pop.size)]
      [op1, op2]
    end

    # Returns the parent with the best fitness, the minimum one
    #
    # @param ind1 [Individual] some individual
    # @param ind2 [Individual] some individual
    # @return     [Individual] the individual with best fitness
    def winner(ind1, ind2)
      (ind1 <=> ind2).zero? ? [ind1, ind2][rand(2)] : [ind1, ind2].min
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
package tw.com.ischool.fireflylite.exception;

public class DSAClientException extends RuntimeException {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

}


text:
class hyperclient::pending_get : public hyperclient::pending
{
    public:
        pending_get(hyperclient_returncode* status,
                    struct hyperclient_attribute** attrs,
                    size_t* attrs_sz);
        virtual ~pending_get() throw ();

    public:
        virtual hyperdex::network_msgtype request_type();
        virtual int64_t handle_response(hyperclient* cl,
                                        const po6::net::location& sender,
                                        std::auto_ptr<e::buffer> msg,
                                        hyperdex::network_msgtype type,
                                        hyperclient_returncode* status);

    private:
        pending_get(const pending_get& other);

    private:
        pending_get& operator = (const pending_get& rhs);

    private:
        hyperclient_attribute** m_attrs;
        size_t* m_attrs_sz;
};

#endif // hyperclient_pending_get_h_


text:
package nounou.elements.data

import nounou.elements.NNElement
import nounou.elements.layouts.NNDataLayout
import scala.collection.immutable.Vector
import nounou._
import nounou.elements.traits._
import breeze.linalg.{DenseVector => DV}
import nounou.elements.ranges.{SampleRange, SampleRangeValid, SampleRangeSpecifier}

/** Base class for data encoded as Int arrays, this is the main data element for an experiment,
  * whether it be electrophysiolgical or high-sampling-rate imaging.
  *
  * This object is mutable, to allow inheritance by [[nounou.elements.data.filters.NNDataFilter]].
  * For that class, output results may change, depending upon _parent changes.
  * Each trace of data must share the following variables:
  * sampling, start, length, xBits, absGain, absOffset, absUnit
  */
abstract class NNData extends NNElement
    with NNChannelsElement with NNDataScaleElement with NNDataTimingElement {

  override def toString(): String =
    s"NNData(${channelCount} ch, ${timing().segmentCount} seg, fs=${timing().sampleRate})"

  /** Provides a textual representation of the child hierarchy starting from this data object.
    * If multiple NNDataFilter objects (e.g. an [[nounou.elements.data.filters.NNDataFilterFIR]] object)
    * are chained after this data, this method will show the chained objects and their tree hierarchy.
    * @return
    */
  final def toStringChain(): String = {
    toString() + (if(getChildren.size!=0) {
      getChildren.map(p => "\n\\ " + p.toStringChain).reduce( _ + _ ).split("\n").flatMap( "\n     " + _ ).mkString.drop(1)
    } else {
      ""
    })
  }

  // <editor-fold defaultstate="collapsed" desc=" DataSource related ">

  private val _children = scala.collection.mutable.Set[NNData]()
  /**'''[NNData: data source]''' Adds a new child to this data source, which will be notified for changes.
    * Be sure to clear children if the children are to be garbage collected.*/
  def setChild(x: NNData): Unit = _children.+=(x)
  /**'''[NNData: data source]''' Adds new children to this data source, which will be notified for changes.
    * Be sure to clear children if the children are to be garbage collected.*/
  final def setChildren(xs: TraversableOnce[NNData]): Unit = xs.map( setChild(_) )
  /**'''[NNData: data source]''' Children of this data source which should be notified upon changes.*/
  def getChildren() = _children
  /**'''[NNData: data source]''' Clear all children of this data source.*/
  def clearChildren(): Unit = _children.clear()
  /**'''[NNData: data source]''' Clear specified child of this data source.*/
  def clearChild(x: NNData): Unit = _children.-=(x)
  /**'''[NNData: data source]''' Clear specified children of this data source.*/
  final def clearChildren(xs: TraversableOnce[NNData]): Unit = xs.map( clearChild(_) )

  /** '''__SHOULD OVERRIDE__''' especially by buffering functions
    * and display functions which have an internal state to update.
    * Always remember to start with super.changedData(), in order to
    * map to all children.
    */
  def changedData(): Unit = _children.map(_.changedData())
  /** '''__SHOULD OVERRIDE__''' especially by buffering functions
    * and display functions which have an internal state to update.
    * Always remember to start with super.changedData(Int), in order to
    * map to all children.
    */
  def changedData(channel: Int): Unit = _children.map(_.changedData(channel))
  /** '''__SHOULD OVERRIDE__''' especially by buffering functions
    * and display functions which have an internal state to update.
    * Always remember to start with super.changedData(Array[Int]), in order to
    * map to all children.
    */
  def changedData(channels: Array[Int]): Unit = _children.map(_.changedData(channels))
  /** '''__SHOULD OVERRIDE__''' especially by buffering functions
    * and display functions which have an internal state to update.
    * Covers sampleRate, segmentLengths, segmentEndTSs, segmentStartTSs, segmentCount
    * Always remember to start with super.changedTiming(), in order to
    * map to all children.
    */
  def changedTiming(): Unit = _children.map(_.changedTiming())
  /** '''__SHOULD OVERRIDE__'''  especially by buffering functions
    * and display functions which have an internal state to update.
    * Always remember to start with super.changedLayout(), in order to
    * map to all children.
    */
  def changedLayout(): Unit = _children.map(_.changedLayout())

  // </editor-fold>

  // <editor-fold defaultstate="collapsed" desc=" NNLayout, channel count ">

  private var varLayout: NNDataLayout = null
  final def layout(): NNDataLayout = getLayout()
  def getLayout(): NNDataLayout = varLayout
  def setLayout(layout: NNDataLayout): Unit = {
    loggerRequire( layout.channelCount == this.channelCount(),
      s"Channel count ${layout.channelCount} of new layout does not match channel count ${this.channelCount()} for ${this.getClass.toString}" )
  }

  // </editor-fold>

  // <editor-fold defaultstate="collapsed" desc=" readXXX ">

  //<editor-fold defaultstate="collapsed" desc="reading a point">

  /** Read a single point from the data, in internal integer scaling, after checking values.
    * Implement via readPointImpl. Prefer
    * [[nounou.elements.data.NNData.readTraceDV(channel:Int,range* readTraceDV]]
    * and readFrame()
    * when possible, as these will avoid repeated function calling overhead.
    */
  def readPoint(channel: Int, frame: Int, segment: Int /*optSegment: OptSegment*/): Int = {
    val realSegment = timing.getRealSegment(segment)
    loggerRequire( timing.isRealisticFrsg(frame, realSegment), s"Unrealistic frame/segment: ${frame}/${segment})" )
    loggerRequire(isValidChannel(channel), s"Invalid channel: " + channel.toString)

    if( timing.isValidFrsg(frame, realSegment) ) readPointImpl(channel, frame, realSegment)
    else 0
  }
  final def readPoint(channel: Int, frame: Int): Int = readPoint(channel, frame, -1)

  // <editor-fold defaultstate="collapsed" desc=" convenience readPoint variations ">

  /** [[nounou.elements.data.NNData.readPoint(channel:Int,frame:Int,segment:Int)* readPoint]] but in physical units.
    */
  final def readPointAbs(channel: Int, frame: Int, segment: Int): Double = scale.convertIntToAbsolute( readPoint(channel, frame, segment) )
  //final def readPointAbs(channel: Int, frame: Int, optSegment: OptSegment): Double = convertINTtoABS( readPoint(channel, frame, optSegment) )
  /** [[nounou.elements.data.NNData.readPoint(channel:Int,frame:Int)* readPoint]]
    * but in physical units.
    */
  final def readPointAbs(channel: Int, frame: Int): Double = readPointAbs(channel, frame, -1)//OptSegmentAutomatic)

  // </editor-fold>

  //</editor-fold>

  /** '''__MUST OVERRIDE__''' Read a single point from the data, in internal integer scaling.
    * Assumes that channel, frame, and segment are all valid and within range.
    */
  def readPointImpl(channel: Int, frame: Int, segment: Int): Int

  //<editor-fold defaultstate="collapsed" desc="reading a trace">

  /** '''__CAN OVERRIDE__''' Read a single trace from the data, in internal integer scaling.
    */
  def readTraceDV(channel: Int, range: SampleRangeSpecifier): DV[Int] = {

    loggerRequire(isValidChannel(channel), "Invalid channel: " + channel.toString)

    range match {
      case ran: SampleRangeValid => readTraceDVImpl(channel, ran)
      case _ => {
        loggerRequire(timing.isRealisticRange(range), "Unrealistic frame/segment: " + range.toString)
        val preValidPost = range.getSampleRangeValidPrePost(this)
        readTraceDVPVPImpl(channel, preValidPost)
      }
    }

  }
  /** '''__CAN OVERRIDE__''' by default, calls
    * [[nounou.elements.data.NNData.readTraceDV(channel:Int,range* readTraceDV ]]
    */
  def readTraceDV(channels: Array[Int],  range: SampleRangeSpecifier): Array[DV[Int]] = {
    val preValidPost = range.getSampleRangeValidPrePost(this)
    channels.map( readTraceDVPVPImpl(_, preValidPost) )
  }

  private final def readTraceDVPVPImpl(channel: Int, preValidPost: (Int, SampleRangeValid, Int)): DV[Int] = {
    val validTrace = readTraceDVImpl(channel, preValidPost._2)
    preValidPost match {
      case (0, rfv, 0) => validTrace
      case (pre, rfv, 0) => DV.vertcat(DV.zeros[Int](pre), validTrace)
      case (0, rfv, post) => DV.vertcat(validTrace, DV.zeros[Int](post))
      case (pre, rfv, post) => DV.vertcat(DV.zeros[Int](pre), validTrace, DV.zeros[Int](post))
    }
  }

  // <editor-fold defaultstate="collapsed" desc=" convenience readTrace variations ">

  /**Internal implementation for [[nounou.elements.data.NNData.readTrace(channel:Int)* readTrace]]
    * to return a breeze.linalg.DenseVector.
    */
  final def readTraceDV(channel: Int): DV[Int] = readTraceDV(channel, NN.SampleRangeAll())

  final def readTraceAbsDV(channel: Int): DV[Double]
    = scale.convertIntToAbsolute(readTraceDV(channel))
  /** Read a single trace in absolute unit scaling (as recorded).*/
  final def readTraceAbsDV(channel: Int,         range: SampleRangeSpecifier): DV[Double]
    = scale.convertIntToAbsolute(readTraceDV(channel, range))
  /** Read multiple traces in absolute unit scaling (as recorded).*/
  final def readTraceAbsDV(channels: Array[Int], range: SampleRangeSpecifier): Array[DV[Double]]
    = readTraceDV(channels, range).map( scale.convertIntToAbsolute(_) )

  /** Read a single trace (whole range) in internal integer scaling.
    * This should only be used for data with only 1 segment.
    */
  final def readTrace(channel: Int) =
                          readTraceDV(channel).toArray
  final def readTrace(channel: Int,           range: SampleRangeSpecifier) =
                          readTraceDV(channel, range).toArray
  final def readTrace(channels: Array[Int],   range: SampleRangeSpecifier): Array[Array[Int]] =
                          readTraceDV(channels, range).map(_.toArray)
  final def readTrace(channel: Int,           range: Array[Int]): Array[Int] =
                          readTrace(channel, NN.SampleRange(range))
  final def readTrace(channel: Int,           range: Array[Int], segment: Int): Array[Int] =
                          readTrace(channel, NN.SampleRange(range, segment))
//  final def readTraceA(channels: Array[Int], range: Array[Int]): Array[Array[Int]] =           readTraceA(channels, convertARRtoRANGE(range))

  /** Read a single trace in absolute unit scaling (as recorded).
    * This should only be used for data with only 1 segment.
    */
  final def readTraceAbs(channel: Int): Array[Double] = readTraceAbsDV(channel).toArray
  final def readTraceAbs(channel: Int,         range: SampleRangeSpecifier): Array[Double] =
      readTraceAbsDV(channel, range).toArray
//  final def readTraceAbsA(channels: Array[Int], range: SampleRangeSpecifier): Array[Array[Double]] =         readTraceAbs(channels, range).map(_.toArray)
  final def readTraceAbs(channel: Int,         range: Array[Int], segment: Int): Array[Double] =
      readTraceAbs(channel, SampleRange.convertArrayToSampleRange(range, segment) )
  final def readTraceAbs(channel: Int,         range: Array[Int]): Array[Double] =
      readTraceAbs(channel, SampleRange.convertArrayToSampleRange(range, -1) )
//  final def readTraceAbsA(channels: Array[Int], range: Array[Int]): Array[Array[Double]] =         readTraceAbsA(channels, convertARRtoRANGE(range))

  //</editor-fold>

  /** CAN OVERRIDE: Read a single data trace from the data, in internal integer scaling.
    * Should return a defensive clone. Assumes that channel and range are within the data range!
    */
  def readTraceDVImpl(channel: Int, rangeFrValid: SampleRangeValid/*range: Range.Inclusive, segment: Int*/): DV[Int] = {
    val res = DV.zeros[Int]( rangeFrValid.length )
    nounou.util.forJava(rangeFrValid.start, rangeFrValid.last + 1, rangeFrValid.step, (c: Int) => (res(c) = readPointImpl(channel, c, rangeFrValid.segment)))
    res
  }

//  //<editor-fold defaultstate="collapsed" desc="reading a frame">
//
//  /** Read a single frame from the data, in internal integer scaling, for just the specified channels.
//    */
//  final def readFrame(frame: Int, channels: Array[Int], segment: Int): DV[Int] = {
//    loggerRequire(isRealisticFr(frame/*, segment*/), "Unrealistic frame/segment: " + (frame, segment).toString)
//    loggerRequire(channels.forall(isValidChannel), "Invalid channels: " + channels.toString)
//
//    if( isValidFr(frame/*, segment*/) ) readFrameImpl(frame, channels/*, segment*//*(currentSegment = segment)*/ ) else DV.zeros[Int]( channels.length )
//
//  }
//
//  /** Read a single frame from the data, in internal integer scaling.
//    */
//  final def readFrame(frame: Int, segment: Int): DV[Int] = {
//    loggerRequire(isRealisticFr(frame, segment), "Unrealistic frame/segment: " + (frame, segment).toString)
//    if( isValidFr(frame, segment) ) readFrameImpl(frame , segment ((currentSegment = segment)*/ ) else DV.zeros[Int]( channelCount )
//  }
////  final def readFrame(frame: Int): DV[Int] = readFrame(frame, 0)
//
//  final def readFrameA(frame: Int): Array[Int] = readFrame(frame).toArray
//  final def readFrameA(frame: Int, segment: Int): Array[Int] = readFrame(frame/*, segment*/).toArray
//  final def readFrameA(frame: Int, channels: Array[Int], segment: Int): Array[Int] = readFrame(frame, channels, segment).toArray
//
//  //</editor-fold>
//
//  /** CAN OVERRIDE: Read a single frame from the data, in internal integer scaling.
//    * Should return a defensive clone. Assumes that frame is within the data range!
//    */
//  def readFrameImpl(frame: Int): DV[Int] = {
//    val res = DV.zeros[Int](channelCount)
//    nounou.util.forJava(0, channelCount, 1, (channel: Int) => res(channel) = readPointImpl(channel, frame))
//    res
//  }
//  /** CAN OVERRIDE: Read a single frame from the data, for just the specified channels, in internal integer scaling.
//    * Should return a defensive clone. Assumes that frame and channels are within the data range!
//    */
//  def readFrameImpl(frame: Int, channels: Array[Int]): DV[Int] = {
//    val res = DV.zeros[Int]( channels.length )
//    nounou.util.forJava(0, channels.length, 1, (channel: Int) => res(channel) = readPointImpl(channel, frame))
//    res
//  }
//
//  // </editor-fold>

  // </editor-fold>

  override def isCompatible(that: NNElement): Boolean = {
    that match {
      case x: NNData => {
        (timing().isCompatible(x.timing())) && scale().isCompatible(x.scale())
        //&& this.layout.isCompatible(x.layout)
        //not channel info
      }
      case _ => false
    }
  }

//  override def :::(x: NNElement): NNData

}

///** Immutable version of XData.
//  *
//  * Must override the following:
//  * +  def readPointImpl(channel: Int, frame: Int, segment: Int): Int
//  * +  (from XFramesImmutable)
//  * ++   val segmentCount: Int
//  * ++   val length: : Vector[Int]
//  * ++   val segmentStartTSs: Vector[Long]
//  * ++   val sampleRate: Double
//  * +  (from XChannelsImmutable)
//  * ++   val channelNames: Vector[String]
//  * +  (from XAbsoluteImmutable)
//  * ++   val absGain: Double
//  * ++   val absOffset: Double
//  * ++   val absUnit: String
//  *
//  * Can override the following:
//  * +   def readTraceImpl(channel: Int, segment: Int): Vector[Int]
//  * +   def readTraceImpl(channel: Int, span:Span, segment: Int): Vector[Int]
//  * +   def readFrameImpl(frame: Int, segment: Int): Vector[Int]
//  * +   def readFrameImpl(frame: Int, channels: Vector[Int], segment: Int): Vector[Int]
//  * +  (from XAbsoluteImmutable)
//  * ++   val xBits: Int = 1024
//  */
//abstract class XDataImmutable extends XData with XFramesImmutable with XChannelsImmutable with XAbsoluteImmutable {
//
//
//  //ToDo 4: channelNames as lazy val?
//
//  // <editor-fold defaultstate="collapsed" desc=" DataSource related ">
//
//  override def changedData(): Unit = logger.error("this is an immutable data source, and changedData() should not be invoked!")
//  override def changedData(channel: Int): Unit = logger.error("this is an immutable data source, and changedData() should not be invoked!")
//  override def changedData(channels: Vector[Int]): Unit = logger.error("this is an immutable data source, and changedData() should not be invoked!")
//  override def changedTiming(): Unit = logger.error("this is an immutable data source, and changedTiming() should not be invoked!")
//
//  // </editor-fold>
//
//}

//
//class NNDataNull$ extends NNData {
//  override def readPointImpl(channel: Int, frame: Int, segment: Int): Int = 0
//  override val absGain: Double = 1D
//  override val absOffset: Double = 0D
//  override val absUnit: String = "Null unit"
//  override val scaleMax: Int = 0
//  override val scaleMin: Int = 0
//  override def segmentLengthImpl(segment: Int): Int = 0
//  override val segmentStartTs: Array[Long] = Array[Long]()
//  override val sampleRate: Double = 1d
////  override val layout: NNLayout = NNLayoutNull
//
//
//  override def :::(x: NNElement): NNData = x match {
//    case NNDataNull => this
//    case xData: NNData => xData
//    case xDataChannel: NNDataChannel => new NNDataChannelArray( Vector(xDataChannel) )
//    case _ => require(false, "cannot append incompatible data types (XDataNull)"); this
//  }
//  override def toString() = "XDataNull()"
//
//  override val segmentCount: Int = 0
//  override val channelCount: Int = 0
//
//  /** OVERRIDE: End timestamp for each segment. Implement by overriding _endTimestamp
//    */
//  override val segmentEndTs: Array[Long] = Array[Long]()
//}
//
//object NNDataNull extends NNDataNull$
//
//
//class NNDataAuxNull extends NNDataNull$ with NNDataAux {
//
//  override def :::(x: NNElement): NNDataAux = x match {
//    case xDataAux: NNDataAux => xDataAux
//    case _ => require(false, "cannot append incompatible data types (XDataAuxNull)"); this
//  }
//  override def toString() = "XDataAuxNull()"
//}
//
//object NNDataAuxNull extends NNDataAuxNull


text:
/***********************************************************************
*
* File: TestParamsIO.java
*
* Author:  mdittmar                                Created: 2010-12-23
*
* Virtual Astrophysical Observatory; contributed by Center for Astrophysics
*
* Update History:
*   2010-12-23:  MCD  Create
*
***********************************************************************/

package cfa.vo.sedlib;

import junit.framework.Test;
import junit.framework.TestSuite;

import cfa.vo.sedlib.io.SedFormat;

import java.util.List;
import java.util.HashMap;

/**
   Tests Sedlib ability to create, read and write the Params objects
*/

public class TestParamsIO extends SedTestBase
{
    Sed m_sed = null;
    String m_fname = null;
    boolean keep = true;
    int rc = 1;

    public TestParamsIO( String name )
    {
	super(name);
    }

    public static Test suite()
    {
	TestSuite suite = new TestSuite( TestParamsIO.class );

	return suite;
    }

    /**
     *  Preparatory steps to be executed before each test.
     */
    protected void setUp()
    {
    }

    /**
     *  Cleanup steps to be executed after each test.
     */
    protected void tearDown()
    {
	m_sed = null;
	m_fname = null;
	rc = 1;
    }

    /**
     *  Tests ability to create and serialize Param objects
     *

     *  Create a new List of Param objects which are fully defined
     *  and populated with values.  Write this object out in
     *  each of the supported formats.
     */
    public void testParams_new()
    {
	String testName = "testParams_new";
	System.out.println("   run "+testName+"()");

	/* Create SED with one (empty) segment */
	m_sed = EmptyObjects.createSED( 1 );

	/* Get the Segment */
	Segment segment = m_sed.getSegment(0);
	assertNotNull( "Failed to create SEGMENT: " , segment );

	/* Create a List of Point objects with values..  */
	/* Assign to Segment                                 */
	segment.setCustomParams( CompleteObjects.createParams() );

	/* Write SED with Params to file in each of the supported formats */
	for (SedFormat format : SedFormat.values())
	{
	    if (format == SedFormat.XML)
		continue;

	    m_fname = "Params." + format.exten();
	    rc = writeSED( format , tu.mkOutFileName( m_fname ), m_sed );
	    assertEquals( testName + ": Failed to write " + m_fname, 0, rc );

	    /* Compare output file with baseline */
	    if ( format == SedFormat.FITS )
		rc = tu.diffFits( m_fname );
	    else
		rc = tu.DIFFIT( m_fname );

	    assertEquals( testName + ": Diff failed - " + m_fname, 0, rc );
	    if ( (rc == 0 ) && (!keep) )
		tu.cleanupFiles( m_fname );
	}
    }

    /**
     *  Tests Param object's getCastValue() behavior.
     *

     *  Load file containing a fully defined Params object,
     *  extract values using getCastValue method and compare to
     *  known values.
     */
    public void testParams_getCast()
    {
	String testName = "testParams_getCast";
		System.out.println("   run "+testName+"()");

	SedFormat format = SedFormat.VOT;
	m_fname = "Params." + format.exten();

	/* Read input file */
	m_sed = readSED( format, tu.mkInFileName( m_fname ) );
	assertNotNull( testName + ": Document load failed - " + m_fname, m_sed );

	/* Set up expected value list */
	HashMap<String,String> goodVals = new HashMap<String,String>();
	goodVals.put( "pi", "3.14159" );
	goodVals.put( "baddbl1", "NaN" );
	goodVals.put( "baddbl2", "NaN" );
	goodVals.put( "baddbl3", "NaN" );
	goodVals.put( "baddbl4", "NaN" );
	goodVals.put( "daysofweek", "7" );
	goodVals.put( "TargetType", "Galaxy" );
	goodVals.put( "camdate", "2011-01-04T22:01:59" );
	goodVals.put( "age", "1.8" );
	goodVals.put( "TargetPosA", "233.737917" );
	goodVals.put( "TargetPosB", "23.50333" );

	List<? extends Param> params;
	String strval;
	String pname;
	String suffix = "A";

	/* Get params list from segment */
	params = m_sed.getSegment(0).getCustomParams();

	rc = 0;
        for (int ii=0; ii<params.size(); ii++)
	{
	    pname = params.get(ii).getName();

	    if ( pname.equals("TargetPos") )
	    {
		/* there are 2 of them.. need to separate */
		pname = pname.concat( suffix );
		suffix = "B";
	    }

            strval = params.get(ii).getCastValue().toString();
	    if ( ! strval.equals( goodVals.get( pname ) ) )
		rc = 1;

	    assertEquals( testName + ": Param " + pname + " Failed Value check.", 0, rc );
        }

    }

    /**
     *  Tests ability to load Params objects from VOT format
     *

     *  Load file containing a fully defined Params object
     *  and write the object back out in the same format.
     *  If all information is extracted properly, the output file
     *  should identically match the input.
     */
    public void testParams_copyVOT()
    {
	String testName = "testParams_copyVOT";
		System.out.println("   run "+testName+"()");

	SedFormat format = SedFormat.VOT;
	String outFileName = "Params2."+format.exten ();
	m_fname = "Params." + format.exten();

	/* Read input file */
	m_sed = readSED( format, tu.mkInFileName( m_fname ) );
	assertNotNull( testName + ": Document load failed - " + m_fname, m_sed );

	/* Write back out.. same format */
	rc = writeSED( format , tu.mkOutFileName( outFileName ), m_sed );
	assertEquals( testName + ": Failed to write " + outFileName, 0, rc );

	rc = tu.DIFFIT( outFileName );
	assertEquals( testName + ": Diff failed - " + outFileName, 0, rc );

	if ( (rc == 0 ) && (!keep) )
	    tu.cleanupFiles( outFileName );
    }

    /**
     *  Tests ability to load Params objects from FITS format
     *

     *  Load file containing a fully defined Params object
     *  and write the object back out in the same format.
     *  If all information is extracted properly, the output file
     *  should identically match the input.
     */
    public void testParams_copyFITS()
    {
	String testName = "testParams_copyFITS";
	System.out.println("   run "+testName+"()");

	SedFormat format = SedFormat.FITS;
	m_fname = "Params." + format.exten();

	/* Read input file */
	m_sed = readSED( format, tu.mkInFileName( m_fname ) );
	assertNotNull( testName + ": Document load failed - " + m_fname, m_sed );

	/* Write back out.. same format */
	m_fname = "Params_copy." + format.exten();
	rc = writeSED( format , tu.mkOutFileName( m_fname ), m_sed );
	assertEquals( testName + ": Failed to write " + m_fname, 0, rc );

	rc = tu.diffFits( m_fname );
	assertEquals( testName + ": Diff failed - " + m_fname, 0, rc );

	if ( (rc == 0 ) && (!keep) )
	    tu.cleanupFiles( m_fname );
    }

    /**
     *  Tests ability to load Params objects from XML format
     *

     *  Load file containing a fully defined Params object
     *  and write the object back out in the same format.
     *  If all information is extracted properly, the output file
     *  should identically match the input.
     */
    public void estParams_copyXML()
    {
	String testName = "testParams_copyXML";
	System.out.println("   run "+testName+"()");

	SedFormat format = SedFormat.XML;
	m_fname = "Params." + format.exten();

	/* Read input file */
	m_sed = readSED( format, tu.mkInFileName( m_fname ) );
	assertNotNull( testName + ": Document load failed - " + m_fname, m_sed );

	/* Write back out.. same format */
	rc = writeSED( format , tu.mkOutFileName( m_fname ), m_sed );
	assertEquals( testName + ": Failed to write " + m_fname, 0, rc );

	rc = tu.DIFFIT( m_fname );
	assertEquals( testName + ": Diff failed - " + m_fname, 0, rc );

	if ( (rc == 0 ) && (!keep) )
	    tu.cleanupFiles( m_fname );
    }

}


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Blog Archive</title>

    <meta name="description" content="Website of Henry Lin">

    <meta name="author" content="Henry Lin">
    <link rel="author" href="/">
    <link href="http://www.hlin.co/blog/" rel="canonical">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="alternate" type="application/rss+xml" title="Henry Lin" href="http://www.hlin.co/feed.xml">

    <link type="text/css" rel="stylesheet" href="/assets/application.css">

About

Blog

hlin.co

A Noble Aim

      08 Sep 2017
      Jordan B. Peterson speaking in the Introduction to the Idea of God: Have a noble aim. Otherwise you have nothing but shallow, trivial pleasures. And they won't sustain you. And that's not good. Because life is so difficult, so much suffering, so...

Maxwell

      19 May 2017
      Maxwell is my one year old boy. He instills way more meaning to the things I enjoy and also to the things I don't - like maybe the Wiggles are okay. To Max: I hope you've had fun so far. Both mum...

Create RSS Feeds

      18 Jul 2016
      I love RSS. It is one of the best ways for websites to notify me of significant content updates. Sadly not all websites provide this where it could be of high value. This means the author is either not aware or does...

Hawai'i

      31 Aug 2015
      I went to Hawai'i in the spring of 2015 for 3 weeks and these are the things I tried and would recommend. Honolulu Steak Shack serves steaks and chicken on rice. With outside seating looking out to the gorgeous Waikiki bay, eating...

Singularity Outcomes

      02 Apr 2015
      Elon Musk on AI: "Hope we're not just the biological boot loader for digital superintelligence. Unfortunately, that is increasingly probable." Elon's comment got me thinking about the likely outcomes for us when a general AI becomes more intelligent than the humans that...

Emoji Bonanza

      27 Mar 2015
      You can find more iOS native emojis from the Chinese (Simplified) - Pinyin keyboard. Access is then through this new keyboard in the symbol section (much like the way you get to the '=' character). There is an extensive collection of unicode...

Ghost City of Ordos

      20 Mar 2015
      "Over the course of our 24 hours in Ordos, we had tried every door within reach – and not one of them had been locked." I love well documented travel writing. @DarmonRichter's piece on the ghost city of Ordos encourages a level...

Alzheimer's Disease

      12 Mar 2015
      When my grandfather died of cancer, it wasn't the ravages of the cancer that horrified me the most. It was the fact that Alzheimer's Disease had already quietly stolen the last oppurtunity for me to be meaningfully there for him. It erroded...

Illustrations by Gediminas Pranckevičius

      09 Mar 2015
      These illustrations from Gediminas Pranckevičius remind me of the personal myths & reflections of Carl Jung.

A combination of the surreal and a sense of shared archetypes makes a compelling work of art.

Guide To Autodidactism

      05 Mar 2015
      @JackKinsella in Guide To Autodidactism Learning learning strategies should be treated as equally fundamental in our schools, yet it isn't. My schooling reality starkly differed, in that the powers that were deemed it preferable to dedicate an hour a day during our...

        © Henry Lin 2017.


text:
namespace Bond.Comm
{
    /// <summary>
    /// Interface for layer stacks. The layer stack encapsulates
    /// a list of layers which work together over the same layer data.
    /// </summary>
    public interface ILayerStack
    {
        /// <summary>
        /// Take action on sending of a message, by invoking a stack of layers (in forward order).
        /// </summary>
        /// <param name="messageType">The type of message</param>
        /// <param name="context">The send context. May not be null.</param>
        /// <param name="layerData">The layer data for this layer, provided as an instance in an <see cref="IBonded"/> ready to be serialized</param>
        /// <param name="logger">The logger</param>
        /// <returns>An error, or null if there is no error.</returns>
        /// <remarks>
        /// In general, the layer is not expected to interact with the message payload itself.
        /// </remarks>
        Error OnSend(MessageType messageType, SendContext context, out IBonded layerData, Logger logger);

        /// <summary>
        /// Take action on receipt of a message, by invoking a stack of layers (in reverse order).
        /// </summary>
        /// <param name="messageType">The type of message</param>
        /// <param name="context">The receive context. May not be null.</param>
        /// <param name="layerData">The layer data for this layer, provided as an <see cref="IBonded"/> to be deserialized</param>
        /// <param name="logger">The logger</param>
        /// <returns>An error, or null if there is no error.</returns>
        /// <remarks>
        /// In general, the layer is not expected to interact with the message payload itself.
        /// </remarks>
        Error OnReceive(MessageType messageType, ReceiveContext context, IBonded layerData, Logger logger);
    }

    /// <summary>
    /// Interface for layer stack provider. The layer stack provider contains a set of layer stack
    /// providers. The layer stack provider is expected to return a new layer stack instance each
    /// time <c>GetLayerStack</c> is invoked unless all the layers are stateless, in which case it
    /// may provide a cached layer stack instance.
    /// </summary>
    public interface ILayerStackProvider
    {
        /// <summary>
        /// Provide a layer stack instance.
        /// </summary>
        /// <param name="uniqueId">A unique ID identifying the request or connection that triggered this call. Used in
        /// layer-originated errors.</param>
        /// <param name="stack">The layer stack instance. May be null if an error occurred.</param>
        /// <param name="logger">The logger</param>
        /// <returns>An error, or null if there is no error.</returns>
        Error GetLayerStack(string uniqueId, out ILayerStack stack, Logger logger);
    }
}


text:
package io.scalajs.nodejs.https

import scala.scalajs.js

/**
  * Server Options
  * @param host         A domain name or IP address of the server to issue the request to. Defaults to 'localhost'.
  * @param hostname     Alias for host. To support url.parse() hostname is preferred over host.
  * @param family       IP address family to use when resolving host and hostname. Valid values are 4 or 6. When
  *                     unspecified, both IP v4 and v6 will be used.
  * @param port         Port of remote server. Defaults to 443.
  * @param localAddress Local interface to bind for network connections.
  * @param socketPath   Unix Domain Socket (use one of host:port or socketPath).
  * @param method       A string specifying the HTTP request method. Defaults to 'GET'.
  * @param path         Request path. Defaults to '/'. Should include query string if any. E.G. '/index.html?page=12'.
  *                     An exception is thrown when the request path contains illegal characters. Currently, only spaces
  *                     are rejected but that may change in the future.
  * @param headers      An object containing request headers.
  * @param auth         Basic authentication i.e. 'user:password' to compute an Authorization header.
  * @param agent        Controls Agent behavior. When an Agent is used request will default to Connection: keep-alive.
  *                     Possible values:
  *

  *
undefined (default): use globalAgent for this host and port.

  *
Agent object: explicitly use the passed in Agent.

  *
false: opts out of connection pooling with an Agent, defaults request to Connection: close.

  *

  * @author lawrence.daniels@gmail.com
  */

class ServerOptions(var host: js.UndefOr[String] = js.undefined,
                    var hostname: js.UndefOr[String] = js.undefined,
                    var family: js.UndefOr[String] = js.undefined,
                    var port: js.UndefOr[Int] = js.undefined,
                    var localAddress: js.UndefOr[String] = js.undefined,
                    var socketPath: js.UndefOr[String] = js.undefined,
                    var method: js.UndefOr[String] = js.undefined,
                    var path: js.UndefOr[String] = js.undefined,
                    var headers: js.UndefOr[js.Dictionary[String]] = js.undefined,
                    var auth: js.UndefOr[js.Dictionary[String]] = js.undefined,
                    var agent: js.UndefOr[String] = js.undefined)
    extends js.Object


text:
@interface GWPlaceholderTextView : UITextView
@property (nonatomic, copy) NSString *placeholder;
@property (nonatomic, strong) UIColor *placeholderColor;
@end


text:
require 'spec_helper'

describe PoiseApplication::AppMixin do
  describe '#app_state_environment' do
    resource(:mixin_test) do
      include described_class
    end
    provider(:mixin_test) do
      include described_class
      def action_run
        new_resource.app_state_environment[:key] = new_resource.name
      end
    end
    recipe do
      application '/srv/mixintest' do
        mixin_test 'one'
        mixin_test 'two'
      end
    end

    it { is_expected.to deploy_application('/srv/mixintest').with(app_state: {'environment' => {'key' => 'two'}}) }

    context 'with no parent' do
      recipe do
        mixin_test 'one'
        mixin_test 'two'
      end

      it { is_expected.to run_mixin_test('one').with(app_state: {'environment' => {'key' => 'one'}}) }
      it { is_expected.to run_mixin_test('two').with(app_state: {'environment' => {'key' => 'two'}}) }
    end # /context with no parent
  end # /describe #app_state_environment
end


text:
#ifndef TENSORFLOW_COMPILER_XLA_SERVICE_GPU_IR_EMISSION_UTILS_H_
#define TENSORFLOW_COMPILER_XLA_SERVICE_GPU_IR_EMISSION_UTILS_H_

#include <utility>

#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Value.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"

// TODO(jlebar): Move functions related to cublas/cudnn to a separate file; they
// don't belong in "ir_emission_utils".

namespace xla {
namespace gpu {

constexpr int64 kWarpSize = 32;

// Returns true if `hlo` will be implemented as a call to BLAS gemm.
bool ImplementedAsGemm(const HloInstruction& hlo);

// A call to cuDNN for batch normalization is represented as CustomCall HLO with
// a call target equal to one of these strings.
//
// The operands to and outputs of these calls are the same as those of the
// corresponding HLOs, except:
//
//  - epsilon and feature_index are proper operands, at the end of the operands
//    list.  They must be HLO constants.
//  - The cuDNN forward training call returns inv_stddev =
//    1/sqrt(variance + epsilon) in place of plain variance.
//  - Similarly, BatchNormGrad accepts inv_stddev in place of the variance
//    operand.
extern const char* const kCudnnBatchNormForwardInferenceCallTarget;
extern const char* const kCudnnBatchNormForwardTrainingCallTarget;
extern const char* const kCudnnBatchNormBackwardCallTarget;

// Returns true if `hlo` will be implemented as a call to a cuDNN batch
// normalization routine.
//
// This returns true if `hlo` is a CustomCall HLO with a call target equal to
// one of the kCudnnBatchNormFoo constants above, but returns *false* for HLOs
// with one of the kBatchNorm opcodes, because these are lowered either to a
// sequence of generic HLOs or to a cuDNN CustomCall.
bool IsCustomCallToDnnBatchNorm(const HloInstruction& hlo);

// A call to cuDNN for convolution (forward, backward filter, or backward input)
// is represented as a CustomCall HLO with a call target equal to one of these
// strings.
//
// These CustomCalls have window() and convolution_dimension_numbers() set like
// regular convolution ops.  They have the same LHS and RHS operands, plus two
// additional constant operands: an int64 operand for the cudnn algorithm and
// a bool operand for whether tensor_ops is enabled. A value of -1 for the cudnn
// algorithm means that the implementation is free to choose the best algorithm
// it can.
//
// These calls output a tuple (conv_result, scratch_memory), where conv_result
// is the actual result of the convolution, and scratch_memory is temporary
// memory used by cudnn.  Callers shouldn't inspect scratch_memory, as its value
// is not well-defined.
//
// CudnnConvolutionRewriter lowers kConvolution HLOs to these custom calls.
// When it does so, it chooses algorithm -1 and 0 bytes of scratch space.  Later
// on in the pipeline, CudnnConvolutionAlgorithmChooser chooses an explicit
// algorithm for each conv and sets the amount of scratch space needed.
//
// (Representing the scratch memory as an output may seem strange at first, but
// it's quite sensible, from a certain point of view.  The scratch buffer is a
// location in memory that the conv can write into, but which it can't legally
// read from, at least until it's written something first.  But that's exactly
// the definition of an output buffer.)
extern const char* const kCudnnConvForwardCallTarget;
extern const char* const kCudnnConvBackwardInputCallTarget;
extern const char* const kCudnnConvBackwardFilterCallTarget;

// Returns true if `hlo` will be implemented as a call to a cuDNN convolution
// routine.
//
// This returns true if `hlo` is a CustomCall HLO with a call target equal to
// one of the kCudnnConvFoo constants above, but returns *false* for HLOs with a
// kConvolution opcode.
bool IsCustomCallToDnnConvolution(const HloInstruction& hlo);

// Creates a CustomCall for a cudnn forward/backward-input/backward-filter conv.
// Note that these CustomCalls return a tuple (conv_result, scratch_memory).  If
// you want just the conv result, you'll need to get-tuple-element the value
// returned by this function.
//
// The created cudnn call will use the default cudnn algorithm and no scratch
// space.
HloInstruction* CreateCudnnConvForward(
    const Shape& shape, HloInstruction* input, HloInstruction* kernel,
    const Window& window, const ConvolutionDimensionNumbers& dnums);
HloInstruction* CreateCudnnConvBackwardInput(
    const Shape& shape, HloInstruction* output, HloInstruction* reverse_filter,
    const Window& window, const ConvolutionDimensionNumbers& dnums);
HloInstruction* CreateCudnnConvBackwardFilter(
    const Shape& shape, HloInstruction* input, HloInstruction* output,
    const Window& window, const ConvolutionDimensionNumbers& dnums);

// Returns true if `hlo` will be implemented as a library call, e.g. cuBLAS gemm
// or cuDNN convolution.
bool ImplementedAsLibraryCall(const HloInstruction& hlo);

bool IsReductionToVector(const HloInstruction& reduce);

// Emits call to "vprintf" with given format and arguments.
llvm::Value* EmitPrintf(tensorflow::StringPiece fmt,
                        tensorflow::gtl::ArraySlice<llvm::Value*> arguments,
                        llvm::IRBuilder<>* builder);

// Emits code to shuffle data between threads of a warp. This has the same
// semantics as the PTX "shfl.down" instruction [0] but works for values of any
// size. The last operand of the emitted "shfl" is `kWarpSize - 1`.
//
// [0]
// http://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-shfl
llvm::Value* EmitShuffleDown(llvm::Value* value, llvm::Value* offset,
                             llvm::IRBuilder<>* builder);

}  // namespace gpu
}  // namespace xla

#endif  // TENSORFLOW_COMPILER_XLA_SERVICE_GPU_IR_EMISSION_UTILS_H_


text:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <winpr/crt.h>
#include <winpr/print.h>
#include <winpr/stream.h>

#include <freerdp/channels/log.h>

#include "rdpsnd_common.h"
#include "rdpsnd_main.h"

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
{
	size_t pos;
	UINT16 i;
	BOOL status = FALSE;
	ULONG written;
	Stream_Write_UINT8(s, SNDC_FORMATS);
	Stream_Write_UINT8(s, 0);
	Stream_Seek_UINT16(s);
	Stream_Write_UINT32(s, 0);                           /* dwFlags */
	Stream_Write_UINT32(s, 0);                           /* dwVolume */
	Stream_Write_UINT32(s, 0);                           /* dwPitch */
	Stream_Write_UINT16(s, 0);                           /* wDGramPort */
	Stream_Write_UINT16(s, context->num_server_formats); /* wNumberOfFormats */
	Stream_Write_UINT8(s, context->block_no);            /* cLastBlockConfirmed */
	Stream_Write_UINT16(s, CHANNEL_VERSION_WIN_MAX);     /* wVersion */
	Stream_Write_UINT8(s, 0);                            /* bPad */

	for (i = 0; i < context->num_server_formats; i++)
	{
		AUDIO_FORMAT format = context->server_formats[i];
		// TODO: Eliminate this!!!
		format.nAvgBytesPerSec =
		    format.nSamplesPerSec * format.nChannels * format.wBitsPerSample / 8;

		if (!audio_format_write(s, &format))
			goto fail;
	}

	pos = Stream_GetPosition(s);
	Stream_SetPosition(s, 2);
	Stream_Write_UINT16(s, pos - 4);
	Stream_SetPosition(s, pos);
	status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR)Stream_Buffer(s),
	                                Stream_GetPosition(s), &written);
	Stream_SetPosition(s, 0);
fail:
	return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream* s)
{
	UINT16 timestamp;
	BYTE confirmBlockNum;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enough data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, timestamp);
	Stream_Read_UINT8(s, confirmBlockNum);
	Stream_Seek_UINT8(s);
	IFCALLRET(context->ConfirmBlock, error, context, confirmBlockNum, timestamp);

	if (error)
		WLog_ERR(TAG, "context->ConfirmBlock failed with error %" PRIu32 "", error);

	return error;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_recv_quality_mode(RdpsndServerContext* context, wStream* s)
{
	UINT16 quality;

	if (Stream_GetRemainingLength(s) < 4)
	{
		WLog_ERR(TAG, "not enough data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT16(s, quality);
	Stream_Seek_UINT16(s); // reserved
	WLog_DBG(TAG, "Client requested sound quality: 0x%04" PRIX16 "", quality);
	return CHANNEL_RC_OK;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
{
	UINT16 i, num_known_format = 0;
	UINT32 flags, vol, pitch;
	UINT16 udpPort;
	BYTE lastblock;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 20)
	{
		WLog_ERR(TAG, "not enough data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, flags);                       /* dwFlags */
	Stream_Read_UINT32(s, vol);                         /* dwVolume */
	Stream_Read_UINT32(s, pitch);                       /* dwPitch */
	Stream_Read_UINT16(s, udpPort);                     /* wDGramPort */
	Stream_Read_UINT16(s, context->num_client_formats); /* wNumberOfFormats */
	Stream_Read_UINT8(s, lastblock);                    /* cLastBlockConfirmed */
	Stream_Read_UINT16(s, context->clientVersion);      /* wVersion */
	Stream_Seek_UINT8(s);                               /* bPad */

	/* this check is only a guess as cbSize can influence the size of a format record */
	if (Stream_GetRemainingLength(s) < context->num_client_formats * 18)
	{
		WLog_ERR(TAG, "not enough data in stream!");
		return ERROR_INVALID_DATA;
	}

	if (!context->num_client_formats)
	{
		WLog_ERR(TAG, "client doesn't support any format!");
		return ERROR_INTERNAL_ERROR;
	}

	context->client_formats = audio_formats_new(context->num_client_formats);

	if (!context->client_formats)
	{
		WLog_ERR(TAG, "calloc failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	for (i = 0; i < context->num_client_formats; i++)
	{
		if (Stream_GetRemainingLength(s) < 18)
		{
			WLog_ERR(TAG, "not enough data in stream!");
			error = ERROR_INVALID_DATA;
			goto out_free;
		}

		Stream_Read_UINT16(s, context->client_formats[i].wFormatTag);
		Stream_Read_UINT16(s, context->client_formats[i].nChannels);
		Stream_Read_UINT32(s, context->client_formats[i].nSamplesPerSec);
		Stream_Read_UINT32(s, context->client_formats[i].nAvgBytesPerSec);
		Stream_Read_UINT16(s, context->client_formats[i].nBlockAlign);
		Stream_Read_UINT16(s, context->client_formats[i].wBitsPerSample);
		Stream_Read_UINT16(s, context->client_formats[i].cbSize);

		if (context->client_formats[i].cbSize > 0)
		{
			if (!Stream_SafeSeek(s, context->client_formats[i].cbSize))
			{
				WLog_ERR(TAG, "Stream_SafeSeek failed!");
				error = ERROR_INTERNAL_ERROR;
				goto out_free;
			}
		}

		if (context->client_formats[i].wFormatTag != 0)
		{
			// lets call this a known format
			// TODO: actually look through our own list of known formats
			num_known_format++;
		}
	}

	if (!context->num_client_formats)
	{
		WLog_ERR(TAG, "client doesn't support any known format!");
		goto out_free;
	}

	return CHANNEL_RC_OK;
out_free:
	free(context->client_formats);
	return error;
}

static DWORD WINAPI rdpsnd_server_thread(LPVOID arg)
{
	DWORD nCount, status;
	HANDLE events[8];
	RdpsndServerContext* context;
	UINT error = CHANNEL_RC_OK;
	context = (RdpsndServerContext*)arg;
	nCount = 0;
	events[nCount++] = context->priv->channelEvent;
	events[nCount++] = context->priv->StopEvent;

	while (TRUE)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %" PRIu32 "!", error);
			break;
		}

		status = WaitForSingleObject(context->priv->StopEvent, 0);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
			break;

		if ((error = rdpsnd_server_handle_messages(context)))
		{
			WLog_ERR(TAG, "rdpsnd_server_handle_messages failed with error %" PRIu32 "", error);
			break;
		}
	}

	if (error && context->rdpcontext)
		setChannelError(context->rdpcontext, error, "rdpsnd_server_thread reported an error");

	ExitThread(error);
	return error;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_initialize(RdpsndServerContext* context, BOOL ownThread)
{
	context->priv->ownThread = ownThread;
	return context->Start(context);
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_select_format(RdpsndServerContext* context, UINT16 client_format_index)
{
	int bs;
	int out_buffer_size;
	AUDIO_FORMAT* format;
	UINT error = CHANNEL_RC_OK;

	if ((client_format_index >= context->num_client_formats) || (!context->src_format))
	{
		WLog_ERR(TAG, "index %d is not correct.", client_format_index);
		return ERROR_INVALID_DATA;
	}

	EnterCriticalSection(&context->priv->lock);
	context->priv->src_bytes_per_sample = context->src_format->wBitsPerSample / 8;
	context->priv->src_bytes_per_frame =
	    context->priv->src_bytes_per_sample * context->src_format->nChannels;
	context->selected_client_format = client_format_index;
	format = &context->client_formats[client_format_index];

	if (format->nSamplesPerSec == 0)
	{
		WLog_ERR(TAG, "invalid Client Sound Format!!");
		error = ERROR_INVALID_DATA;
		goto out;
	}

	if (context->latency <= 0)
		context->latency = 50;

	context->priv->out_frames = context->src_format->nSamplesPerSec * context->latency / 1000;

	if (context->priv->out_frames < 1)
		context->priv->out_frames = 1;

	switch (format->wFormatTag)
	{
		case WAVE_FORMAT_DVI_ADPCM:
			bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
			context->priv->out_frames -= context->priv->out_frames % bs;

			if (context->priv->out_frames < bs)
				context->priv->out_frames = bs;

			break;

		case WAVE_FORMAT_ADPCM:
			bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2;
			context->priv->out_frames -= context->priv->out_frames % bs;

			if (context->priv->out_frames < bs)
				context->priv->out_frames = bs;

			break;
	}

	context->priv->out_pending_frames = 0;
	out_buffer_size = context->priv->out_frames * context->priv->src_bytes_per_frame;

	if (context->priv->out_buffer_size < out_buffer_size)
	{
		BYTE* newBuffer;
		newBuffer = (BYTE*)realloc(context->priv->out_buffer, out_buffer_size);

		if (!newBuffer)
		{
			WLog_ERR(TAG, "realloc failed!");
			error = CHANNEL_RC_NO_MEMORY;
			goto out;
		}

		context->priv->out_buffer = newBuffer;
		context->priv->out_buffer_size = out_buffer_size;
	}

	freerdp_dsp_context_reset(context->priv->dsp_context, format);
out:
	LeaveCriticalSection(&context->priv->lock);
	return error;
}

static BOOL rdpsnd_server_align_wave_pdu(wStream* s, UINT32 alignment)
{
	size_t size;
	Stream_SealLength(s);
	size = Stream_Length(s);

	if ((size % alignment) != 0)
	{
		size_t offset = alignment - size % alignment;

		if (!Stream_EnsureRemainingCapacity(s, offset))
			return FALSE;

		Stream_Zero(s, offset);
	}

	Stream_SealLength(s);
	return TRUE;
}

/**
 * Function description
 * context->priv->lock should be obtained before calling this function
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_send_wave_pdu(RdpsndServerContext* context, UINT16 wTimestamp)
{
	size_t length;
	size_t start, end = 0;
	const BYTE* src;
	AUDIO_FORMAT* format;
	ULONG written;
	wStream* s = context->priv->rdpsnd_pdu;
	UINT error = CHANNEL_RC_OK;

	if (context->selected_client_format >= context->num_client_formats)
		return ERROR_INTERNAL_ERROR;

	format = &context->client_formats[context->selected_client_format];
	/* WaveInfo PDU */
	Stream_SetPosition(s, 0);
	Stream_Write_UINT8(s, SNDC_WAVE);                        /* msgType */
	Stream_Write_UINT8(s, 0);                                /* bPad */
	Stream_Write_UINT16(s, 0);                               /* BodySize */
	Stream_Write_UINT16(s, wTimestamp);                      /* wTimeStamp */
	Stream_Write_UINT16(s, context->selected_client_format); /* wFormatNo */
	Stream_Write_UINT8(s, context->block_no);                /* cBlockNo */
	Stream_Seek(s, 3);                                       /* bPad */
	start = Stream_GetPosition(s);
	src = context->priv->out_buffer;
	length = context->priv->out_pending_frames * context->priv->src_bytes_per_frame;

	if (!freerdp_dsp_encode(context->priv->dsp_context, context->src_format, src, length, s))
		return ERROR_INTERNAL_ERROR;
	else
	{
		/* Set stream size */
		if (!rdpsnd_server_align_wave_pdu(s, format->nBlockAlign))
			return ERROR_INTERNAL_ERROR;

		end = Stream_GetPosition(s);
		Stream_SetPosition(s, 2);
		Stream_Write_UINT16(s, end - start + 8);
		Stream_SetPosition(s, end);
		context->block_no = (context->block_no + 1) % 256;

		if (!WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR)Stream_Buffer(s),
		                            start + 4, &written))
		{
			WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
			error = ERROR_INTERNAL_ERROR;
		}
	}

	if (error != CHANNEL_RC_OK)
	{
		WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
		error = ERROR_INTERNAL_ERROR;
		goto out;
	}

	Stream_SetPosition(s, start);
	Stream_Write_UINT32(s, 0); /* bPad */
	Stream_SetPosition(s, start);

	if (!WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR)Stream_Pointer(s), end - start,
	                            &written))
	{
		WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
		error = ERROR_INTERNAL_ERROR;
	}

out:
	Stream_SetPosition(s, 0);
	context->priv->out_pending_frames = 0;
	return error;
}

/**
 * Function description
 * context->priv->lock should be obtained before calling this function
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_send_wave2_pdu(RdpsndServerContext* context, UINT16 wTimestamp)
{
	size_t length;
	size_t end = 0;
	const BYTE* src;
	AUDIO_FORMAT* format;
	ULONG written;
	wStream* s = context->priv->rdpsnd_pdu;
	UINT error = CHANNEL_RC_OK;

	if (context->selected_client_format >= context->num_client_formats)
		return ERROR_INTERNAL_ERROR;

	format = &context->client_formats[context->selected_client_format];
	/* WaveInfo PDU */
	Stream_SetPosition(s, 0);
	Stream_Write_UINT8(s, SNDC_WAVE2);                       /* msgType */
	Stream_Write_UINT8(s, 0);                                /* bPad */
	Stream_Write_UINT16(s, 0);                               /* BodySize */
	Stream_Write_UINT16(s, wTimestamp);                      /* wTimeStamp */
	Stream_Write_UINT16(s, context->selected_client_format); /* wFormatNo */
	Stream_Write_UINT8(s, context->block_no);                /* cBlockNo */
	Stream_Seek(s, 3);                                       /* bPad */
	Stream_Write_UINT32(s, wTimestamp);                      /* dwAudioTimeStamp */
	src = context->priv->out_buffer;
	length = context->priv->out_pending_frames * context->priv->src_bytes_per_frame;

	if (!freerdp_dsp_encode(context->priv->dsp_context, context->src_format, src, length, s))
		error = ERROR_INTERNAL_ERROR;
	else
	{
		BOOL rc;

		/* Set stream size */
		if (!rdpsnd_server_align_wave_pdu(s, format->nBlockAlign))
			return ERROR_INTERNAL_ERROR;

		end = Stream_GetPosition(s);
		Stream_SetPosition(s, 2);
		Stream_Write_UINT16(s, end - 4);
		context->block_no = (context->block_no + 1) % 256;
		rc = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR)Stream_Buffer(s), end,
		                            &written);

		if (!rc || (end != written))
		{
			WLog_ERR(TAG,
			         "WTSVirtualChannelWrite failed! [stream length=%" PRIdz " - written=%" PRIu32,
			         end, written);
			error = ERROR_INTERNAL_ERROR;
		}
	}

	Stream_SetPosition(s, 0);
	context->priv->out_pending_frames = 0;
	return error;
}

/* Wrapper function to send WAVE or WAVE2 PDU depending on client connected */
static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wTimestamp)
{
	if (context->clientVersion >= CHANNEL_VERSION_WIN_8)
		return rdpsnd_server_send_wave2_pdu(context, wTimestamp);
	else
		return rdpsnd_server_send_wave_pdu(context, wTimestamp);
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, const void* buf, int nframes,
                                       UINT16 wTimestamp)
{
	int cframes;
	int cframesize;
	UINT error = CHANNEL_RC_OK;
	EnterCriticalSection(&context->priv->lock);

	if (context->selected_client_format >= context->num_client_formats)
	{
		/* It's possible while format negotiation has not been done */
		WLog_WARN(TAG, "Drop samples because client format has not been negotiated.");
		error = ERROR_NOT_READY;
		goto out;
	}

	while (nframes > 0)
	{
		cframes = MIN(nframes, context->priv->out_frames - context->priv->out_pending_frames);
		cframesize = cframes * context->priv->src_bytes_per_frame;
		CopyMemory(context->priv->out_buffer +
		               (context->priv->out_pending_frames * context->priv->src_bytes_per_frame),
		           buf, cframesize);
		buf = (BYTE*)buf + cframesize;
		nframes -= cframes;
		context->priv->out_pending_frames += cframes;

		if (context->priv->out_pending_frames >= context->priv->out_frames)
		{
			if ((error = rdpsnd_server_send_audio_pdu(context, wTimestamp)))
			{
				WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %" PRIu32 "", error);
				break;
			}
		}
	}

out:
	LeaveCriticalSection(&context->priv->lock);
	return error;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_set_volume(RdpsndServerContext* context, int left, int right)
{
	size_t pos;
	BOOL status;
	ULONG written;
	wStream* s = context->priv->rdpsnd_pdu;
	Stream_Write_UINT8(s, SNDC_SETVOLUME);
	Stream_Write_UINT8(s, 0);
	Stream_Seek_UINT16(s);
	Stream_Write_UINT16(s, left);
	Stream_Write_UINT16(s, right);
	pos = Stream_GetPosition(s);
	Stream_SetPosition(s, 2);
	Stream_Write_UINT16(s, pos - 4);
	Stream_SetPosition(s, pos);
	status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR)Stream_Buffer(s),
	                                Stream_GetPosition(s), &written);
	Stream_SetPosition(s, 0);
	return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_close(RdpsndServerContext* context)
{
	size_t pos;
	BOOL status;
	ULONG written;
	wStream* s = context->priv->rdpsnd_pdu;
	UINT error = CHANNEL_RC_OK;
	EnterCriticalSection(&context->priv->lock);

	if (context->priv->out_pending_frames > 0)
	{
		if (context->selected_client_format >= context->num_client_formats)
		{
			WLog_ERR(TAG, "Pending audio frame exists while no format selected.");
			error = ERROR_INVALID_DATA;
		}
		else if ((error = rdpsnd_server_send_audio_pdu(context, 0)))
		{
			WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %" PRIu32 "", error);
		}
	}

	LeaveCriticalSection(&context->priv->lock);

	if (error)
		return error;

	context->selected_client_format = 0xFFFF;
	Stream_Write_UINT8(s, SNDC_CLOSE);
	Stream_Write_UINT8(s, 0);
	Stream_Seek_UINT16(s);
	pos = Stream_GetPosition(s);
	Stream_SetPosition(s, 2);
	Stream_Write_UINT16(s, pos - 4);
	Stream_SetPosition(s, pos);
	status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR)Stream_Buffer(s),
	                                Stream_GetPosition(s), &written);
	Stream_SetPosition(s, 0);
	return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_start(RdpsndServerContext* context)
{
	void* buffer = NULL;
	DWORD bytesReturned;
	RdpsndServerPrivate* priv = context->priv;
	UINT error = ERROR_INTERNAL_ERROR;
	priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpsnd");

	if (!priv->ChannelHandle)
	{
		WLog_ERR(TAG, "WTSVirtualChannelOpen failed!");
		return ERROR_INTERNAL_ERROR;
	}

	if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer,
	                            &bytesReturned) ||
	    (bytesReturned != sizeof(HANDLE)))
	{
		WLog_ERR(TAG,
		         "error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned "
		         "size(%" PRIu32 ")",
		         bytesReturned);

		if (buffer)
			WTSFreeMemory(buffer);

		goto out_close;
	}

	CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE));
	WTSFreeMemory(buffer);
	priv->rdpsnd_pdu = Stream_New(NULL, 4096);

	if (!priv->rdpsnd_pdu)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		error = CHANNEL_RC_NO_MEMORY;
		goto out_close;
	}

	if (!InitializeCriticalSectionEx(&context->priv->lock, 0, 0))
	{
		WLog_ERR(TAG, "InitializeCriticalSectionEx failed!");
		goto out_pdu;
	}

	if ((error = rdpsnd_server_send_formats(context, context->priv->rdpsnd_pdu)))
	{
		WLog_ERR(TAG, "rdpsnd_server_send_formats failed with error %" PRIu32 "", error);
		goto out_lock;
	}

	if (priv->ownThread)
	{
		context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		if (!context->priv->StopEvent)
		{
			WLog_ERR(TAG, "CreateEvent failed!");
			goto out_lock;
		}

		context->priv->Thread =
		    CreateThread(NULL, 0, rdpsnd_server_thread, (void*)context, 0, NULL);

		if (!context->priv->Thread)
		{
			WLog_ERR(TAG, "CreateThread failed!");
			goto out_stopEvent;
		}
	}

	return CHANNEL_RC_OK;
out_stopEvent:
	CloseHandle(context->priv->StopEvent);
	context->priv->StopEvent = NULL;
out_lock:
	DeleteCriticalSection(&context->priv->lock);
out_pdu:
	Stream_Free(context->priv->rdpsnd_pdu, TRUE);
	context->priv->rdpsnd_pdu = NULL;
out_close:
	WTSVirtualChannelClose(context->priv->ChannelHandle);
	context->priv->ChannelHandle = NULL;
	return error;
}

/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_stop(RdpsndServerContext* context)
{
	UINT error = CHANNEL_RC_OK;

	if (context->priv->ownThread)
	{
		if (context->priv->StopEvent)
		{
			SetEvent(context->priv->StopEvent);

			if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED)
			{
				error = GetLastError();
				WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
				return error;
			}

			CloseHandle(context->priv->Thread);
			CloseHandle(context->priv->StopEvent);
		}
	}

	DeleteCriticalSection(&context->priv->lock);

	if (context->priv->rdpsnd_pdu)
		Stream_Free(context->priv->rdpsnd_pdu, TRUE);

	return error;
}

RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm)
{
	RdpsndServerContext* context;
	RdpsndServerPrivate* priv;
	context = (RdpsndServerContext*)calloc(1, sizeof(RdpsndServerContext));

	if (!context)
	{
		WLog_ERR(TAG, "calloc failed!");
		return NULL;
	}

	context->vcm = vcm;
	context->Start = rdpsnd_server_start;
	context->Stop = rdpsnd_server_stop;
	context->selected_client_format = 0xFFFF;
	context->Initialize = rdpsnd_server_initialize;
	context->SelectFormat = rdpsnd_server_select_format;
	context->SendSamples = rdpsnd_server_send_samples;
	context->SetVolume = rdpsnd_server_set_volume;
	context->Close = rdpsnd_server_close;
	context->priv = priv = (RdpsndServerPrivate*)calloc(1, sizeof(RdpsndServerPrivate));

	if (!priv)
	{
		WLog_ERR(TAG, "calloc failed!");
		goto out_free;
	}

	priv->dsp_context = freerdp_dsp_context_new(TRUE);

	if (!priv->dsp_context)
	{
		WLog_ERR(TAG, "freerdp_dsp_context_new failed!");
		goto out_free_priv;
	}

	priv->input_stream = Stream_New(NULL, 4);

	if (!priv->input_stream)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		goto out_free_dsp;
	}

	priv->expectedBytes = 4;
	priv->waitingHeader = TRUE;
	priv->ownThread = TRUE;
	return context;
out_free_dsp:
	freerdp_dsp_context_free(priv->dsp_context);
out_free_priv:
	free(context->priv);
out_free:
	free(context);
	return NULL;
}

void rdpsnd_server_context_reset(RdpsndServerContext* context)
{
	context->priv->expectedBytes = 4;
	context->priv->waitingHeader = TRUE;
	Stream_SetPosition(context->priv->input_stream, 0);
}

void rdpsnd_server_context_free(RdpsndServerContext* context)
{
	if (context->priv->ChannelHandle)
		WTSVirtualChannelClose(context->priv->ChannelHandle);

	free(context->priv->out_buffer);

	if (context->priv->dsp_context)
		freerdp_dsp_context_free(context->priv->dsp_context);

	if (context->priv->input_stream)
		Stream_Free(context->priv->input_stream, TRUE);

	free(context->client_formats);
	free(context->priv);
	free(context);
}

HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext* context)
{
	return context->priv->channelEvent;
}

/*
 * Handle rpdsnd messages - server side
 *
 * @param Server side context
 *
 * @return 0 on success
 * 		   ERROR_NO_DATA if no data could be read this time
 *         otherwise error
 */
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT rdpsnd_server_handle_messages(RdpsndServerContext* context)
{
	DWORD bytesReturned;
	UINT ret = CHANNEL_RC_OK;
	RdpsndServerPrivate* priv = context->priv;
	wStream* s = priv->input_stream;

	if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s),
	                           priv->expectedBytes, &bytesReturned))
	{
		if (GetLastError() == ERROR_NO_DATA)
			return ERROR_NO_DATA;

		WLog_ERR(TAG, "channel connection closed");
		return ERROR_INTERNAL_ERROR;
	}

	priv->expectedBytes -= bytesReturned;
	Stream_Seek(s, bytesReturned);

	if (priv->expectedBytes)
		return CHANNEL_RC_OK;

	Stream_SealLength(s);
	Stream_SetPosition(s, 0);

	if (priv->waitingHeader)
	{
		/* header case */
		Stream_Read_UINT8(s, priv->msgType);
		Stream_Seek_UINT8(s); /* bPad */
		Stream_Read_UINT16(s, priv->expectedBytes);
		priv->waitingHeader = FALSE;
		Stream_SetPosition(s, 0);

		if (priv->expectedBytes)
		{
			if (!Stream_EnsureCapacity(s, priv->expectedBytes))
			{
				WLog_ERR(TAG, "Stream_EnsureCapacity failed!");
				return CHANNEL_RC_NO_MEMORY;
			}

			return CHANNEL_RC_OK;
		}
	}

	/* when here we have the header + the body */
#ifdef WITH_DEBUG_SND
	WLog_DBG(TAG, "message type %" PRIu8 "", priv->msgType);
#endif
	priv->expectedBytes = 4;
	priv->waitingHeader = TRUE;

	switch (priv->msgType)
	{
		case SNDC_WAVECONFIRM:
			ret = rdpsnd_server_recv_waveconfirm(context, s);
			break;

		case SNDC_FORMATS:
			ret = rdpsnd_server_recv_formats(context, s);

			if ((ret == CHANNEL_RC_OK) && (context->clientVersion < CHANNEL_VERSION_WIN_7))
				IFCALL(context->Activated, context);

			break;

		case SNDC_QUALITYMODE:
			ret = rdpsnd_server_recv_quality_mode(context, s);
			Stream_SetPosition(s,
			                   0); /* in case the Activated callback tries to treat some messages */

			if ((ret == CHANNEL_RC_OK) && (context->clientVersion >= CHANNEL_VERSION_WIN_7))
				IFCALL(context->Activated, context);

			break;

		default:
			WLog_ERR(TAG, "UNKNOWN MESSAGE TYPE!! (0x%02" PRIX8 ")", priv->msgType);
			ret = ERROR_INVALID_DATA;
			break;
	}

	Stream_SetPosition(s, 0);
	return ret;
}


text:
FILE(REMOVE_RECURSE
  "CMakeFiles/product_trmm_133.dir/product_trmm.cpp.o"
  "product_trmm_133.pdb"
  "product_trmm_133"
)

# Per-language clean rules from dependency scanning.
FOREACH(lang CXX)
  INCLUDE(CMakeFiles/product_trmm_133.dir/cmake_clean_${lang}.cmake OPTIONAL)
ENDFOREACH(lang)


text:
const path = require('path');

/**
 * @function configPrefix
 * return a piece of settings object, configured by a 'prefix' or 'no-prefix' presets
 * @param include {boolean} - the value of the object properties for message prefix configuration
 * @return {object} - a piece of settings, responsible for prefix configuration
 * */
function configPrefix(include) {
  return {
    LOG_TIMESTAMP: include,
    LOG_ENVIRONMENT: include,
    LOG_LEVEL: include,
    LOG_REQID: include,
    LOG_CALLER_PREFIX: include
  };
}

function getCallerAppVersion(pwd = __dirname) {
  try {
    const callerModulePath = pwd.split(`${path.sep}node_modules`);
    let callerModulePackageJSON = '';
    // if contained node_modules
    if (callerModulePath.length > 1) {
      // part of the path before /node_modules
      callerModulePackageJSON = path.normalize(`${callerModulePath[0]}/package.json`);
    }

    if (callerModulePackageJSON) {
      const json = require(callerModulePackageJSON); // eslint-disable-line
      return json.version;
    }
  } catch (e) {} // eslint-disable-line
  console.warn('Unable to fetch caller module\'s version'); // eslint-disable-line
  return 'unknown';
}

/**
 * @function applyPreset
 * @param preset {string} - a key name of a preset
 * @return {object} - a piece of settings object based on the preset value
 * */
function applyPreset(preset) {
  switch (preset) {
    case 'dial-once': {
      const appVersion = getCallerAppVersion();
      if (['staging', 'production'].includes(process.env.NODE_ENV)) {
        return {
          CONSOLE_LOGGING: false,
          LOGENTRIES_LOGGING: true,
          LOGSTASH_LOGGING: true,
          BUGSNAG_LOGGING: true,
          JSONIFY: true,
          BUGSNAG_APP_VERSION: appVersion
        };
      }
      return {
        CONSOLE_LOGGING: true,
        LOGSTASH_LOGGING: false,
        LOGENTRIES_LOGGING: false,
        BUGSNAG_LOGGING: false,
        JSONIFY: true,
        BUGSNAG_APP_VERSION: appVersion
      };
    }
    case 'no-prefix': {
      return configPrefix(false);
    }
    case 'prefix': {
      return configPrefix(true);
    }
    case 'jsonify': {
      return { JSONIFY: true };
    }
    default: {
      return {};
    }
  }
}

/**
 * @param settings {Object} - chain settings
 * @return settings object per the given presets
 * */
module.exports = (settings) => {
  const presetConfigs = {};
  for (const preset of settings.presets) {
    Object.assign(presetConfigs, applyPreset(preset));
  }
  return presetConfigs;
};

module.exports.getCallerAppVersion = getCallerAppVersion;