text:
namespace v8 {
namespace internal {
namespace compiler {

TEST(CompareWrapper) {
  // Who tests the testers?
  // If CompareWrapper is broken, then test expectations will be broken.
  CompareWrapper wWord32Equal(IrOpcode::kWord32Equal);
  CompareWrapper wInt32LessThan(IrOpcode::kInt32LessThan);
  CompareWrapper wInt32LessThanOrEqual(IrOpcode::kInt32LessThanOrEqual);
  CompareWrapper wUint32LessThan(IrOpcode::kUint32LessThan);
  CompareWrapper wUint32LessThanOrEqual(IrOpcode::kUint32LessThanOrEqual);

  {
    FOR_INT32_INPUTS(pl) {
      FOR_INT32_INPUTS(pr) {
        int32_t a = *pl;
        int32_t b = *pr;
        CHECK_EQ(a == b, wWord32Equal.Int32Compare(a, b));
        CHECK_EQ(a < b, wInt32LessThan.Int32Compare(a, b));
        CHECK_EQ(a <= b, wInt32LessThanOrEqual.Int32Compare(a, b));
      }
    }
  }

  {
    FOR_UINT32_INPUTS(pl) {
      FOR_UINT32_INPUTS(pr) {
        uint32_t a = *pl;
        uint32_t b = *pr;
        CHECK_EQ(a == b, wWord32Equal.Int32Compare(a, b));
        CHECK_EQ(a < b, wUint32LessThan.Int32Compare(a, b));
        CHECK_EQ(a <= b, wUint32LessThanOrEqual.Int32Compare(a, b));
      }
    }
  }

  CHECK_EQ(true, wWord32Equal.Int32Compare(0, 0));
  CHECK_EQ(true, wWord32Equal.Int32Compare(257, 257));
  CHECK_EQ(true, wWord32Equal.Int32Compare(65539, 65539));
  CHECK_EQ(true, wWord32Equal.Int32Compare(-1, -1));
  CHECK_EQ(true, wWord32Equal.Int32Compare(0xffffffff, 0xffffffff));

  CHECK_EQ(false, wWord32Equal.Int32Compare(0, 1));
  CHECK_EQ(false, wWord32Equal.Int32Compare(257, 256));
  CHECK_EQ(false, wWord32Equal.Int32Compare(65539, 65537));
  CHECK_EQ(false, wWord32Equal.Int32Compare(-1, -2));
  CHECK_EQ(false, wWord32Equal.Int32Compare(0xffffffff, 0xfffffffe));

  CHECK_EQ(false, wInt32LessThan.Int32Compare(0, 0));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(357, 357));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(75539, 75539));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(-1, -1));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(0xffffffff, 0xffffffff));

  CHECK_EQ(true, wInt32LessThan.Int32Compare(0, 1));
  CHECK_EQ(true, wInt32LessThan.Int32Compare(456, 457));
  CHECK_EQ(true, wInt32LessThan.Int32Compare(85537, 85539));
  CHECK_EQ(true, wInt32LessThan.Int32Compare(-2, -1));
  CHECK_EQ(true, wInt32LessThan.Int32Compare(0xfffffffe, 0xffffffff));

  CHECK_EQ(false, wInt32LessThan.Int32Compare(1, 0));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(457, 456));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(85539, 85537));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(-1, -2));
  CHECK_EQ(false, wInt32LessThan.Int32Compare(0xffffffff, 0xfffffffe));

  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0, 0));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(357, 357));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(75539, 75539));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(-1, -1));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0xffffffff, 0xffffffff));

  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0, 1));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(456, 457));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(85537, 85539));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(-2, -1));
  CHECK_EQ(true, wInt32LessThanOrEqual.Int32Compare(0xfffffffe, 0xffffffff));

  CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(1, 0));
  CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(457, 456));
  CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(85539, 85537));
  CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(-1, -2));
  CHECK_EQ(false, wInt32LessThanOrEqual.Int32Compare(0xffffffff, 0xfffffffe));

  // Unsigned comparisons.
  CHECK_EQ(false, wUint32LessThan.Int32Compare(0, 0));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(357, 357));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(75539, 75539));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(-1, -1));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(0xffffffff, 0xffffffff));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(0xffffffff, 0));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(-2999, 0));

  CHECK_EQ(true, wUint32LessThan.Int32Compare(0, 1));
  CHECK_EQ(true, wUint32LessThan.Int32Compare(456, 457));
  CHECK_EQ(true, wUint32LessThan.Int32Compare(85537, 85539));
  CHECK_EQ(true, wUint32LessThan.Int32Compare(-11, -10));
  CHECK_EQ(true, wUint32LessThan.Int32Compare(0xfffffffe, 0xffffffff));
  CHECK_EQ(true, wUint32LessThan.Int32Compare(0, 0xffffffff));
  CHECK_EQ(true, wUint32LessThan.Int32Compare(0, -2996));

  CHECK_EQ(false, wUint32LessThan.Int32Compare(1, 0));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(457, 456));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(85539, 85537));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(-10, -21));
  CHECK_EQ(false, wUint32LessThan.Int32Compare(0xffffffff, 0xfffffffe));

  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, 0));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(357, 357));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(75539, 75539));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-1, -1));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0xffffffff, 0xffffffff));

  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, 1));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(456, 457));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(85537, 85539));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-300, -299));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(-300, -300));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0xfffffffe, 0xffffffff));
  CHECK_EQ(true, wUint32LessThanOrEqual.Int32Compare(0, -2995));

  CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(1, 0));
  CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(457, 456));
  CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(85539, 85537));
  CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(-130, -170));
  CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(0xffffffff, 0xfffffffe));
  CHECK_EQ(false, wUint32LessThanOrEqual.Int32Compare(-2997, 0));

  CompareWrapper wFloat64Equal(IrOpcode::kFloat64Equal);
  CompareWrapper wFloat64LessThan(IrOpcode::kFloat64LessThan);
  CompareWrapper wFloat64LessThanOrEqual(IrOpcode::kFloat64LessThanOrEqual);

  // Check NaN handling.
  double nan = std::numeric_limits<double>::quiet_NaN();
  double inf = V8_INFINITY;
  CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 0.0));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, 1.0));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, inf));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, -inf));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, nan));

  CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, nan));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, nan));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, nan));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, nan));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(nan, nan));

  CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, 0.0));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, 1.0));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, -inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, nan));

  CHECK_EQ(false, wFloat64LessThan.Float64Compare(0.0, nan));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(1.0, nan));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, nan));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, nan));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(nan, nan));

  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, 0.0));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, 1.0));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, inf));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, -inf));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, nan));

  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(0.0, nan));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1.0, nan));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, nan));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(-inf, nan));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(nan, nan));

  // Check inf handling.
  CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, 0.0));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, 1.0));
  CHECK_EQ(true, wFloat64Equal.Float64Compare(inf, inf));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, -inf));

  CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, inf));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, inf));
  CHECK_EQ(true, wFloat64Equal.Float64Compare(inf, inf));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, inf));

  CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, 0.0));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, 1.0));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, -inf));

  CHECK_EQ(true, wFloat64LessThan.Float64Compare(0.0, inf));
  CHECK_EQ(true, wFloat64LessThan.Float64Compare(1.0, inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, inf));
  CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, inf));

  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, 0.0));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, 1.0));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(inf, inf));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, -inf));

  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0.0, inf));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(1.0, inf));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(inf, inf));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, inf));

  // Check -inf handling.
  CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, 0.0));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, 1.0));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(-inf, inf));
  CHECK_EQ(true, wFloat64Equal.Float64Compare(-inf, -inf));

  CHECK_EQ(false, wFloat64Equal.Float64Compare(0.0, -inf));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(1.0, -inf));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(inf, -inf));
  CHECK_EQ(true, wFloat64Equal.Float64Compare(-inf, -inf));

  CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, 0.0));
  CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, 1.0));
  CHECK_EQ(true, wFloat64LessThan.Float64Compare(-inf, inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, -inf));

  CHECK_EQ(false, wFloat64LessThan.Float64Compare(0.0, -inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(1.0, -inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(inf, -inf));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(-inf, -inf));

  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, 0.0));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, 1.0));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, inf));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, -inf));

  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(0.0, -inf));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1.0, -inf));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(inf, -inf));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-inf, -inf));

  // Check basic values.
  CHECK_EQ(true, wFloat64Equal.Float64Compare(0, 0));
  CHECK_EQ(true, wFloat64Equal.Float64Compare(257.1, 257.1));
  CHECK_EQ(true, wFloat64Equal.Float64Compare(65539.1, 65539.1));
  CHECK_EQ(true, wFloat64Equal.Float64Compare(-1.1, -1.1));

  CHECK_EQ(false, wFloat64Equal.Float64Compare(0, 1));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(257.2, 256.2));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(65539.2, 65537.2));
  CHECK_EQ(false, wFloat64Equal.Float64Compare(-1.2, -2.2));

  CHECK_EQ(false, wFloat64LessThan.Float64Compare(0, 0));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(357.3, 357.3));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(75539.3, 75539.3));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(-1.3, -1.3));

  CHECK_EQ(true, wFloat64LessThan.Float64Compare(0, 1));
  CHECK_EQ(true, wFloat64LessThan.Float64Compare(456.4, 457.4));
  CHECK_EQ(true, wFloat64LessThan.Float64Compare(85537.4, 85539.4));
  CHECK_EQ(true, wFloat64LessThan.Float64Compare(-2.4, -1.4));

  CHECK_EQ(false, wFloat64LessThan.Float64Compare(1, 0));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(457.5, 456.5));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(85539.5, 85537.5));
  CHECK_EQ(false, wFloat64LessThan.Float64Compare(-1.5, -2.5));

  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0, 0));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(357.6, 357.6));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(75539.6, 75539.6));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-1.6, -1.6));

  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(0, 1));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(456.7, 457.7));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(85537.7, 85539.7));
  CHECK_EQ(true, wFloat64LessThanOrEqual.Float64Compare(-2.7, -1.7));

  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(1, 0));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(457.8, 456.8));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(85539.8, 85537.8));
  CHECK_EQ(false, wFloat64LessThanOrEqual.Float64Compare(-1.8, -2.8));
}

void Int32BinopInputShapeTester::TestAllInputShapes() {
  std::vector<int32_t> inputs = ValueHelper::int32_vector();
  int num_int_inputs = static_cast<int>(inputs.size());
  if (num_int_inputs > 16) num_int_inputs = 16;  // limit to 16 inputs

  for (int i = -2; i < num_int_inputs; i++) {    // for all left shapes
    for (int j = -2; j < num_int_inputs; j++) {  // for all right shapes
      if (i >= 0 && j >= 0) break;               // No constant/constant combos
      RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
                                           MachineType::Int32());
      Node* p0 = m.Parameter(0);
      Node* p1 = m.Parameter(1);
      Node* n0;
      Node* n1;

      // left = Parameter | Load | Constant
      if (i == -2) {
        n0 = p0;
      } else if (i == -1) {
        n0 = m.LoadFromPointer(&input_a, MachineType::Int32());
      } else {
        n0 = m.Int32Constant(inputs[i]);
      }

      // right = Parameter | Load | Constant
      if (j == -2) {
        n1 = p1;
      } else if (j == -1) {
        n1 = m.LoadFromPointer(&input_b, MachineType::Int32());
      } else {
        n1 = m.Int32Constant(inputs[j]);
      }

      gen->gen(&m, n0, n1);

      if (false) printf("Int32BinopInputShapeTester i=%d, j=%d\n", i, j);
      if (i >= 0) {
        input_a = inputs[i];
        RunRight(&m);
      } else if (j >= 0) {
        input_b = inputs[j];
        RunLeft(&m);
      } else {
        Run(&m);
      }
    }
  }
}

void Int32BinopInputShapeTester::Run(RawMachineAssemblerTester<int32_t>* m) {
  FOR_INT32_INPUTS(pl) {
    FOR_INT32_INPUTS(pr) {
      input_a = *pl;
      input_b = *pr;
      int32_t expect = gen->expected(input_a, input_b);
      if (false) printf("  cmp(a=%d, b=%d) ?== %d\n", input_a, input_b, expect);
      CHECK_EQ(expect, m->Call(input_a, input_b));
    }
  }
}

void Int32BinopInputShapeTester::RunLeft(
    RawMachineAssemblerTester<int32_t>* m) {
  FOR_UINT32_INPUTS(i) {
    input_a = *i;
    int32_t expect = gen->expected(input_a, input_b);
    if (false) printf("  cmp(a=%d, b=%d) ?== %d\n", input_a, input_b, expect);
    CHECK_EQ(expect, m->Call(input_a, input_b));
  }
}

void Int32BinopInputShapeTester::RunRight(
    RawMachineAssemblerTester<int32_t>* m) {
  FOR_UINT32_INPUTS(i) {
    input_b = *i;
    int32_t expect = gen->expected(input_a, input_b);
    if (false) printf("  cmp(a=%d, b=%d) ?== %d\n", input_a, input_b, expect);
    CHECK_EQ(expect, m->Call(input_a, input_b));
  }
}

TEST(ParametersEqual) {
  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
                                       MachineType::Int32());
  Node* p1 = m.Parameter(1);
  CHECK(p1);
  Node* p0 = m.Parameter(0);
  CHECK(p0);
  CHECK_EQ(p0, m.Parameter(0));
  CHECK_EQ(p1, m.Parameter(1));
}

void RunSmiConstant(int32_t v) {
// TODO(dcarney): on x64 Smis are generated with the SmiConstantRegister
#if !V8_TARGET_ARCH_X64
  if (Smi::IsValid(v)) {
    RawMachineAssemblerTester<Object*> m;
    m.Return(m.NumberConstant(v));
    CHECK_EQ(Smi::FromInt(v), m.Call());
  }
#endif
}

void RunNumberConstant(double v) {
  RawMachineAssemblerTester<Object*> m;
#if V8_TARGET_ARCH_X64
  // TODO(dcarney): on x64 Smis are generated with the SmiConstantRegister
  Handle<Object> number = m.isolate()->factory()->NewNumber(v);
  if (number->IsSmi()) return;
#endif
  m.Return(m.NumberConstant(v));
  Object* result = m.Call();
  m.CheckNumber(v, result);
}

TEST(RunEmpty) {
  RawMachineAssemblerTester<int32_t> m;
  m.Return(m.Int32Constant(0));
  CHECK_EQ(0, m.Call());
}

TEST(RunInt32Constants) {
  FOR_INT32_INPUTS(i) {
    RawMachineAssemblerTester<int32_t> m;
    m.Return(m.Int32Constant(*i));
    CHECK_EQ(*i, m.Call());
  }
}

TEST(RunSmiConstants) {
  for (int32_t i = 1; i < Smi::kMaxValue && i != 0; i = i << 1) {
    RunSmiConstant(i);
    RunSmiConstant(3 * i);
    RunSmiConstant(5 * i);
    RunSmiConstant(-i);
    RunSmiConstant(i | 1);
    RunSmiConstant(i | 3);
  }
  RunSmiConstant(Smi::kMaxValue);
  RunSmiConstant(Smi::kMaxValue - 1);
  RunSmiConstant(Smi::kMinValue);
  RunSmiConstant(Smi::kMinValue + 1);

  FOR_INT32_INPUTS(i) { RunSmiConstant(*i); }
}

TEST(RunNumberConstants) {
  {
    FOR_FLOAT64_INPUTS(i) { RunNumberConstant(*i); }
  }
  {
    FOR_INT32_INPUTS(i) { RunNumberConstant(*i); }
  }

  for (int32_t i = 1; i < Smi::kMaxValue && i != 0; i = i << 1) {
    RunNumberConstant(i);
    RunNumberConstant(-i);
    RunNumberConstant(i | 1);
    RunNumberConstant(i | 3);
  }
  RunNumberConstant(Smi::kMaxValue);
  RunNumberConstant(Smi::kMaxValue - 1);
  RunNumberConstant(Smi::kMinValue);
  RunNumberConstant(Smi::kMinValue + 1);
}

TEST(RunEmptyString) {
  RawMachineAssemblerTester<Object*> m;
  m.Return(m.StringConstant("empty"));
  m.CheckString("empty", m.Call());
}

TEST(RunHeapConstant) {
  RawMachineAssemblerTester<Object*> m;
  m.Return(m.StringConstant("empty"));
  m.CheckString("empty", m.Call());
}

TEST(RunHeapNumberConstant) {
  RawMachineAssemblerTester<HeapObject*> m;
  Handle<HeapObject> number = m.isolate()->factory()->NewHeapNumber(100.5);
  m.Return(m.HeapConstant(number));
  HeapObject* result = m.Call();
  CHECK_EQ(result, *number);
}

TEST(RunParam1) {
  RawMachineAssemblerTester<int32_t> m(MachineType::Int32());
  m.Return(m.Parameter(0));

  FOR_INT32_INPUTS(i) {
    int32_t result = m.Call(*i);
    CHECK_EQ(*i, result);
  }
}

TEST(RunParam2_1) {
  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
                                       MachineType::Int32());
  Node* p0 = m.Parameter(0);
  Node* p1 = m.Parameter(1);
  m.Return(p0);
  USE(p1);

  FOR_INT32_INPUTS(i) {
    int32_t result = m.Call(*i, -9999);
    CHECK_EQ(*i, result);
  }
}

TEST(RunParam2_2) {
  RawMachineAssemblerTester<int32_t> m(MachineType::Int32(),
                                       MachineType::Int32());
  Node* p0 = m.Parameter(0);
  Node* p1 = m.Parameter(1);
  m.Return(p1);
  USE(p0);

  FOR_INT32_INPUTS(i) {
    int32_t result = m.Call(-7777, *i);
    CHECK_EQ(*i, result);
  }
}

TEST(RunParam3) {
  for (int i = 0; i < 3; i++) {
    RawMachineAssemblerTester<int32_t> m(
        MachineType::Int32(), MachineType::Int32(), MachineType::Int32());
    Node* nodes[] = {m.Parameter(0), m.Parameter(1), m.Parameter(2)};
    m.Return(nodes[i]);

    int p[] = {-99, -77, -88};
    FOR_INT32_INPUTS(j) {
      p[i] = *j;
      int32_t result = m.Call(p[0], p[1], p[2]);
      CHECK_EQ(*j, result);
    }
  }
}

TEST(RunBinopTester) {
  {
    RawMachineAssemblerTester<int32_t> m;
    Int32BinopTester bt(&m);
    bt.AddReturn(bt.param0);

    FOR_INT32_INPUTS(i) { CHECK_EQ(*i, bt.call(*i, 777)); }
  }

  {
    RawMachineAssemblerTester<int32_t> m;
    Int32BinopTester bt(&m);
    bt.AddReturn(bt.param1);

    FOR_INT32_INPUTS(i) { CHECK_EQ(*i, bt.call(666, *i)); }
  }

  {
    RawMachineAssemblerTester<int32_t> m;
    Float64BinopTester bt(&m);
    bt.AddReturn(bt.param0);

    FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, bt.call(*i, 9.0)); }
  }

  {
    RawMachineAssemblerTester<int32_t> m;
    Float64BinopTester bt(&m);
    bt.AddReturn(bt.param1);

    FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, bt.call(-11.25, *i)); }
  }
}

#if V8_TARGET_ARCH_64_BIT
// TODO(ahaas): run int64 tests on all platforms when supported.
TEST(RunBufferedRawMachineAssemblerTesterTester) {
  {
    BufferedRawMachineAssemblerTester<int64_t> m;
    m.Return(m.Int64Constant(0x12500000000));
    CHECK_EQ(0x12500000000, m.Call());
  }
  {
    BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
    m.Return(m.Parameter(0));
    FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(*i, m.Call(*i)); }
  }
  {
    BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
                                                 MachineType::Int64());
    m.Return(m.Int64Add(m.Parameter(0), m.Parameter(1)));
    FOR_INT64_INPUTS(i) {
      FOR_INT64_INPUTS(j) {
        CHECK_EQ(*i + *j, m.Call(*i, *j));
        CHECK_EQ(*j + *i, m.Call(*j, *i));
      }
    }
  }
  {
    BufferedRawMachineAssemblerTester<int64_t> m(
        MachineType::Int64(), MachineType::Int64(), MachineType::Int64());
    m.Return(
        m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)));
    FOR_INT64_INPUTS(i) {
      FOR_INT64_INPUTS(j) {
        CHECK_EQ(*i + *i + *j, m.Call(*i, *i, *j));
        CHECK_EQ(*i + *j + *i, m.Call(*i, *j, *i));
        CHECK_EQ(*j + *i + *i, m.Call(*j, *i, *i));
      }
    }
  }
  {
    BufferedRawMachineAssemblerTester<int64_t> m(
        MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
        MachineType::Int64());
    m.Return(m.Int64Add(
        m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)),
        m.Parameter(3)));
    FOR_INT64_INPUTS(i) {
      FOR_INT64_INPUTS(j) {
        CHECK_EQ(*i + *i + *i + *j, m.Call(*i, *i, *i, *j));
        CHECK_EQ(*i + *i + *j + *i, m.Call(*i, *i, *j, *i));
        CHECK_EQ(*i + *j + *i + *i, m.Call(*i, *j, *i, *i));
        CHECK_EQ(*j + *i + *i + *i, m.Call(*j, *i, *i, *i));
      }
    }
  }
  {
    BufferedRawMachineAssemblerTester<void> m;
    int64_t result;
    m.Store(MachineTypeForC<int64_t>().representation(),
            m.PointerConstant(&result), m.Int64Constant(0x12500000000),
            kNoWriteBarrier);
    m.Return(m.Int32Constant(0));
    m.Call();
    CHECK_EQ(0x12500000000, result);
  }
  {
    BufferedRawMachineAssemblerTester<void> m(MachineType::Float64());
    double result;
    m.Store(MachineTypeForC<double>().representation(),
            m.PointerConstant(&result), m.Parameter(0), kNoWriteBarrier);
    m.Return(m.Int32Constant(0));
    FOR_FLOAT64_INPUTS(i) {
      m.Call(*i);
      CHECK_DOUBLE_EQ(*i, result);
    }
  }
  {
    BufferedRawMachineAssemblerTester<void> m(MachineType::Int64(),
                                              MachineType::Int64());
    int64_t result;
    m.Store(MachineTypeForC<int64_t>().representation(),
            m.PointerConstant(&result),
            m.Int64Add(m.Parameter(0), m.Parameter(1)), kNoWriteBarrier);
    m.Return(m.Int32Constant(0));
    FOR_INT64_INPUTS(i) {
      FOR_INT64_INPUTS(j) {
        m.Call(*i, *j);
        CHECK_EQ(*i + *j, result);

        m.Call(*j, *i);
        CHECK_EQ(*j + *i, result);
      }
    }
  }
  {
    BufferedRawMachineAssemblerTester<void> m(
        MachineType::Int64(), MachineType::Int64(), MachineType::Int64());
    int64_t result;
    m.Store(
        MachineTypeForC<int64_t>().representation(), m.PointerConstant(&result),
        m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)),
        kNoWriteBarrier);
    m.Return(m.Int32Constant(0));
    FOR_INT64_INPUTS(i) {
      FOR_INT64_INPUTS(j) {
        m.Call(*i, *i, *j);
        CHECK_EQ(*i + *i + *j, result);

        m.Call(*i, *j, *i);
        CHECK_EQ(*i + *j + *i, result);

        m.Call(*j, *i, *i);
        CHECK_EQ(*j + *i + *i, result);
      }
    }
  }
  {
    BufferedRawMachineAssemblerTester<void> m(
        MachineType::Int64(), MachineType::Int64(), MachineType::Int64(),
        MachineType::Int64());
    int64_t result;
    m.Store(MachineTypeForC<int64_t>().representation(),
            m.PointerConstant(&result),
            m.Int64Add(m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)),
                                  m.Parameter(2)),
                       m.Parameter(3)),
            kNoWriteBarrier);
    m.Return(m.Int32Constant(0));
    FOR_INT64_INPUTS(i) {
      FOR_INT64_INPUTS(j) {
        m.Call(*i, *i, *i, *j);
        CHECK_EQ(*i + *i + *i + *j, result);

        m.Call(*i, *i, *j, *i);
        CHECK_EQ(*i + *i + *j + *i, result);

        m.Call(*i, *j, *i, *i);
        CHECK_EQ(*i + *j + *i + *i, result);

        m.Call(*j, *i, *i, *i);
        CHECK_EQ(*j + *i + *i + *i, result);
      }
    }
  }
}

#endif
}  // namespace compiler
}  // namespace internal
}  // namespace v8


text:
## Introducing exhibit
exhibit is a one-page template designed specifically for hosting on [GitHub Pages](http://pages.github.com) and serving locally using [Jekyll](http://jekyllrb.com).

## Prerequisites
exhibit requires the minimum versions of Node and Ruby below.

* [Node 0.10.30](http://nodejs.org/download)
* [Ruby 2.0](http://www.ruby-lang.org/en/installation)

Run the commands below to determine which versions are currently installed.

~~~bash
# each command returns a version number
$ node --version
$ ruby -v
~~~

## Install exhibit
Clone exhibit from the `gh-pages` branch on GitHub and go into its directory.

~~~
$ git clone -b gh-pages https://github.com/caleorourke/exhibit.git
$ cd exhibit
~~~

Install Grunt and dev dependencies for Node.

~~~bash
$ sudo npm install -g grunt-cli
$ sudo npm install
~~~

Install Jekyll and other Ruby runtime dependencies.

~~~bash
$ sudo grunt install
~~~

## Start Using exhibit
exhibit leverages [Grunt](http://gruntjs.com) as a harness for installing Node and Ruby dependencies, in addition to serving the site locally.

### Commands
Run any of these commands to initiate a task.

* `$ grunt build`
* `$ grunt install`
* `$ grunt serve`
* `$ grunt test`

#### $ grunt build

1. Bundles and minifies `*.less` files to `*.css` using [RECESS](http://twitter.github.io/recess)
2. Bundles and minifies `*.js` files using [UglifyJS](https://www.npmjs.com/package/grunt-contrib-uglify)

#### $ grunt install

1. Updates RubyGems
2. Runs `gem install github-pages`

#### $ grunt serve

1. Bundles and minifies `*.less` files to `*.css` using [RECESS](http://twitter.github.io/recess)
2. Bundles and minifies `*.js` files using [UglifyJS](https://www.npmjs.com/package/grunt-contrib-uglify)
3. Builds the site locally in the `_site` directory
4. Starts a local environment on `http://localhost:4000`
5. Regenerates a new `_site` directory whenever a file is modified (except `.less` and `.js` assets)

> Serve mode lasts forever. It will not timeout after a period of non-usage. In order to stop it, press `CTRL+C`.

#### $ grunt test

1. Builds the website locally in the `_site` directory
2. Spits out any errors found during the build process

## Updating exhibit
Dependencies are updated often by their original authors. To install the most recent versions, run `sudo npm update`.

If this fails for whatever reason, run the following commands to delete the original `node_modules` directory and build a new one.

~~~bash
$ sudo rm -r node_modules
$ sudo npm install
~~~

## License

Code and documentation licensed under the MIT license.

redpajama_set_name: RedPajamaGithub


text:
package com.thaiopensource.relaxng.output.xsd;

import com.thaiopensource.relaxng.output.xsd.basic.Attribute;
import com.thaiopensource.relaxng.output.xsd.basic.Definition;
import com.thaiopensource.relaxng.output.xsd.basic.Element;
import com.thaiopensource.relaxng.output.xsd.basic.GroupDefinition;
import com.thaiopensource.relaxng.output.xsd.basic.GroupRef;
import com.thaiopensource.relaxng.output.xsd.basic.Include;
import com.thaiopensource.relaxng.output.xsd.basic.Particle;
import com.thaiopensource.relaxng.output.xsd.basic.ParticleChoice;
import com.thaiopensource.relaxng.output.xsd.basic.Schema;
import com.thaiopensource.relaxng.output.xsd.basic.SchemaWalker;
import com.thaiopensource.relaxng.output.xsd.basic.Structure;
import com.thaiopensource.relaxng.output.xsd.basic.Wildcard;
import com.thaiopensource.relaxng.output.xsd.basic.WildcardAttribute;
import com.thaiopensource.relaxng.output.xsd.basic.WildcardElement;
import com.thaiopensource.util.VoidValue;
import com.thaiopensource.xml.util.Name;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

public class NamespaceManager {
  private final Schema schema;
  private final Map<Name, NameInfo> elementNameMap = new HashMap<Name, NameInfo>();
  private final Map<Name, NameInfo> attributeNameMap = new HashMap<Name, NameInfo>();
  private final Map<Object, Name> substitutionGroupMap = new HashMap<Object, Name>();
  private final Map<String, Name> groupDefinitionAbstractElementMap = new HashMap<String, Name>();
  private final Map<Name, List<Name>> abstractElementSubstitutionGroupMemberMap = new HashMap<Name, List<Name>>();

  static class SourceUri {
    String targetNamespace;
    // list of strings giving included URIs
    final List<String> includes = new Vector<String>();
  }

  static class TargetNamespace {
    String rootSchema;
    final List<Structure> movedStructures = new Vector<Structure>();
    final Set<Structure> movedStructureSet = new HashSet<Structure>();
    final Map<Structure, String> movedStructureNameMap = new HashMap<Structure, String>();
    final Set<String> movedElementNameSet = new HashSet<String>();
    final Set<String> movedAttributeNameSet = new HashSet<String>();
    boolean movedOtherElement = false;
    boolean movedOtherAttribute = false;
    String otherElementName;
    String otherAttributeName;
  }

  static class NameInfo {
    static final int OCCUR_NONE = 0;
    static final int OCCUR_NESTED = 1;
    static final int OCCUR_TOP = 2;
    static final int OCCUR_MOVE = 3;
    static final int OCCUR_ROOT = 4;
    int occur = OCCUR_NONE;
    Structure globalType = null;
  }

  // Maps sourceUri to SourceUri
  private final Map<String, SourceUri> sourceUriMap = new HashMap<String, SourceUri>();
  // Maps targetNamespace to TargetNamespace
  private final Map<String, TargetNamespace> targetNamespaceMap = new HashMap<String,TargetNamespace>();

  class IncludeFinder extends SchemaWalker {
    private final SourceUri source;
    IncludeFinder(Schema schema) {
      source = lookupSourceUri(schema.getUri());
      schema.accept(this);
    }

    public void visitInclude(Include include) {
      Schema included = include.getIncludedSchema();
      source.includes.add(included.getUri());
      new IncludeFinder(included);
    }
  }

  class RootMarker extends SchemaWalker {
    public void visitGroup(GroupDefinition def) {
    }

    public VoidValue visitElement(Element p) {
      NameInfo info = lookupElementName(p.getName());
      info.globalType = p;
      info.occur = NameInfo.OCCUR_ROOT;
      lookupTargetNamespace(p.getName().getNamespaceUri());
      return VoidValue.VOID;
    }
  }

  static class NamespaceUsage {
    int elementCount;
    int attributeCount;
    static boolean isBetter(NamespaceUsage n1, NamespaceUsage n2) {
      return (n1.elementCount > n2.elementCount
              || (n1.elementCount == n2.elementCount
                  && n1.attributeCount > n2.attributeCount));
    }
    public boolean equals(Object obj) {
      if (!(obj instanceof NamespaceUsage))
        return false;
      NamespaceUsage other = (NamespaceUsage)obj;
      return (elementCount == other.elementCount
              && attributeCount == other.attributeCount);
    }
  }

  class TargetNamespaceSelector extends SchemaWalker {
    private boolean nested;
    private final Map<String, NamespaceUsage> namespaceUsageMap = new HashMap<String, NamespaceUsage>();

    TargetNamespaceSelector(Schema schema) {
      schema.accept(this);
      lookupSourceUri(schema.getUri()).targetNamespace = selectTargetNamespace();
    }

    public VoidValue visitElement(Element element) {
      NamespaceUsage usage = getUsage(element.getName().getNamespaceUri());
      if (!nested)
        usage.elementCount++;
      boolean saveNested = nested;
      nested = true;
      element.getComplexType().accept(this);
      nested = saveNested;
      return VoidValue.VOID;
    }

    public VoidValue visitAttribute(Attribute a) {
      NamespaceUsage usage = getUsage(a.getName().getNamespaceUri());
      if (!nested)
        usage.attributeCount++;
      return VoidValue.VOID;
    }

    public VoidValue visitWildcardElement(WildcardElement p) {
      return visitWildcard(p.getWildcard());
    }

    public VoidValue visitWildcardAttribute(WildcardAttribute a) {
       return visitWildcard(a.getWildcard());
    }

    private VoidValue visitWildcard(Wildcard wc) {
      String ns = otherNamespace(wc);
      if (ns != null) {
        lookupTargetNamespace(ns);
        if (!nested)
          getUsage(ns).attributeCount++;
      }
      return VoidValue.VOID;
    }

    private NamespaceUsage getUsage(String ns) {
      NamespaceUsage usage = namespaceUsageMap.get(ns);
      if (usage == null) {
        usage = new NamespaceUsage();
        namespaceUsageMap.put(ns, usage);
        if (!ns.equals(""))
          lookupTargetNamespace(ns);
      }
      return usage;
    }

    public void visitInclude(Include include) {
      new TargetNamespaceSelector(include.getIncludedSchema());
    }

    String selectTargetNamespace() {
      Map.Entry<String,NamespaceUsage> best = null;
      for (Map.Entry<String, NamespaceUsage> tem : namespaceUsageMap.entrySet()) {
        if (best == null
            || NamespaceUsage.isBetter(tem.getValue(),
                                       best.getValue())
            // avoid output depending on order of hash table iteration
            || (tem.getValue().equals(best.getValue())
                && (tem.getKey()).compareTo(best.getKey()) < 0))
          best = tem;
      }
      namespaceUsageMap.clear();
      if (best == null)
        return null;
      String targetNamespace = best.getKey();
      // for "" case
      lookupTargetNamespace(targetNamespace);
      return targetNamespace;
    }
  }

  class GlobalElementSelector extends SchemaWalker {
    private final boolean absentTargetNamespace;
    private boolean nested = false;

    GlobalElementSelector(Schema schema) {
      absentTargetNamespace = getTargetNamespace(schema.getUri()).equals("");
      schema.accept(this);
    }

    public VoidValue visitElement(Element element) {
      Name name = element.getName();
      if (!name.getNamespaceUri().equals("") || absentTargetNamespace) {
        NameInfo info = lookupElementName(name);
        int occur = nested ? NameInfo.OCCUR_NESTED : NameInfo.OCCUR_TOP;
        if (occur > info.occur) {
          info.occur = occur;
          info.globalType = element;
        }
        else if (occur == info.occur && !element.equals(info.globalType))
          info.globalType = null;
      }
      boolean saveNested = nested;
      nested = true;
      element.getComplexType().accept(this);
      nested = saveNested;
      return VoidValue.VOID;
    }

    public void visitInclude(Include include) {
      new GlobalElementSelector(include.getIncludedSchema());
    }
  }

  class StructureMover extends SchemaWalker {
    private final String currentNamespace;

    StructureMover(String currentNamespace) {
      this.currentNamespace = currentNamespace;
    }

    public VoidValue visitElement(Element p) {
      NameInfo info = lookupElementName(p.getName());
      String ns = p.getName().getNamespaceUri();
      if (ns.equals(currentNamespace) || (ns.equals("") && !p.equals(info.globalType)))
        p.getComplexType().accept(this);
      else {
        noteMoved(info, p);
        moveStructure(p);
        p.getComplexType().accept(new StructureMover(ns));
      }
      return VoidValue.VOID;
    }

    public VoidValue visitAttribute(Attribute a) {
      String ns = a.getName().getNamespaceUri();
      if (!ns.equals("") && !ns.equals(currentNamespace)) {
        noteMoved(lookupAttributeName(a.getName()), a);
        moveStructure(a);
      }
      return VoidValue.VOID;
    }

    private void noteMoved(NameInfo info, Structure s) {
      if (info.occur < NameInfo.OCCUR_MOVE) {
        info.occur = NameInfo.OCCUR_MOVE;
        info.globalType = s;
      }
      else if (info.occur == NameInfo.OCCUR_MOVE && !s.equals(info.globalType))
        info.globalType = null;
    }

    private void moveStructure(Structure p) {
      TargetNamespace tn = lookupTargetNamespace(p.getName().getNamespaceUri());
      if (!tn.movedStructureSet.contains(p)) {
        tn.movedStructureSet.add(p);
        tn.movedStructures.add(p);
      }
    }

    public void visitInclude(Include include) {
      Schema included = include.getIncludedSchema();
      included.accept(new StructureMover(getTargetNamespace(included.getUri())));
    }

    public VoidValue visitWildcardElement(WildcardElement p) {
      return visitWildcard(p.getWildcard(), true);
    }

    public VoidValue visitWildcardAttribute(WildcardAttribute a) {
      return visitWildcard(a.getWildcard(), false);
    }

    private VoidValue visitWildcard(Wildcard wc, boolean isElement) {
      String ns = otherNamespace(wc);
      if (ns != null && !ns.equals(currentNamespace)) {
        TargetNamespace tn = lookupTargetNamespace(ns);
        if (isElement)
          tn.movedOtherElement = true;
        else
          tn.movedOtherAttribute = true;
      }
      return VoidValue.VOID;
    }
  }

  NamespaceManager(Schema schema, Guide guide, SourceUriGenerator sug) {
    this.schema = schema;
    new IncludeFinder(schema);
    schema.accept(new RootMarker());
    assignTargetNamespaces();
    new GlobalElementSelector(schema);
    findSubstitutionGroups(guide);
    chooseRootSchemas(sug);
    schema.accept(new StructureMover(getTargetNamespace(schema.getUri())));
  }

  private void assignTargetNamespaces() {
    new TargetNamespaceSelector(schema);
    // TODO maybe use info from <start> to select which targetNamespace of included schemas to use
    String ns = filterUpTargetNamespace(schema.getUri());
    if (ns == null) {
      lookupTargetNamespace("");
      lookupSourceUri(schema.getUri()).targetNamespace = "";
      ns = "";
    }
    inheritDownTargetNamespace(schema.getUri(), ns);
  }

  private String filterUpTargetNamespace(String sourceUri) {
    String ns = getTargetNamespace(sourceUri);
    if (ns != null)
      return ns;
    List<String> includes = lookupSourceUri(sourceUri).includes;
    if (includes.size() == 0)
      return null;
    Map<String, Integer> occurMap = new HashMap<String, Integer>();
    for (String include : includes) {
      String tem = filterUpTargetNamespace(include);
      if (tem != null) {
        Integer count = occurMap.get(tem);
        occurMap.put(tem, count == null ? 1 : count + 1);
      }
    }
    Map.Entry<String,Integer> best = null;
    boolean bestAmbig = false;
    for (Map.Entry<String, Integer> tem : occurMap.entrySet()) {
      if (best == null || tem.getValue() > best.getValue()) {
        best = tem;
        bestAmbig = false;
      }
      else if ((tem.getValue()).intValue() == (best.getValue()).intValue())
        bestAmbig = true;
    }
    if (best == null || bestAmbig)
      return null;
    ns = best.getKey();
    lookupSourceUri(sourceUri).targetNamespace = ns;
    return ns;
  }

  private void inheritDownTargetNamespace(String sourceUri, String targetNamespace) {
    for (String uri : lookupSourceUri(sourceUri).includes) {
      String ns = lookupSourceUri(uri).targetNamespace;
      if (ns == null) {
        ns = targetNamespace;
        lookupSourceUri(uri).targetNamespace = ns;
      }
      inheritDownTargetNamespace(uri, ns);
    }
  }

  private void chooseRootSchemas(SourceUriGenerator sug) {
    for (Map.Entry<String, TargetNamespace> entry : targetNamespaceMap.entrySet()) {
      String ns = entry.getKey();
      List<String> list = new Vector<String>();
      findRootSchemas(schema.getUri(), ns, list);
      if (list.size() == 1)
        (entry.getValue()).rootSchema = list.get(0);
      else {
        String sourceUri = sug.generateSourceUri(ns);
        lookupSourceUri(sourceUri).includes.addAll(list);
        lookupSourceUri(sourceUri).targetNamespace = ns;
        (entry.getValue()).rootSchema = sourceUri;
        schema.addInclude(sourceUri, schema.getEncoding(), null, null);
      }
    }
  }

  boolean isGlobal(Element element) {
    return element.equals(lookupElementName(element.getName()).globalType);
  }

  Element getGlobalElement(Name name) {
    NameInfo info = elementNameMap.get(name);
    if (info == null)
      return null;
    return (Element)info.globalType;
  }

  boolean isGlobal(Attribute attribute) {
    return attribute.equals(lookupAttributeName(attribute.getName()).globalType);
  }

  String getProxyName(Structure struct) {
    String ns = struct.getName().getNamespaceUri();
    TargetNamespace tn = lookupTargetNamespace(ns);
    String name = tn.movedStructureNameMap.get(struct);
    if (name == null) {
      name = generateName(ns, tn, struct.getName().getLocalName(), struct instanceof Element);
      tn.movedStructureNameMap.put(struct, name);
    }
    return name;
  }

  String getOtherElementName(String ns) {
    TargetNamespace tn = lookupTargetNamespace(ns);
    if (!tn.movedOtherElement)
      return null;
    if (tn.otherElementName == null)
      tn.otherElementName = generateName(ns, tn, "local", true);
    return tn.otherElementName;
  }

  String getOtherAttributeName(String ns) {
    TargetNamespace tn = lookupTargetNamespace(ns);
    if (!tn.movedOtherAttribute)
      return null;
    if (tn.otherAttributeName == null)
      tn.otherAttributeName = generateName(ns, tn, "local", false);
    return tn.otherAttributeName;
  }

  private String generateName(String ns, TargetNamespace tn, String base, boolean isElement) {
    Set<String> movedStructureNameSet = isElement ? tn.movedElementNameSet : tn.movedAttributeNameSet;
    String name = base;
    for (int n = 1;; n++) {
      if (!movedStructureNameSet.contains(name)) {
        Definition def;
        if (isElement)
          def = schema.getGroup(name);
        else
          def = schema.getAttributeGroup(name);
        if (def == null
            || !getTargetNamespace(def.getParentSchema().getUri()).equals(ns)
            || (def instanceof GroupDefinition
                && getElementNameForGroupRef((GroupDefinition)def) != null))
          break;
      }
      name = base + Integer.toString(n);
    }
    movedStructureNameSet.add(name);
    return name;
  }

  static class GroupDefinitionFinder extends SchemaWalker {
    final List<GroupDefinition> list = new Vector<GroupDefinition>();

    public void visitGroup(GroupDefinition def) {
      list.add(def);
    }

    static List<GroupDefinition> findGroupDefinitions(Schema schema) {
      GroupDefinitionFinder gdf = new GroupDefinitionFinder();
      schema.accept(gdf);
      return gdf.list;
    }
  }

  private void findSubstitutionGroups(Guide guide) {
    List<GroupDefinition> groups = GroupDefinitionFinder.findGroupDefinitions(schema);
    Map<Name, String> elementNameToGroupName = new HashMap<Name, String>();
    while (addAbstractElements(guide, groups, elementNameToGroupName))
      ;
    cleanSubstitutionGroupMap(elementNameToGroupName);
    cleanAbstractElementSubstitutionGroupMemberMap(elementNameToGroupName);
  }

  private boolean addAbstractElements(Guide guide, List<GroupDefinition> groups, Map<Name, String> elementNameToGroupName) {
    Set<Name> newAbstractElements = new HashSet<Name>();
    for (GroupDefinition def : groups) {
      if (guide.getGroupEnableAbstractElement(def.getName())
          && getGroupDefinitionAbstractElementName(def) == null) {
        Name elementName = abstractElementName(def);
        if (elementName != null) {
          List<Name> members = substitutionGroupMembers(def);
          if (members != null) {
            elementNameToGroupName.put(elementName, def.getName());
            addSubstitutionGroup(elementName, members, newAbstractElements);
          }
        }
      }
    }
    if (newAbstractElements.size() == 0)
      return false;
    for (Name name : newAbstractElements) {
      groupDefinitionAbstractElementMap.put(elementNameToGroupName.get(name), name);
    }
    return true;
  }

  private void addSubstitutionGroup(Name elementName, List<Name> members, Set<Name> newAbstractElements) {
    for (Name member : members) {
      Name old = getSubstitutionGroup(member);
      if (old != null && !old.equals(elementName)) {
        newAbstractElements.remove(old);
        return;
      }
      substitutionGroupMap.put(member, elementName);
    }
    newAbstractElements.add(elementName);
    abstractElementSubstitutionGroupMemberMap.put(elementName, members);
  }

  private void cleanSubstitutionGroupMap(Map<Name, String> elementNameToGroupName) {
    for (Iterator<Map.Entry<Object,Name>> iter = substitutionGroupMap.entrySet().iterator(); iter.hasNext();) {
      Map.Entry<Object,Name> entry = iter.next();
      Name head = entry.getValue();
      if (groupDefinitionAbstractElementMap.get(elementNameToGroupName.get(head)) == null)
        iter.remove();
    }
  }

  private void cleanAbstractElementSubstitutionGroupMemberMap(Map<Name, String> elementNameToGroupName) {
    for (Iterator<Name> iter = abstractElementSubstitutionGroupMemberMap.keySet().iterator(); iter.hasNext();) {
      if (groupDefinitionAbstractElementMap.get(elementNameToGroupName.get(iter.next())) == null)
        iter.remove();
    }
  }

  private Name abstractElementName(GroupDefinition def) {
    Name name = new Name(getTargetNamespace(def.getParentSchema().getUri()), def.getName());
    if (lookupElementName(name).globalType != null)
      return null;
    return name;
  }

  private List<Name> substitutionGroupMembers(GroupDefinition def) {
    if (def.getParticle() instanceof Element)
      return null;
    List<Name> members = new Vector<Name>();
    if (!particleMembers(def.getParticle(), members))
      return null;
    return members;
  }

  private boolean particleMembers(Particle child, List<Name> members) {
    if (child instanceof Element) {
      Element e = (Element)child;
      if (!isGlobal(e))
        return false;
      members.add(e.getName());
    }
    else if (child instanceof GroupRef) {
      Name name = getElementNameForGroupRef(schema.getGroup(((GroupRef)child).getName()));
      if (name == null)
        return false;
      members.add(name);
    }
    else if (child instanceof ParticleChoice) {
      for (Particle particle : ((ParticleChoice)child).getChildren()) {
        if (!particleMembers(particle, members))
          return false;
      }
    }
    else
      return false;
    return true;
  }

  Name getElementNameForGroupRef(GroupDefinition def) {
    Name abstractElementName = getGroupDefinitionAbstractElementName(def);
    if (abstractElementName != null)
      return abstractElementName;
    return getGroupDefinitionSingleElementName(def);
  }

  boolean isGroupDefinitionOmitted(GroupDefinition def) {
    return getGroupDefinitionSingleElementName(def) != null;
  }

  Name getGroupDefinitionAbstractElementName(GroupDefinition def) {
    return groupDefinitionAbstractElementMap.get(def.getName());
  }

  List<Name> getAbstractElementSubstitutionGroupMembers(Name name) {
    return abstractElementSubstitutionGroupMemberMap.get(name);
  }

  private Name getGroupDefinitionSingleElementName(GroupDefinition def) {
    Particle particle = def.getParticle();
    if (!(particle instanceof Element) || !isGlobal((Element)particle))
      return null;
    return ((Element)particle).getName();
  }

  Name getSubstitutionGroup(Name name) {
    return substitutionGroupMap.get(name);
  }

  String getTargetNamespace(String schemaUri) {
    return lookupSourceUri(schemaUri).targetNamespace;
  }

  boolean isTargetNamespace(String ns) {
    return targetNamespaceMap.get(ns) != null;
  }

  Set<String> getTargetNamespaces() {
    return targetNamespaceMap.keySet();
  }

  String getRootSchema(String targetNamespace) {
    return lookupTargetNamespace(targetNamespace).rootSchema;
  }

  List<Structure> getMovedStructures(String namespace) {
    return lookupTargetNamespace(namespace).movedStructures;
  }

  List<String> effectiveIncludes(String sourceUri) {
    String ns = getTargetNamespace(sourceUri);
    List<String> list = new Vector<String>();
    for (String uri : lookupSourceUri(sourceUri).includes)
      findRootSchemas(uri, ns, list);
    return list;
  }

  private void findRootSchemas(String sourceUri, String ns, List<String> list) {
    if (getTargetNamespace(sourceUri).equals(ns))
      list.add(sourceUri);
    else {
      for (String uri : lookupSourceUri(sourceUri).includes)
        findRootSchemas(uri, ns, list);
    }
  }

  private SourceUri lookupSourceUri(String uri) {
    SourceUri s = sourceUriMap.get(uri);
    if (s == null) {
      s = new SourceUri();
      sourceUriMap.put(uri, s);
    }
    return s;
  }

  private TargetNamespace lookupTargetNamespace(String ns) {
    TargetNamespace t = targetNamespaceMap.get(ns);
    if (t == null) {
      t = new TargetNamespace();
      targetNamespaceMap.put(ns, t);
    }
    return t;
  }

  private NameInfo lookupElementName(Name name) {
    NameInfo info = elementNameMap.get(name);
    if (info == null) {
      info = new NameInfo();
      elementNameMap.put(name, info);
    }
    return info;
  }

  private NameInfo lookupAttributeName(Name name) {
    NameInfo info = attributeNameMap.get(name);
    if (info == null) {
      info = new NameInfo();
      attributeNameMap.put(name, info);
    }
    return info;
  }

  static String otherNamespace(Wildcard wc) {
    if (wc.isPositive())
      return null;
    Set<String> namespaces = wc.getNamespaces();
    switch (namespaces.size()) {
    case 2:
      if (!namespaces.contains(""))
        return null;
      Iterator<String> iter = namespaces.iterator();
      String ns = iter.next();
      if (!ns.equals(""))
        return ns;
      return iter.next();
    case 1:
      if (namespaces.contains(""))
        return "";
    }
    return null;
  }

}


text:
package ma.glasnost.orika.test.concurrency.model;

import java.util.List;

public class ModelWithNestedObjSource {

    private List<NestedModel> value;

    public ModelWithNestedObjSource(List<NestedModel> value) {
        this.value = value;
    }

    public List<NestedModel> getValue() {
        return value;
    }

    public void setValue(List<NestedModel> value) {
        this.value = value;
    }
}


text:
    <md-checkbox [(ngModel)]="disableButtonRipples">Disable button ripples</md-checkbox>
    <button md-button [disableRipple]="disableButtonRipples">flat</button>
    <button md-raised-button [disableRipple]="disableButtonRipples">raised</button>
    <button md-fab [disableRipple]="disableButtonRipples">
      <md-icon>check</md-icon>
    </button>
    <button md-mini-fab [disableRipple]="disableButtonRipples">
      <md-icon>check</md-icon>
    </button>

<md-checkbox [(ngModel)]="centered">Centered</md-checkbox>

<md-checkbox [(ngModel)]="unbounded">Unbounded</md-checkbox>

<md-checkbox [(ngModel)]="disabled">Disabled</md-checkbox>

<md-checkbox [(ngModel)]="rounded">Rounded container (flaky in Firefox)</md-checkbox>

    Speed
    <md-radio-group [(ngModel)]="rippleSpeed">
      <md-radio-button name="demo-ripple-options" value="0.1">Slow</md-radio-button>
      <md-radio-button name="demo-ripple-options" value="1">Normal</md-radio-button>
      <md-radio-button name="demo-ripple-options" value="4">Fast</md-radio-button>
    </md-radio-group>

    <md-input placeholder="Max radius" aria-label="radius" [(ngModel)]="maxRadius"></md-input>
    <md-input placeholder="Ripple color" aria-label="color" [(ngModel)]="rippleColor"></md-input>
    <md-input placeholder="Ripple background" aria-label="background" [(ngModel)]="rippleBackgroundColor"></md-input>

    <button md-raised-button (click)="doManualRipple()">Manual ripple</button>

      Click me

  {{centered}} {{rounded}}


text:
#ifndef MUXABLE_VEC_H_
#define MUXABLE_VEC_H_

#include <src/types/transport_params_vec.h>
#include <deps/chaste/data_structs/vector/vector_typed_declare_template.h>

declare_ch_vector(CAMIO_MUXABLE_VEC,camio_muxable_t)
declare_ch_vector_cmp(CAMIO_MUXABLE_VEC,camio_muxable_t)

#endif /* MUXABLE_VEC_H_ */


text:
<?php

namespace ZendTest\Permissions\Acl\TestAsset\UseCase1;

use Zend\Permissions\Acl\Assertion\AssertionInterface;
use Zend\Permissions\Acl as ZendAcl;

class UserIsBlogPostOwnerAssertion implements AssertionInterface
{

    public $lastAssertRole = null;
    public $lastAssertResource = null;
    public $lastAssertPrivilege = null;
    public $assertReturnValue = true;

    public function assert(ZendAcl\Acl $acl, ZendAcl\Role\RoleInterface $user = null, ZendAcl\Resource\ResourceInterface $blogPost = null, $privilege = null)
    {
        $this->lastAssertRole      = $user;
        $this->lastAssertResource  = $blogPost;
        $this->lastAssertPrivilege = $privilege;
        return $this->assertReturnValue;
    }
}


text:
from open_vsdcli.vsd_common import *

@vsdcli.command(name='enterprise-list')
@click.option('--filter', metavar='<filter>',
              help='Filter for name, description, lastUpdatedDate, '
                   'creationDate, externalID')
@click.pass_context
def enterprise_list(ctx, filter):
    """Show all enterprise within the VSD"""
    result = ctx.obj['nc'].get("enterprises", filter=filter)
    table = PrettyTable(["Enterprise ID", "Name"])
    for line in result:
        table.add_row([line['ID'],
                       line['name']])
    print(table)

@vsdcli.command(name='enterprise-show')
@click.argument('enterprise-id', metavar='<enterprise-id>', required=True)
@click.pass_context
def enterprise_show(ctx, enterprise_id):
    """Show information for a given enterprise id"""
    result = ctx.obj['nc'].get("enterprises/%s" % enterprise_id)[0]
    print_object(result, exclude=['APIKey'], only=ctx.obj['show_only'])

@vsdcli.command(name='enterprise-create')
@click.argument('name', metavar='<name>', required=True)
@click.pass_context
def enterprise_create(ctx, name):
    """Add an enterprise to the VSD"""
    params = {}
    params['name'] = name
    result = ctx.obj['nc'].post("enterprises", params)[0]
    print_object(result, only=ctx.obj['show_only'])

@vsdcli.command(name='enterprise-delete')
@click.argument('enterprise-id', metavar='<enterprise ID>', required=True)
@click.confirmation_option(prompt='Are you sure ?')
@click.pass_context
def enterprise_delete(ctx, enterprise_id):
    """Delete a given enterprise"""
    ctx.obj['nc'].delete("enterprises/%s?responseChoice=1" % enterprise_id)

@vsdcli.command(name='enterprise-update')
@click.argument('enterprise-id', metavar='<enterprise ID>', required=True)
@click.option('--key-value', metavar='<key:value>', multiple=True)
@click.pass_context
def enterprise_update(ctx, enterprise_id, key_value):
    """Update key/value for a given enterprise"""
    params = {}
    for kv in key_value:
        key, value = kv.split(':', 1)
        params[key] = value
    ctx.obj['nc'].put("enterprises/%s" % enterprise_id, params)
    result = ctx.obj['nc'].get("enterprises/%s" % enterprise_id)[0]
    print_object(result, only=ctx.obj['show_only'])

@vsdcli.command(name='enterprisepermission-list')
@click.option('--redundancygroup-id', metavar='<id>')
@click.option('--gateway-id', metavar='<id>')
@click.option('--vlan-id', metavar='<id>')
@click.option('--service-id', metavar='<id>')
@click.option('--port-id', metavar='<id>')
@click.option('--filter', metavar='<filter>',
              help='Filter for name, lastUpdatedDate, creationDate, '
                   'externalID')
@click.pass_context
def enterprisepermission_list(ctx, filter, **ids):
    """List all Enterprise Permission for a CSP entity"""
    id_type, id = check_id(**ids)
    request = "%ss/%s/enterprisepermissions" % (id_type, id)
    if not filter:
        result = ctx.obj['nc'].get(request)
    else:
        result = ctx.obj['nc'].get(request, filter=filter)
    table = PrettyTable(["ID",
                         "Action",
                         "Entity ID",
                         "Entity type",
                         "Entity name"])
    for line in result:
        table.add_row([line['ID'],
                       line['permittedAction'],
                       line['permittedEntityID'],
                       line['permittedEntityType'],
                       line['permittedEntityName']])
    print(table)

@vsdcli.command(name='enterprisepermission-show')
@click.argument('enterprisepermission-id', metavar='<enterprisepermission-id>',
                required=True)
@click.pass_context
def enterprisepermission_show(ctx, permission_id):
    """Show information for a given enterprisepermission id"""
    result = ctx.obj['nc'].get("enterprisepermissions/%s" %
                               enterprisepermission_id)[0]
    print_object(result, only=ctx.obj['show_only'])

@vsdcli.command(name='enterprisepermission-create')
@click.argument('entity-id', metavar='<group or user ID>', required=True)
@click.option('--action', type=click.Choice(['USE',
                                             'EXTEND',
                                             'READ',
                                             'INSTANTIATE']),
              default='USE', help='Default : USE')
@click.option('--redundancygroup-id', metavar='<id>')
@click.option('--gateway-id', metavar='<id>')
@click.option('--vlan-id', metavar='<id>')
@click.option('--service-id', metavar='<id>')
@click.option('--port-id', metavar='<id>')
@click.pass_context
def enterprisepermission_create(ctx, entity_id, action, **ids):
    """Add permission for a given element (gateway, vlan, etc...)"""
    id_type, id = check_id(**ids)
    params = {}
    params['permittedEntityID'] = entity_id
    params['permittedAction'] = action
    ctx.obj['nc'].post("%ss/%s/enterprisepermissions" % (id_type, id), params)


text:
package com.funtl.framework.track.kdniao.query.unifiedorder.request;

/**
 * Created by 金勇 on 2016-12-02.
 * 因为返回的JSON 的 Key 的首字母为大写字母,所以以下的属性 首字母也是大写,方便解析
 */
public class QueryUnifiedorderRequest {
	/**
	 * 订单编号	O
	 */
	private String orderCode;
	/**
	 * 快递公司编码	R
	 */
	private String shipperCode;
	/**
	 * 物流单号	R
	 */
	private String logisticCode;

	public String getOrderCode() {
		return orderCode;
	}

	public void setOrderCode(String orderCode) {
		this.orderCode = orderCode;
	}

	public String getShipperCode() {
		return shipperCode;
	}

	public void setShipperCode(String shipperCode) {
		this.shipperCode = shipperCode;
	}

	public String getLogisticCode() {
		return logisticCode;
	}

	public void setLogisticCode(String logisticCode) {
		this.logisticCode = logisticCode;
	}
}


text:
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Address',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('street', models.CharField(max_length=255)),
                ('postal_code', models.CharField(max_length=5)),
            ],
        ),
    ]


text:
layout: post
date: 2011-08-08
time: "09:00:00"
author: "Greg Wilson"
title: Introducing Programming a Different Way
category: ["Content"]
---

Our quick introduction to Python is the module I'm least happy with, so I've been thinking about how to re-design it. I've included a new outline below; comments would be very welcome.

Programming is what you do when you can't find an off-the-shelf tool to do what you want

Scientists' needs are so specialized that there often isn't such a tool

Even if it exists, the cost of finding it may be too high (can't Google by semantics)

Why is programming hard to teach/learn?

Trying to convey three things at once:

Here's something interesting tha tyou might actually want to do.

Here's the syntax of whatever programming language we're using.

Here are some key ideas about programs and programming that will help you do things.

#1 is what engages your interest

#2 is what you'll grapple with (and will need to master in order to do #1)

#3 is what's most useful in the long term

But it's hard or impossible to learn the general without first learning some specifics

And you have deadlines: getting that graph plotted is more important right now than the big picture

We will teach basic programming by example

Show you small programs, then explain the things they contain

Also explain a few principles along the way

We will use Python

Widely used for scientific programming, but that's not the main reason

Our experience is that novices find it more readable than alternatives

And it allows us to do useful things before introducing advanced concepts (e.g., OOP)

Will not start with multimedia programming, 3D graphics, etc.

Guzdial et al have found that it's more engaging for students

But getting those packages installed (and for us, maintaining them) is hard work

We assume that you've done some programming, in some language, at some point

Have at least heard terms like "variable", "loop", "if/else", "array"

Quick test: can you read a list of numbers, one per line, and print the least and greatest?

Before we dive in, what is a program?

Cynical answer: "anything that might contain bugs"

Classic answer: "Instructions for a computer"

Our answer adds: "...that a human being can understand"

Takes a lot of work to turn the things we write into instructions a computer can execute

Time to solution is (time to write code that's correct) + (time for that code to execute)

The latter halves every 18 months (Moore's Law)

The former depends on human factors that change on a scale of years (languages) or generations (psychology)

Programs store data and do calculations

Use variables for the first

Write instructions that use those variables to describe the second

Put the following in a text file (not Word) and run it

# Convert temperature in Fahrenheit to Kelvin.
temp_in_f = 98.6
temp_in_k = (temp_in_f - 32.0) * (5.0 / 9.0) + 273.15
print "body temperature in Kelvin:", temp_in_k
body temperature in Kelvin: 310.15

Variable is a name that labels a value (picture)

Created by assignment

[Box] versus declaration (static typing) or create-by-read (and why the latter is bad)

Usual rules of arithmetic: * before +, parentheses

Print displays values

Put text (character strings) in quotes

Print automatically puts a space between values, and ends the line

Need to know it: use "5/9" instead of "5.0/9.0"

# Convert temperature in Fahrenheit to Kelvin.
temp_in_f = 98.6
temp_in_k = (temp_in_f - 32.0) * (5 / 9) + 273.15  # this line is different
print "body temperature in Kelvin:", temp_in_k
body temperature in Kelvin: 273.15

Run interpreter, try 5/9, get 0

Shows that Python can be used interactively

Integer vs. float, and what division does

Automatic conversion: 5.0/9 does the right thing

[Box] Why are so many decimal places shown in 5.0/9

Need to know it: sometimes Python doesn't know what to do

# Try adding numbers and strings.
print "2 + 3:", 2 + 3
print "two + three:", "two" + "three"
print "2 + three:", 2 + "three"
2 + 3: 5 two + three: twothree 2 + three: Traceback (most recent call last): File "add-numbers-strings.py", line 5, in <module> print "2 + three:", 2 + "three" TypeError: unsupported operand type(s) for +: 'int' and 'str'

In this case, "2three" would be sensible

But what about "1" + 2?

The character "1" is not the number 1

On your own, try "two" * 3

Back to useful things

Computers are useful because they can do lots of calculations on lots of data

Which means we need a concise way to represent multiple values and multiple steps

Writing out a million additions would take longer than doing them

# Find the mean.
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]
total = 0
number = 0
for value in data:
    total = total + value
    number = number + 1
mean = total / number
print "mean is", mean
mean is 2

Use list to store multiple values

Like a vector in mathematics

Use loop to perform multiple operations

Like Σ in mathematics

But we have to break it down into sequential steps

And since we're doing that, have to be able to update variables's values

Can trace execution step by step manually or in a debugger

An important skill

Want to write programs so that tracing is easy

See what this means when we talk about functions

Did you notice that the result in the example above is wrong?

25/9 is 2, but 25.0/9.0 is 2.77777777778

Problem is that total starts as an integer, we're adding integers, we wind up doing int/int (again)

Could fix it by initializing total to 0.0

Or use a function to do the conversion explicitly

# Find the mean.
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]
total = 0
number = 0
for value in data:
    total = total + value
    number = number + 1
mean = float(total) / number   # this line has changed
print "mean is", mean
mean is 2.77777777778

Functions do what they do in mathematics

Values in, values out

Spend a whole chapter on them, since they're key to building large programs

Right now, most important lesson is that just because a program runs, doesn't mean it's correct

Could check the original program by using a smaller data set

E.g., [1, 4] produces 2 instead of 2.5

Writing programs so that they're checkable is a big idea that we'll return to

Need to know it: the len function

# Find the mean.
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]
total = 0
for value in data:
    total = total + value
mean = float(total) / len(data) # this line has changed
print "mean is", mean
mean is 2.77777777778

Need to know it: list are mutable

# Calculate running sum by creating new list.
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]
result = []
current = 0
for value in data:
    current = current + value
    result.append(current)
print "running total:", result
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]

Start with the empty list

result.append is a method

Like a function, but attached to some kind of object like a list

noun and verb

Important enough that we'll spend a whole chapter on this, too

How to double the values in place?

# Try to double the values in place.
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]
for value in data:
    value = 2 * value
print "doubled data is:", data
doubled data is [1, 4, 2, 3, 3, 4, 3, 4, 1]

New values are being created, but never assigned to list elements

Easiest to understand with a picture

Need to know it: list indexing

Mathematicians use subscripts, we use square brackets

Index from 0..N-1 rather than 1..N for reasons that made sense in 1970 and have become customary since

Python and Java use 0..N-1 (like C)

Fortran and MATLAB use 1..N (like human beings)

# Try to double the values in place.
data = [1, 4, 2]
data[0] = 2 * data[0]
data[1] = 2 * data[1]
data[2] = 2 * data[2]
print "doubled data is:", data
doubled data is [2, 8, 4]

Clearly doesn't scale...

Need to get all the indices for a list of length N

The range function produces a list of numbers from 0..N-1

Examples

Exactly the indices for a list

You will almost never be the first person to need something

It's probably in the language, or in a library

Hard part is finding it...

# Double the values in a list in place
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]
length = len(data) # 9
indices = range(length) # [0, 1, 2, 3, 4, 5, 6, 7, 8]
for i in indices:
    data[i] = 2 * data[i]
print "doubled data is:", data
doubled data is: [2, 8, 4, 6, 6, 8, 6, 8, 2]

Fold this together by combining function calls (like \sqrt{sin(x)})

# Double the values in a list in place.
data = [1, 4, 2, 3, 3, 4, 3, 4, 1]
for i in range(len(data)):
    data[i] = 2 * data[i]
print "doubled data is:", data
doubled data is: [2, 8, 4, 6, 6, 8, 6, 8, 2]

Usually won't type in our data

Store it outside program

[Box] Explain difference between memory, local disk, and remote disk

And why we don't do everything one way or the other: performance vs. cost

# Count the number of lines in a file
reader = open("data.txt", "r")
number = 0
for line in reader:
    number = number + 1
reader.close()
print number, "values in file"
9 lines in file

What about mean?

# Find the mean.
reader = open("data.txt", "r")
total = 0.0
number = 0
for line in reader:
    total = total + line
    number = number + 1
reader.close()
print "mean is", total / number
Traceback (most recent call last): File "mean-read-broken.py", line 7, in <module> total = total + line TypeError: unsupported operand type(s) for +: 'float' and 'str'

Data in file is text, so we need to convert

# Find the mean.
reader = open("data.txt", "r")
total = 0.0
number = 0
for line in reader:
    value = float(line)
    total = total + value
    number = number + 1
reader.close()
print "mean is", total / number
mean is 2.77777777778

Notice that we're using the original program as an oracle

Pro: start simple, make more complex, confidence at each step

Con: bug in original perpetuated indefinitely

Real-world data is never clean

Count how many scores were not between 0 and 5

# Count number of values out of range.
data = [0, 3, 2, -1, 1, 4, 4, 6, 5, 5, 6]
num_outliers = 0
for value in data:
    if value < 0:         num_outliers = num_outliers + 1     if value > 5:
        num_outliers = num_outliers + 1
print num_outliers, "values out of range"
3 values out of range

Need to know it: combine tests using and and or

# Count number of values out of range.
data = [0, 3, 2, -1, 1, 4, 4, 6, 5, 5, 6]
num_outliers = 0
for value in data:
    if (value < 0) or (value > 5):
        num_outliers = num_outliers + 1
print num_outliers, "values out of range"
3 values out of range

Need to know it: in-place operators

# Count number of values out of range.
data = [0, 3, 2, -1, 1, 4, 4, 6, 5, 5, 6]
num_outliers = 0
for value in data:
    if (value < 0) or (value > 5):
        num_outliers += 1
print num_outliers, "values out of range"
3 values out of range

Don't actually "need" to know it

But it's a common idiom in many languages

Data cleanup

Values are supposed to be monotonic increasing

Check that they are, report where it fails if they're not

# Report where values are not monotonically inreasing
data = [1, 2, 2, 3, 4, 4, 5, 6, 5, 6, 7, 7, 8]
for i in range(2, len(data)):
    if data[i] < data[i-1]:
        print "failure:", i
    i = i + 1
failure: 8

Group by threes

# Combine successive triples of data.
data = [1, 2, 2, 3, 4, 4, 5, 6, 5, 6, 7, 7, 8]
result = []
for i in range(0, len(data), 3):
    sum = data[i] + data[i+1] + data[i+2]
    result.append(sum)
print "grouped data:", result
Traceback (most recent call last): File "group-by-threes-fails.py", line 6, in <module> sum = data[i] + data[i+1] + data[i+2] IndexError: list index out of range

13 values = 4 groups of 3 and 1 left over

First question must be, what's the right thing to do scientifically?

Let's assume, "Add up as many as are there"

# Combine successive triples of data.
data = [1, 2, 2, 3, 4, 4, 5, 6, 5, 6, 7, 7, 8]
result = []
for i in range(0, len(data), 3):
    sum = data[i]
    if (i+1) < len(data):
        sum += data[i+1]
    if (i+2) < len(data):
        sum += data[i+2]
    result.append(sum)
print "grouped data:", result
grouped data: [5, 11, 16, 20, 8]

But this is clumsy

How do we add up the first three, or as many as are there?

Don't want to have to keep modifying the list as we try out ideas

So use a list of lists.

# Add up the first three, or as many as are there.
test_cases = [[],                     # no data at all
              [10],                   # just one value
              [10, 20],               # two values
              [10, 20, 30],           # three
              [10, 20, 30, 40]]       # more than enough

for data in test_cases:
    print data
[] [10] [10, 20] [10, 20, 30] [10, 20, 30, 40]

Can now try all our tests by running one program

Back to our original problem: sum of at most the first three

# Sum up at most the first three values.
test_cases = [[],                     # no data at all
              [10],                   # just one value
              [10, 20],               # two values
              [10, 20, 30],           # three
              [10, 20, 30, 40]]       # more than enough

for data in test_cases:
    limit = min(3, len(data))
    sum = 0
    for i in range(limit):
        sum += data[i]
    print data, "=>", sum
[] => 0 [10] => 10 [10, 20] => 30 [10, 20, 30] => 60 [10, 20, 30, 40] => 60

That looks right

Though if there were 100 tests cases, we would want different output

Come back to this idea later

Need one more tool: nested loops

# Loops can run inside loops.
for i in range(4):
    for j in range(i):
        print i, j
1 0 2 0 2 1 3 0 3 1 3 2

Easiest to understand with a picture

Final step: instead of starting at zero every time, start at 0, 3, 6, 9, etc.

Need more test cases

Don't need to test everything (which is why we skip from 40 to 60 to 80)

We'll come back to how we decide what is or isn't a useful test case

# Sum up in groups of three.
test_cases = [[],
              [10],
              [10, 20],
              [10, 20, 30],
              [10, 20, 30, 40],
              [10, 20, 30, 40, 50, 60],
              [10, 20, 30, 40, 50, 60, 70, 80]]

for data in test_cases:
    result = []
    for i in range(0, len(data), 3):
        limit = min(i+3, len(data))
        sum = 0
        for i in range(i, limit):
            sum += data[i]
        result.append(sum)
    print data, "=>", result
[] => [] [10] => [10] [10, 20] => [30] [10, 20, 30] => [60] [10, 20, 30, 40] => [60, 40] [10, 20, 30, 40, 50, 60] => [60, 150] [10, 20, 30, 40, 50, 60, 70, 80] => [60, 150, 150]

Understand this in pieces

Outer for loop is selecting a test case

So think about its body in terms of one test case

Inner loop is going in strides of three

So think about its body for some arbitrary value of i

limit is as far as we can go toward three values up from i

So range(i, limit) guaranteed to be valid indices for list

Human beings can only keep a few things in working memory at once

"Seven plus or minus two"

How we actually understand this program is:

for data in test_cases:
    result = sum_by_threes(data)
    print data, "=>", result

to sum_by_threes given a list data:
    result = []
    for i in range(0, len(data), 3):
        limit = min(i+3, len(data))
        sum = sum_from(data, i, limit)
        result.append(sum)

to sum_from given a list data, and start and end indices:
    sum = 0
    for i in range(start, end):
        sum += data[i]

The computer doesn't care one way or another

But what we need is a way to write our programs in pieces, then combine the pieces

That's the subject of the next chapter


text:
#include "tile/tileManager.h"

#include "data/tileSource.h"
#include "map.h"
#include "platform.h"
#include "tile/tile.h"
#include "tile/tileCache.h"
#include "util/mapProjection.h"
#include "view/view.h"

#include "glm/gtx/norm.hpp"

#include <algorithm>

#define DBG(...) LOG(__VA_ARGS__)

namespace Tangram {

enum class TileManager::ProxyID : uint8_t {
    no_proxies = 0,
    child1 = 1 << 0,
    child2 = 1 << 1,
    child3 = 1 << 2,
    child4 = 1 << 3,
    parent = 1 << 4,
    parent2 = 1 << 5,
};

struct TileManager::TileEntry {

    TileEntry(std::shared_ptr<Tile>& _tile)
        : tile(_tile), m_proxyCounter(0), m_proxies(0), m_visible(false) {}

    ~TileEntry() { clearTask(); }

    std::shared_ptr<Tile> tile;
    std::shared_ptr<TileTask> task;

    /* A Counter for number of tiles this tile acts a proxy for */
    int32_t m_proxyCounter;

    /* The set of proxy tiles referenced by this tile */
    uint8_t m_proxies;
    bool m_visible;

    bool isInProgress() {
        return bool(task) && !task->isCanceled();
    }

    bool isCanceled() {
        return bool(task) && task->isCanceled();
    }

    bool needsLoading() {
        if (bool(tile)) { return false; }
        if (!task) { return true; }
        if (task->isCanceled()) { return false; }
        if (task->needsLoading()) { return true; }

        for (auto& subtask : task->subTasks()) {
            if (subtask->needsLoading()) { return true; }
        }
        return false;
    }

    // Complete task only when
    // - task still exists
    // - task has a tile ready
    // - tile has all rasters set
    bool completeTileTask() {
        if (bool(task) && task->isReady()) {

            for (auto& rTask : task->subTasks()) {
                if (!rTask->isReady()) { return false; }
            }

            task->complete();
            tile = task->getTile();
            task.reset();

            return true;
        }
        return false;
    }

    void clearTask() {
        if (task) {
            for (auto& raster : task->subTasks()) {
                raster->cancel();
            }
            task->subTasks().clear();
            task->cancel();

            task.reset();
        }
    }

    /* Methods to set and get proxy counter */
    int getProxyCounter() { return m_proxyCounter; }
    void incProxyCounter() { m_proxyCounter++; }
    void decProxyCounter() { m_proxyCounter = m_proxyCounter > 0 ? m_proxyCounter - 1 : 0; }
    void resetProxyCounter() { m_proxyCounter = 0; }

    bool setProxy(ProxyID id) {
        if ((m_proxies & static_cast<uint8_t>(id)) == 0) {
            m_proxies |= static_cast<uint8_t>(id);
            return true;
        }
        return false;
    }

    bool unsetProxy(ProxyID id) {
        if ((m_proxies & static_cast<uint8_t>(id)) != 0) {
            m_proxies &= ~static_cast<uint8_t>(id);
            return true;
        }
        return false;
    }

    /* Method to check whther this tile is in the current set of visible tiles
     * determined by view::updateTiles().
     */
    bool isVisible() const {
        return m_visible;
    }

    void setVisible(bool _visible) {
        m_visible = _visible;
    }
};

TileManager::TileSet::TileSet(std::shared_ptr<TileSource> _source, bool _clientSource) :
    source(_source), clientTileSource(_clientSource) {}

TileManager::TileSet::~TileSet() {
    cancelTasks();
}

void TileManager::TileSet::cancelTasks() {
    for (auto& tile : tiles) {
        auto& entry = tile.second;
        if (entry.isInProgress()) {
            source->cancelLoadingTile(*entry.task);
        }
        entry.clearTask();
    }
}

TileManager::TileManager(Platform& platform, TileTaskQueue& _tileWorker) :
    m_workers(_tileWorker) {

    m_tileCache = std::unique_ptr<TileCache>(new TileCache(DEFAULT_CACHE_SIZE));

    // Callback to pass task from Download-Thread to Worker-Queue
    m_dataCallback = TileTaskCb{[&](std::shared_ptr<TileTask> task) {

        if (task->isReady()) {
             platform.requestRender();

        } else if (task->hasData()) {
            m_workers.enqueue(task);

        } else {
            task->cancel();
        }
    }};
}

TileManager::~TileManager() {
    m_tileSets.clear();
}

void TileManager::setTileSources(const std::vector<std::shared_ptr<TileSource>>& _sources) {

    m_tileCache->clear();

    // Remove all (non-client datasources) sources and respective tileSets not present in the
    // new scene
    auto it = std::remove_if(
        m_tileSets.begin(), m_tileSets.end(),
        [&](auto& tileSet) {
            if (!tileSet.clientTileSource) {
                LOGN("Remove source %s", tileSet.source->name().c_str());
                return true;
            }
            // Clear cache
            tileSet.tiles.clear();
            return false;
        });

    m_tileSets.erase(it, m_tileSets.end());

    // add new sources
    for (const auto& source : _sources) {

        // ignore sources not used to generate tile geometry
        if (!source->generateGeometry()) { continue; }

        if (std::find_if(m_tileSets.begin(), m_tileSets.end(),
                         [&](const TileSet& a) {
                             return a.source->name() == source->name();
                         }) == m_tileSets.end()) {
            LOGW("add source %s", source->name().c_str());
            m_tileSets.push_back({ source, false });
        } else {
            LOGW("Duplicate named datasource (not added): %s", source->name().c_str());
        }
    }
}

std::shared_ptr<TileSource> TileManager::getClientTileSource(int32_t _sourceId) {
    auto it = std::find_if(m_tileSets.begin(), m_tileSets.end(),
         [&](auto& ts) { return ts.source->id() == _sourceId; });

    if (it != m_tileSets.end()) {
        return it->source;
    }
    return nullptr;
}

void TileManager::addClientTileSource(std::shared_ptr<TileSource> _tileSource) {
    auto it = std::find_if(m_tileSets.begin(), m_tileSets.end(),
        [&](auto& ts) { return ts.source->id() == _tileSource->id(); });

    if (it == m_tileSets.end()) {
        m_tileSets.emplace_back(_tileSource, true);
    }
}

bool TileManager::removeClientTileSource(int32_t _sourceId) {

    auto it = std::find_if(m_tileSets.begin(), m_tileSets.end(),
                           [&](auto& ts) { return ts.source->id() == _sourceId; });

    if (it != m_tileSets.end()) {
        m_tileSets.erase(it);
        return true;
    }
    return false;
}

void TileManager::cancelTileTasks() {

    for (auto& tileSet : m_tileSets) {
        for (auto& tile : tileSet.tiles) {
            tile.second.clearTask();
        }
        tileSet.source->clearData();
    }

    m_tileCache->clear();
}

void TileManager::clearTileSets(bool clearSourceCaches) {

    for (auto& tileSet : m_tileSets) {
        tileSet.cancelTasks();

        tileSet.tiles.clear();

        if (clearSourceCaches) {
            tileSet.source->clearData();
        }
    }

    m_tileCache->clear();
}

void TileManager::clearTileSet(int32_t _sourceId) {
    for (auto& tileSet : m_tileSets) {
        if (tileSet.source->id() != _sourceId) { continue; }

        tileSet.cancelTasks();
        tileSet.tiles.clear();
    }

    m_tileCache->clear();
    m_tileSetChanged = true;
}

void TileManager::updateTileSets(const View& _view) {

    m_tiles.clear();
    m_tilesInProgress = 0;
    m_tileSetChanged = false;

    if (!getDebugFlag(DebugFlags::freeze_tiles)) {

        for (auto& tileSet : m_tileSets) {
            tileSet.visibleTiles.clear();
        }

        auto tileCb = [&, zoom = _view.getZoom()](TileID _tileID){
            for (auto& tileSet : m_tileSets) {
                auto zoomBias = tileSet.source->zoomBias();
                auto maxZoom = tileSet.source->maxZoom();

                // Insert scaled and maxZoom mapped tileID in the visible set
                tileSet.visibleTiles.insert(_tileID.zoomBiasAdjusted(zoomBias).withMaxSourceZoom(maxZoom));
            }
        };

        _view.getVisibleTiles(tileCb);
    }

    for (auto& tileSet : m_tileSets) {
        // check if tile set is active for zoom (zoom might be below min_zoom)
        if (tileSet.source->isActiveForZoom(_view.getZoom()) && tileSet.source->isVisible()) {
            updateTileSet(tileSet, _view.state());
        }
    }

    loadTiles();

    // Make m_tiles an unique list of tiles for rendering sorted from
    // high to low zoom-levels.
    std::sort(m_tiles.begin(), m_tiles.end(), [](auto& a, auto& b) {
            return a->sourceID() == b->sourceID() ?
                a->getID() < b->getID() :
                a->sourceID() < b->sourceID(); }
        );

    // Remove duplicates: Proxy tiles could have been added more than once
    m_tiles.erase(std::unique(m_tiles.begin(), m_tiles.end()), m_tiles.end());
}

void TileManager::updateTileSet(TileSet& _tileSet, const ViewState& _view) {

    bool newTiles = false;

    if (_tileSet.sourceGeneration != _tileSet.source->generation()) {
        _tileSet.sourceGeneration = _tileSet.source->generation();
    }

    // Tile load request above this zoom-level will be canceled in order to
    // not wait for tiles that are too small to contribute significantly to
    // the current view.
    int maxZoom = glm::round(_view.zoom + 1.f);
    int minZoom = glm::round(_view.zoom - 2.f);

    std::vector<TileID> removeTiles;
    auto& tiles = _tileSet.tiles;

    // Check for ready tasks, move Tile to active TileSet and unset Proxies.
    for (auto& it : tiles) {
        auto& entry = it.second;
        if (entry.completeTileTask()) {
            clearProxyTiles(_tileSet, it.first, entry, removeTiles);

            newTiles = true;
            m_tileSetChanged = true;
        }
    }

    const auto& visibleTiles = _tileSet.visibleTiles;

    // Loop over visibleTiles and add any needed tiles to tileSet
    auto curTilesIt = tiles.begin();
    auto visTilesIt = visibleTiles.begin();

    auto generation = _tileSet.source->generation();

    while (visTilesIt != visibleTiles.end() || curTilesIt != tiles.end()) {

        auto& visTileId = visTilesIt == visibleTiles.end()
            ? NOT_A_TILE : *visTilesIt;

        auto& curTileId = curTilesIt == tiles.end()
            ? NOT_A_TILE : curTilesIt->first;

        if (visTileId == curTileId) {
            // tiles in both sets match
            assert(visTilesIt != visibleTiles.end() &&
                   curTilesIt != tiles.end());

            auto& entry = curTilesIt->second;
            entry.setVisible(true);

            if (entry.tile) {
                m_tiles.push_back(entry.tile);
            } else if (entry.needsLoading()) {
                // Not yet available - enqueue for loading
                if (!entry.task) {
                    entry.task = _tileSet.source->createTask(visTileId);
                }
                enqueueTask(_tileSet, visTileId, _view);
            }

            // NB: Special handling to update tiles from ClientDataSource.
            // Can be removed once ClientDataSource is immutable
            if (entry.tile) {
                auto sourceGeneration = entry.tile->sourceGeneration();
                if ((sourceGeneration < generation) && !entry.isInProgress()) {
                    // Tile needs update - enqueue for loading
                    entry.task = _tileSet.source->createTask(visTileId);
                    enqueueTask(_tileSet, visTileId, _view);
                }
            } else if (entry.isCanceled()) {
                auto sourceGeneration = entry.task->sourceGeneration();
                if (sourceGeneration < generation) {
                    // Tile needs update - enqueue for loading
                    entry.task = _tileSet.source->createTask(visTileId);
                    enqueueTask(_tileSet, visTileId, _view);
                }
            }

            if (entry.isInProgress()) {
                m_tilesInProgress++;
            }

            if (newTiles && entry.isInProgress()) {
                // check again for proxies
                updateProxyTiles(_tileSet, visTileId, entry);
            }

            ++curTilesIt;
            ++visTilesIt;

        } else if (curTileId > visTileId) {
            // tileSet is missing an element present in visibleTiles
            // NB: if (curTileId == NOT_A_TILE) it is always > visTileId
            //     and if curTileId > visTileId, then visTileId cannot be
            //     NOT_A_TILE. (for the current implementation of > operator)
            assert(visTilesIt != visibleTiles.end());

            if (!addTile(_tileSet, visTileId)) {
                // Not in cache - enqueue for loading
                enqueueTask(_tileSet, visTileId, _view);
                m_tilesInProgress++;
            }

            ++visTilesIt;

        } else {
            // tileSet has a tile not present in visibleTiles
            assert(curTilesIt != tiles.end());

            auto& entry = curTilesIt->second;

            if (entry.getProxyCounter() > 0) {
                if (entry.tile) {
                    m_tiles.push_back(entry.tile);
                } else if (entry.isInProgress()) {
                    if (curTileId.z >= maxZoom || curTileId.z <= minZoom) {
                        // Cancel tile loading but keep tile entry for referencing
                        // this tiles proxy tiles.
                        _tileSet.source->cancelLoadingTile(*entry.task);
                        entry.clearTask();
                    }
                }
            } else {
                removeTiles.push_back(curTileId);
            }
            entry.setVisible(false);
            ++curTilesIt;
        }
    }

    while (!removeTiles.empty()) {
        auto it = tiles.find(removeTiles.back());
        removeTiles.pop_back();

        if ((it != tiles.end()) && (!it->second.isVisible()) &&
            (it->second.getProxyCounter() <= 0)) {
            clearProxyTiles(_tileSet, it->first, it->second, removeTiles);
            removeTile(_tileSet, it);
        }
    }

    for (auto& it : tiles) {
        auto& entry = it.second;

#if 0 && LOG_LEVEL >= 3
        size_t rasterLoading = 0;
        size_t rasterDone = 0;
        if (entry.task) {
            for (auto &raster : entry.task->subTasks()) {
                if (raster->isReady()) { rasterDone++; }
                else { rasterLoading++; }
            }
        }
        DBG("> %s - ready:%d proxy:%d/%d loading:%d rDone:%d rLoading:%d canceled:%d",
             it.first.toString().c_str(),
             bool(entry.tile),
             entry.getProxyCounter(),
             entry.m_proxies,
             entry.task && !entry.task->isReady(),
             rasterDone,
             rasterLoading,
             entry.task && entry.task->isCanceled());
#endif

        if (entry.isInProgress()) {
            auto& id = it.first;
            auto& task = entry.task;

            // Update tile distance to map center for load priority.
            auto tileCenter = MapProjection::tileCenter(id);
            double scaleDiv = exp2(id.z - _view.zoom);
            if (scaleDiv < 1) { scaleDiv = 0.1/scaleDiv; } // prefer parent tiles
            task->setPriority(glm::length2(tileCenter - _view.center) * scaleDiv);
            task->setProxyState(entry.getProxyCounter() > 0);
        }

        if (entry.tile) {
            // Mark as proxy
            entry.tile->setProxyState(entry.getProxyCounter() > 0);
        }
    }
}

void TileManager::enqueueTask(TileSet& _tileSet, const TileID& _tileID,
                              const ViewState& _view) {

    // Keep the items sorted by distance
    auto tileCenter = MapProjection::tileCenter(_tileID);
    double distance = glm::length2(tileCenter - _view.center);

    auto it = std::upper_bound(m_loadTasks.begin(), m_loadTasks.end(), distance,
                               [](auto& distance, auto& other){
                                   return distance < std::get<0>(other);
                               });

    m_loadTasks.insert(it, std::make_tuple(distance, &_tileSet, _tileID));
}

void TileManager::loadTiles() {

    if (m_loadTasks.empty()) { return; }

    for (auto& loadTask : m_loadTasks) {

        auto tileId = std::get<2>(loadTask);
        auto& tileSet = *std::get<1>(loadTask);
        auto tileIt = tileSet.tiles.find(tileId);
        auto& entry = tileIt->second;

        tileSet.source->loadTileData(entry.task, m_dataCallback);

        LOGTO("Load Tile: %s", tileId.toString().c_str());

    }

    // DBG("loading:%d cache: %fMB",
    //     m_loadTasks.size(),
    //     (double(m_tileCache->getMemoryUsage()) / (1024 * 1024)));

    m_loadTasks.clear();
}

bool TileManager::addTile(TileSet& _tileSet, const TileID& _tileID) {

    auto tile = m_tileCache->get(_tileSet.source->id(), _tileID);

    if (tile) {
        if (tile->sourceGeneration() == _tileSet.source->generation()) {
            m_tiles.push_back(tile);

            // Reset tile on potential internal dynamic data set
            tile->resetState();
        } else {
            // Clear stale tile data
            tile.reset();
        }
    }

    // Add TileEntry to TileSet
    auto entry = _tileSet.tiles.emplace(_tileID, tile);

    if (!tile) {
        // Add Proxy if corresponding proxy MapTile ready
        updateProxyTiles(_tileSet, _tileID, entry.first->second);

        entry.first->second.task = _tileSet.source->createTask(_tileID);
    }
    entry.first->second.setVisible(true);

    return bool(tile);
}

void TileManager::removeTile(TileSet& _tileSet, std::map<TileID, TileEntry>::iterator& _tileIt) {

    auto& entry = _tileIt->second;

    if (entry.isInProgress()) {
        // 1. Remove from Datasource. Make sure to cancel
        //  the network request associated with this tile.
        _tileSet.source->cancelLoadingTile(*entry.task);

        entry.clearTask();

    } else if (entry.tile) {
        // Add to cache
        m_tileCache->put(_tileSet.source->id(), entry.tile);
    }

    // Remove tile from set
    _tileIt = _tileSet.tiles.erase(_tileIt);
}

bool TileManager::updateProxyTile(TileSet& _tileSet, TileEntry& _tile, const TileID& _proxyTileId, ProxyID _proxyId) {

    if (!_proxyTileId.isValid()) { return false; }

    auto& tiles = _tileSet.tiles;

    // check if the proxy exists in the visible tile set
    {
        const auto& it = tiles.find(_proxyTileId);
        if (it != tiles.end()) {
            if (_tile.setProxy(_proxyId)) {
                auto& entry = it->second;
                entry.incProxyCounter();

                if (entry.tile) {
                    m_tiles.push_back(entry.tile);
                }
                return true;
            }
            // Note: No need to check the cache: When the tile is in
            // tileSet it has already been fetched from cache
            return false;
        }
    }

    // check if the proxy exists in the cache
    {
        auto proxyTile = m_tileCache->get(_tileSet.source->id(), _proxyTileId);
        if (proxyTile && _tile.setProxy(_proxyId)) {

            auto result = tiles.emplace(_proxyTileId, proxyTile);
            auto& entry = result.first->second;
            entry.incProxyCounter();

            m_tiles.push_back(proxyTile);
            return true;
        }
    }

    return false;
}

void TileManager::updateProxyTiles(TileSet& _tileSet, const TileID& _tileID, TileEntry& _tile) {
    // TODO: this should be improved to use the nearest proxy tile available.
    // Currently it would use parent or grand*parent  as proxies even if the
    // child proxies would be more appropriate

    // Try parent proxy
    auto zoomBias = _tileSet.source->zoomBias();
    auto maxZoom = _tileSet.source->maxZoom();
    auto parentID = _tileID.getParent(zoomBias);
    auto minZoom = _tileSet.source->minDisplayZoom();
    if (minZoom <= parentID.z
            && updateProxyTile(_tileSet, _tile, parentID, ProxyID::parent)) {
        return;
    }
    // Try grandparent
    auto grandparentID = parentID.getParent(zoomBias);
    if (minZoom <= grandparentID.z
            && updateProxyTile(_tileSet, _tile, grandparentID, ProxyID::parent2)) {
        return;
    }
    // Try children
    if (maxZoom > _tileID.z) {
        for (int i = 0; i < 4; i++) {
            auto childID = _tileID.getChild(i, maxZoom);
            updateProxyTile(_tileSet, _tile, childID, static_cast<ProxyID>(1 << i));
        }
    }
}

void TileManager::clearProxyTiles(TileSet& _tileSet, const TileID& _tileID, TileEntry& _tile,
                                  std::vector<TileID>& _removes) {
    auto& tiles = _tileSet.tiles;
    auto zoomBias = _tileSet.source->zoomBias();
    auto maxZoom = _tileSet.source->maxZoom();

    auto removeProxy = [&tiles,&_removes](TileID id) {
        auto it = tiles.find(id);
        if (it != tiles.end()) {
            auto& entry = it->second;
            entry.decProxyCounter();
            if (entry.getProxyCounter() <= 0 && !entry.isVisible()) {
                _removes.push_back(id);
            }
        }
    };
    // Check if grand parent proxy is present
    if (_tile.unsetProxy(ProxyID::parent2)) {
        TileID gparentID(_tileID.getParent(zoomBias).getParent(zoomBias));
        removeProxy(gparentID);
    }

    // Check if parent proxy is present
    if (_tile.unsetProxy(ProxyID::parent)) {
        TileID parentID(_tileID.getParent(zoomBias));
        removeProxy(parentID);
    }

    // Check if child proxies are present
    for (int i = 0; i < 4; i++) {
        if (_tile.unsetProxy(static_cast<ProxyID>(1 << i))) {
            TileID childID(_tileID.getChild(i, maxZoom));
            removeProxy(childID);
        }
    }
}

void TileManager::setCacheSize(size_t _cacheSize) {
    m_tileCache->limitCacheSize(_cacheSize);
}

}


text:
#ifdef HAVE_LIBEXIF

#include <stdio.h>
#include <libexif/exif-data.h>

#include "feh.h"
#include "debug.h"
#include "exif.h"
#include "exif_canon.h"

/* get interesting canon maker note tags in readable form */
void exc_get_mnote_canon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize)
{
  /* char buf[EXIF_STD_BUF_LEN];

  buf[0] = '\0';
  exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf));
  exif_trim_spaces(buf); */

  switch(tag)
  {
    default:
    {
      /* normal makernote tags without special treatment */
      exif_get_mnote_tag(ed, tag, buffer, maxsize);
    }
    break;
  }

  return;
}

#endif


text:
from share.provider import OAIProviderAppConfig

class AppConfig(OAIProviderAppConfig):
    name = 'providers.edu.citeseerx'
    version = '0.0.1'
    title = 'citeseerx'
    long_title = 'CiteSeerX Scientific Literature Digital Library and Search Engine'
    home_page = 'http://citeseerx.ist.psu.edu'
    url = 'http://citeseerx.ist.psu.edu/oai2'
    time_granularity = False


text:
<!DOCTYPE html>

    <base href="/">
    <title>Skoleruter</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://bootswatch.com/yeti/bootstrap.min.css">

    <link rel="stylesheet" href="styles.css">
    <link rel="manifest" href="/manifest.json">
    <link rel="shortcut icon" href="image2993.ico" type="image/x-icon" />

    <my-app>

Laster inn skolerutedata
</my-app>