<commit_before>/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

/** \class RooCBShape
    \ingroup Roofit

PDF implementing the Crystal Ball line shape.
**/

#include "RooFit.h"

#include "Riostream.h"
#include "Riostream.h"
#include <math.h>

#include "RooCBShape.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooMath.h"
#include "TMath.h"

#include "TError.h"

using namespace std;

ClassImp(RooCBShape);

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::ApproxErf(Double_t arg) const
{
  static const double erflim = 5.0;
  if( arg > erflim )
    return 1.0;
  if( arg < -erflim )
    return -1.0;

  return RooMath::erf(arg);
}

////////////////////////////////////////////////////////////////////////////////

RooCBShape::RooCBShape(const char *name, const char *title,
             RooAbsReal& _m, RooAbsReal& _m0, RooAbsReal& _sigma,
             RooAbsReal& _alpha, RooAbsReal& _n) :
  RooAbsPdf(name, title),
  m("m", "Dependent", this, _m),
  m0("m0", "M0", this, _m0),
  sigma("sigma", "Sigma", this, _sigma),
  alpha("alpha", "Alpha", this, _alpha),
  n("n", "Order", this, _n)
{
}

////////////////////////////////////////////////////////////////////////////////

RooCBShape::RooCBShape(const RooCBShape& other, const char* name) :
  RooAbsPdf(other, name), m("m", this, other.m), m0("m0", this, other.m0),
  sigma("sigma", this, other.sigma), alpha("alpha", this, other.alpha),
  n("n", this, other.n)
{
}

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::evaluate() const {
  Double_t t = (m-m0)/sigma;
  if (alpha < 0) t = -t;

  Double_t absAlpha = fabs((Double_t)alpha);

  if (t >= -absAlpha) {
    return exp(-0.5*t*t);
  }
  else {
    Double_t a =  TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
    Double_t b= n/absAlpha - absAlpha;

    return a/TMath::Power(b - t, n);
  }
}

////////////////////////////////////////////////////////////////////////////////

Int_t RooCBShape::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /*rangeName*/) const
{
  if( matchArgs(allVars,analVars,m) )
    return 1 ;

  return 0;
}

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::analyticalIntegral(Int_t code, const char* rangeName) const
{
  static const double sqrtPiOver2 = 1.2533141373;
  static const double sqrt2 = 1.4142135624;

  R__ASSERT(code==1);
  double result = 0.0;
  bool useLog = false;

  if( fabs(n-1.0) < 1.0e-05 )
    useLog = true;

  double sig = fabs((Double_t)sigma);

  double tmin = (m.min(rangeName)-m0)/sig;
  double tmax = (m.max(rangeName)-m0)/sig;

  if(alpha < 0) {
    double tmp = tmin;
    tmin = -tmax;
    tmax = -tmp;
  }

  double absAlpha = fabs((Double_t)alpha);

  if( tmin >= -absAlpha ) {
    result += sig*sqrtPiOver2*(   ApproxErf(tmax/sqrt2)
                                - ApproxErf(tmin/sqrt2) );
  }
  else if( tmax <= -absAlpha ) {
    double a = TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
    double b = n/absAlpha - absAlpha;

    if(useLog) {
      result += a*sig*( log(b-tmin) - log(b-tmax) );
    }
    else {
      result += a*sig/(1.0-n)*(   1.0/(TMath::Power(b-tmin,n-1.0))
                                - 1.0/(TMath::Power(b-tmax,n-1.0)) );
    }
  }
  else {
    double a = TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
    double b = n/absAlpha - absAlpha;

    double term1 = 0.0;
    if(useLog) {
      term1 = a*sig*(  log(b-tmin) - log(n/absAlpha));
    }
    else {
      term1 = a*sig/(1.0-n)*(   1.0/(TMath::Power(b-tmin,n-1.0))
                              - 1.0/(TMath::Power(n/absAlpha,n-1.0)) );
    }

    double term2 = sig*sqrtPiOver2*(   ApproxErf(tmax/sqrt2)
                                     - ApproxErf(-absAlpha/sqrt2) );

    result += term1 + term2;
  }

  return result != 0. ? result : std::numeric_limits<double>::min();
}

////////////////////////////////////////////////////////////////////////////////
/// Advertise that we know the maximum of self for given (m0,alpha,n,sigma)

Int_t RooCBShape::getMaxVal(const RooArgSet& vars) const
{
  RooArgSet dummy ;

  if (matchArgs(vars,dummy,m)) {
    return 1 ;
  }
  return 0 ;
}

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::maxVal(Int_t code) const
{
  R__ASSERT(code==1) ;

  // The maximum value for given (m0,alpha,n,sigma)
  return 1.0 ;
}
<commit_msg>[RF] Sanitise integral of RooCBShape.<commit_after>/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

/** \class RooCBShape
    \ingroup Roofit

PDF implementing the Crystal Ball line shape.
**/

#include "RooFit.h"

#include "Riostream.h"
#include "Riostream.h"
#include <math.h>

#include "RooCBShape.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooMath.h"
#include "TMath.h"

#include "TError.h"

using namespace std;

ClassImp(RooCBShape);

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::ApproxErf(Double_t arg) const
{
  static const double erflim = 5.0;
  if( arg > erflim )
    return 1.0;
  if( arg < -erflim )
    return -1.0;

  return RooMath::erf(arg);
}

////////////////////////////////////////////////////////////////////////////////

RooCBShape::RooCBShape(const char *name, const char *title,
             RooAbsReal& _m, RooAbsReal& _m0, RooAbsReal& _sigma,
             RooAbsReal& _alpha, RooAbsReal& _n) :
  RooAbsPdf(name, title),
  m("m", "Dependent", this, _m),
  m0("m0", "M0", this, _m0),
  sigma("sigma", "Sigma", this, _sigma),
  alpha("alpha", "Alpha", this, _alpha),
  n("n", "Order", this, _n)
{
}

////////////////////////////////////////////////////////////////////////////////

RooCBShape::RooCBShape(const RooCBShape& other, const char* name) :
  RooAbsPdf(other, name), m("m", this, other.m), m0("m0", this, other.m0),
  sigma("sigma", this, other.sigma), alpha("alpha", this, other.alpha),
  n("n", this, other.n)
{
}

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::evaluate() const {
  Double_t t = (m-m0)/sigma;
  if (alpha < 0) t = -t;

  Double_t absAlpha = fabs((Double_t)alpha);

  if (t >= -absAlpha) {
    return exp(-0.5*t*t);
  }
  else {
    Double_t a =  TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
    Double_t b= n/absAlpha - absAlpha;

    return a/TMath::Power(b - t, n);
  }
}

////////////////////////////////////////////////////////////////////////////////

Int_t RooCBShape::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /*rangeName*/) const
{
  if( matchArgs(allVars,analVars,m) )
    return 1 ;

  return 0;
}

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::analyticalIntegral(Int_t code, const char* rangeName) const
{
  static const double sqrtPiOver2 = 1.2533141373;
  static const double sqrt2 = 1.4142135624;

  R__ASSERT(code==1);
  double result = 0.0;
  bool useLog = false;

  if( fabs(n-1.0) < 1.0e-05 )
    useLog = true;

  double sig = fabs((Double_t)sigma);

  double tmin = (m.min(rangeName)-m0)/sig;
  double tmax = (m.max(rangeName)-m0)/sig;

  if(alpha < 0) {
    double tmp = tmin;
    tmin = -tmax;
    tmax = -tmp;
  }

  double absAlpha = fabs((Double_t)alpha);

  if( tmin >= -absAlpha ) {
    result += sig*sqrtPiOver2*(   ApproxErf(tmax/sqrt2)
                                - ApproxErf(tmin/sqrt2) );
  }
  else if( tmax <= -absAlpha ) {
    double a = TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
    double b = n/absAlpha - absAlpha;

    if(useLog) {
      result += a*sig*( log(b-tmin) - log(b-tmax) );
    }
    else {
      result += a*sig/(1.0-n)*(   1.0/(TMath::Power(b-tmin,n-1.0))
                                - 1.0/(TMath::Power(b-tmax,n-1.0)) );
    }
  }
  else {
    double a = TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
    double b = n/absAlpha - absAlpha;

    double term1 = 0.0;
    if(useLog) {
      term1 = a*sig*(  log(b-tmin) - log(n/absAlpha));
    }
    else {
      term1 = a*sig/(1.0-n)*(   1.0/(TMath::Power(b-tmin,n-1.0))
                              - 1.0/(TMath::Power(n/absAlpha,n-1.0)) );
    }

    double term2 = sig*sqrtPiOver2*(   ApproxErf(tmax/sqrt2)
                                     - ApproxErf(-absAlpha/sqrt2) );

    result += term1 + term2;
  }

  return result != 0. ? result : 1.E-300;
}

////////////////////////////////////////////////////////////////////////////////
/// Advertise that we know the maximum of self for given (m0,alpha,n,sigma)

Int_t RooCBShape::getMaxVal(const RooArgSet& vars) const
{
  RooArgSet dummy ;

  if (matchArgs(vars,dummy,m)) {
    return 1 ;
  }
  return 0 ;
}

////////////////////////////////////////////////////////////////////////////////

Double_t RooCBShape::maxVal(Int_t code) const
{
  R__ASSERT(code==1) ;

  // The maximum value for given (m0,alpha,n,sigma)
  return 1.0 ;
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file eint8_outcept in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either eint8_outpress or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/framework/ir/mkldnn/cpu_quantize_squash_pass.h"
#include <algorithm>
#include <string>
#include <vector>
#include "paddle/fluid/platform/enforce.h"
#include "paddle/fluid/string/pretty_log.h"

namespace paddle {
namespace framework {
namespace ir {

using string::PrettyLogDetail;

void CPUQuantizeSquashPass::FindNodesToKeep(
    Graph* graph,
    std::unordered_map<const Node*, int>* nodes_keep_counter) const {
  GraphPatternDetector gpd;
  patterns::DequantAny deq_any_pattern{gpd.mutable_pattern(), "deqant_any"};
  deq_any_pattern();

  int found_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    GET_IR_NODE_FROM_SUBGRAPH(dequant_out, dequant_out, deq_any_pattern);

    if (nodes_keep_counter->find(dequant_out) == nodes_keep_counter->end())
      (*nodes_keep_counter)[dequant_out] = 1;
    else
      (*nodes_keep_counter)[dequant_out] += 1;

    found_count++;
  };
  gpd(graph, handler);
  AddStatis(found_count);
}

void CPUQuantizeSquashPass::DequantQuantSquash(
    Graph* graph,
    std::unordered_map<const Node*, int>* nodes_keep_counter) const {
  GraphPatternDetector gpd;
  patterns::DequantQuantAny squash_pattern{gpd.mutable_pattern(), "squash"};
  squash_pattern();

  int found_dequant_quant_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    VLOG(4) << "squash requantize-quantize ops pair";

    GET_IR_NODE_FROM_SUBGRAPH(dequant_in, dequant_in, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_op, dequant_op, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_out, dequant_out, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(quant_op, quant_op, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(quant_out, quant_out, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(next_op, next_op, squash_pattern);

    auto* next_op_desc = next_op->Op();
    float dequant_scale = boost::get<float>(dequant_op->Op()->GetAttr("Scale"));
    float quant_scale = boost::get<float>(quant_op->Op()->GetAttr("Scale"));
    PADDLE_ENFORCE(nodes_keep_counter->find(dequant_out) !=
                   nodes_keep_counter->end());

    // check if dequantize op should be kept or removed, decrease the counter
    bool keep_dequant = (*nodes_keep_counter)[dequant_out]-- > 1;

    if (dequant_scale == quant_scale) {
      // squash dequantize-quantize to nothing
      auto quant_out_var_name = quant_out->Name();
      auto next_op_inputs = next_op_desc->InputNames();
      for (const auto& name : next_op_inputs) {
        auto input_names = next_op_desc->Input(name);
        std::replace(input_names.begin(), input_names.end(), quant_out_var_name,
                     dequant_in->Name());
        next_op_desc->SetInput(name, input_names);
      }

      if (keep_dequant)
        GraphSafeRemoveNodes(graph, {quant_op, quant_out});
      else
        GraphSafeRemoveNodes(graph,
                             {dequant_op, quant_op, dequant_out, quant_out});

      IR_NODE_LINK_TO(dequant_in, next_op);

      found_dequant_quant_count++;
    } else {
      // squash dequantize-quantize to requantize op
      OpDesc desc;
      desc.SetType("requantize");
      desc.SetInput("Input", std::vector<std::string>({dequant_in->Name()}));
      desc.SetOutput("Output", std::vector<std::string>({quant_out->Name()}));
      desc.SetAttr("Scale_in", dequant_scale);
      desc.SetAttr("Scale_out", quant_scale);

      auto requant_op = g->CreateOpNode(&desc);

      if (keep_dequant)
        GraphSafeRemoveNodes(graph, {quant_op});
      else
        GraphSafeRemoveNodes(graph, {dequant_op, quant_op, dequant_out});

      IR_NODE_LINK_TO(dequant_in, requant_op);
      IR_NODE_LINK_TO(requant_op, quant_out);

      found_dequant_quant_count++;
    }
  };
  gpd(graph, handler);
  AddStatis(found_dequant_quant_count);
  PrettyLogDetail("---    squashed %d dequantize-quantize pairs",
                  found_dequant_quant_count);
}

void CPUQuantizeSquashPass::ConvRequantSquash(Graph* graph) const {
  GraphPatternDetector gpd;
  patterns::ConvRequant conv_requant_pattern{gpd.mutable_pattern(),
                                             "conv_requant"};
  conv_requant_pattern();

  int found_requant_squash_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    VLOG(4) << "squash conv-requantize ops pair";

    GET_IR_NODE_FROM_SUBGRAPH(conv_op, conv_op, conv_requant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(conv_out, conv_out, conv_requant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(requant_op, requant_op, conv_requant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(requant_out, requant_out, conv_requant_pattern);

    // if conv2d has one output squash
    if (conv_out->outputs.size() == 1) {
      float requant_scale_out =
          boost::get<float>(requant_op->Op()->GetAttr("Scale_out"));
      conv_op->Op()->SetAttr("Scale_out", requant_scale_out);
      conv_op->Op()->SetOutput("Output",
                               std::vector<std::string>({requant_out->Name()}));
      IR_NODE_LINK_TO(conv_op, requant_out);
      GraphSafeRemoveNodes(graph, {conv_out, requant_op});

      found_requant_squash_count++;
    }
  };
  gpd(graph, handler);
  AddStatis(found_requant_squash_count);
  PrettyLogDetail("---    squashed %d requantize with convs",
                  found_requant_squash_count);
}

void CPUQuantizeSquashPass::ConvDequantSquash(Graph* graph) const {
  GraphPatternDetector gpd;
  patterns::ConvDequant conv_dequant_pattern{gpd.mutable_pattern(),
                                             "conv_dequant"};
  conv_dequant_pattern();

  int found_conv_dequant_squash_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    VLOG(4) << "squash conv-dequant ops pair";

    GET_IR_NODE_FROM_SUBGRAPH(conv_op, conv_op, conv_dequant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(conv_out, conv_out, conv_dequant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_op, dequant_op, conv_dequant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_out, dequant_out, conv_dequant_pattern);

    // if conv2d has one output
    if (conv_out->outputs.size() == 1) {
      conv_op->Op()->SetAttr("force_fp32_output", true);
      conv_op->Op()->SetOutput("Output",
                               std::vector<std::string>({dequant_out->Name()}));
      IR_NODE_LINK_TO(conv_op, dequant_out);
      GraphSafeRemoveNodes(graph, {conv_out, dequant_op});
      found_conv_dequant_squash_count++;
    }
  };
  gpd(graph, handler);
  AddStatis(found_conv_dequant_squash_count);
  PrettyLogDetail("---    squashed %d dequant with convs",
                  found_conv_dequant_squash_count);
}

void CPUQuantizeSquashPass::ApplyImpl(ir::Graph* graph) const {
  PADDLE_ENFORCE(graph);
  FusePassBase::Init("cpu_quantize_squash_pass", graph);

  std::unordered_map<const Node*, int> nodes_keep_counter;
  FindNodesToKeep(graph, &nodes_keep_counter);
  DequantQuantSquash(graph, &nodes_keep_counter);
  ConvRequantSquash(graph);
  ConvDequantSquash(graph);
}

}  // namespace ir
}  // namespace framework
}  // namespace paddle

REGISTER_PASS(cpu_quantize_squash_pass,
              paddle::framework::ir::CPUQuantizeSquashPass);
<commit_msg>Fix conv2d+dequantize squash for residual fusion (#19545)<commit_after>// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file eint8_outcept in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either eint8_outpress or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/fluid/framework/ir/mkldnn/cpu_quantize_squash_pass.h"
#include <algorithm>
#include <string>
#include <vector>
#include "paddle/fluid/platform/enforce.h"
#include "paddle/fluid/string/pretty_log.h"

namespace paddle {
namespace framework {
namespace ir {

using string::PrettyLogDetail;

void CPUQuantizeSquashPass::FindNodesToKeep(
    Graph* graph,
    std::unordered_map<const Node*, int>* nodes_keep_counter) const {
  GraphPatternDetector gpd;
  patterns::DequantAny deq_any_pattern{gpd.mutable_pattern(), "deqant_any"};
  deq_any_pattern();

  int found_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    GET_IR_NODE_FROM_SUBGRAPH(dequant_out, dequant_out, deq_any_pattern);

    if (nodes_keep_counter->find(dequant_out) == nodes_keep_counter->end())
      (*nodes_keep_counter)[dequant_out] = 1;
    else
      (*nodes_keep_counter)[dequant_out] += 1;

    found_count++;
  };
  gpd(graph, handler);
  AddStatis(found_count);
}

void CPUQuantizeSquashPass::DequantQuantSquash(
    Graph* graph,
    std::unordered_map<const Node*, int>* nodes_keep_counter) const {
  GraphPatternDetector gpd;
  patterns::DequantQuantAny squash_pattern{gpd.mutable_pattern(), "squash"};
  squash_pattern();

  int found_dequant_quant_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    VLOG(4) << "squash requantize-quantize ops pair";

    GET_IR_NODE_FROM_SUBGRAPH(dequant_in, dequant_in, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_op, dequant_op, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_out, dequant_out, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(quant_op, quant_op, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(quant_out, quant_out, squash_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(next_op, next_op, squash_pattern);

    auto* next_op_desc = next_op->Op();
    float dequant_scale = boost::get<float>(dequant_op->Op()->GetAttr("Scale"));
    float quant_scale = boost::get<float>(quant_op->Op()->GetAttr("Scale"));
    PADDLE_ENFORCE(nodes_keep_counter->find(dequant_out) !=
                   nodes_keep_counter->end());

    // check if dequantize op should be kept or removed, decrease the counter
    bool keep_dequant = (*nodes_keep_counter)[dequant_out]-- > 1;

    if (dequant_scale == quant_scale) {
      // squash dequantize-quantize to nothing
      auto quant_out_var_name = quant_out->Name();
      auto next_op_inputs = next_op_desc->InputNames();
      for (const auto& name : next_op_inputs) {
        auto input_names = next_op_desc->Input(name);
        std::replace(input_names.begin(), input_names.end(), quant_out_var_name,
                     dequant_in->Name());
        next_op_desc->SetInput(name, input_names);
      }

      if (keep_dequant)
        GraphSafeRemoveNodes(graph, {quant_op, quant_out});
      else
        GraphSafeRemoveNodes(graph,
                             {dequant_op, quant_op, dequant_out, quant_out});

      IR_NODE_LINK_TO(dequant_in, next_op);

      found_dequant_quant_count++;
    } else {
      // squash dequantize-quantize to requantize op
      OpDesc desc;
      desc.SetType("requantize");
      desc.SetInput("Input", std::vector<std::string>({dequant_in->Name()}));
      desc.SetOutput("Output", std::vector<std::string>({quant_out->Name()}));
      desc.SetAttr("Scale_in", dequant_scale);
      desc.SetAttr("Scale_out", quant_scale);

      auto requant_op = g->CreateOpNode(&desc);

      if (keep_dequant)
        GraphSafeRemoveNodes(graph, {quant_op});
      else
        GraphSafeRemoveNodes(graph, {dequant_op, quant_op, dequant_out});

      IR_NODE_LINK_TO(dequant_in, requant_op);
      IR_NODE_LINK_TO(requant_op, quant_out);

      found_dequant_quant_count++;
    }
  };
  gpd(graph, handler);
  AddStatis(found_dequant_quant_count);
  PrettyLogDetail("---    squashed %d dequantize-quantize pairs",
                  found_dequant_quant_count);
}

void CPUQuantizeSquashPass::ConvRequantSquash(Graph* graph) const {
  GraphPatternDetector gpd;
  patterns::ConvRequant conv_requant_pattern{gpd.mutable_pattern(),
                                             "conv_requant"};
  conv_requant_pattern();

  int found_requant_squash_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    VLOG(4) << "squash conv-requantize ops pair";

    GET_IR_NODE_FROM_SUBGRAPH(conv_op, conv_op, conv_requant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(conv_out, conv_out, conv_requant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(requant_op, requant_op, conv_requant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(requant_out, requant_out, conv_requant_pattern);

    // if conv2d has one output squash
    if (conv_out->outputs.size() == 1) {
      float requant_scale_out =
          boost::get<float>(requant_op->Op()->GetAttr("Scale_out"));
      conv_op->Op()->SetAttr("Scale_out", requant_scale_out);
      conv_op->Op()->SetOutput("Output",
                               std::vector<std::string>({requant_out->Name()}));
      IR_NODE_LINK_TO(conv_op, requant_out);
      GraphSafeRemoveNodes(graph, {conv_out, requant_op});

      found_requant_squash_count++;
    }
  };
  gpd(graph, handler);
  AddStatis(found_requant_squash_count);
  PrettyLogDetail("---    squashed %d requantize with convs",
                  found_requant_squash_count);
}

void CPUQuantizeSquashPass::ConvDequantSquash(Graph* graph) const {
  GraphPatternDetector gpd;
  patterns::ConvDequant conv_dequant_pattern{gpd.mutable_pattern(),
                                             "conv_dequant"};
  conv_dequant_pattern();

  int found_conv_dequant_squash_count = 0;
  auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
                     Graph* g) {
    VLOG(4) << "squash conv-dequant ops pair";

    GET_IR_NODE_FROM_SUBGRAPH(conv_op, conv_op, conv_dequant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(conv_out, conv_out, conv_dequant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_op, dequant_op, conv_dequant_pattern);
    GET_IR_NODE_FROM_SUBGRAPH(dequant_out, dequant_out, conv_dequant_pattern);

    // if conv2d has one output
    // and there is no fuse residual connection
    // because residual fusion does not support force output with fp32
    if (conv_out->outputs.size() == 1 &&
        !(conv_op->Op()->GetAttrIfExists<bool>("fuse_residual_connection"))) {
      conv_op->Op()->SetAttr("force_fp32_output", true);
      conv_op->Op()->SetOutput("Output",
                               std::vector<std::string>({dequant_out->Name()}));
      IR_NODE_LINK_TO(conv_op, dequant_out);
      GraphSafeRemoveNodes(graph, {conv_out, dequant_op});
      found_conv_dequant_squash_count++;
    }
  };
  gpd(graph, handler);
  AddStatis(found_conv_dequant_squash_count);
  PrettyLogDetail("---    squashed %d dequant with convs",
                  found_conv_dequant_squash_count);
}

void CPUQuantizeSquashPass::ApplyImpl(ir::Graph* graph) const {
  PADDLE_ENFORCE(graph);
  FusePassBase::Init("cpu_quantize_squash_pass", graph);

  std::unordered_map<const Node*, int> nodes_keep_counter;
  FindNodesToKeep(graph, &nodes_keep_counter);
  DequantQuantSquash(graph, &nodes_keep_counter);
  ConvRequantSquash(graph);
  ConvDequantSquash(graph);
}

}  // namespace ir
}  // namespace framework
}  // namespace paddle

REGISTER_PASS(cpu_quantize_squash_pass,
              paddle::framework::ir::CPUQuantizeSquashPass);
<|endoftext|>


<commit_before>#pragma once
#ifndef AMFOBJECT_HPP
#define AMFOBJECT_HPP

#include <functional>
#include <map>

#include "amfitem.hpp"
#include "types/amfinteger.hpp"
#include "types/amfstring.hpp"

// TODO: nested class?
class AmfObjectTraits {
public:
	AmfObjectTraits(std::string className, bool dynamic, bool externalizable) :
		className(className), dynamic(dynamic), externalizable(externalizable) { };

	std::string className;
	std::vector<std::string> attributes;
	bool dynamic;
	bool externalizable;
	std::function<std::vector<u8>()> externalizer;
};

class AmfObject : public AmfItem {
public:
	AmfObject(AmfObjectTraits traits) : traits(traits) { };

	std::vector<u8> serialize() const {
		/* AmfObject is defined as
		 * object-marker
		 * (
		 *   U29O-ref |
		 *   (U29O-traits-ext class-name *(U8)) |
		 *   U29O-traits-ref |
		 *   (U29O-traits class-name *(UTF-8-vr))
		 * )
		 * *(value-type)
		 * *(dynamic-member)
		 */
		std::vector<u8> buf = { AMF_OBJECT };

		AmfString className(traits.className);
		// serialized class name with AmfString marker
		std::vector<u8> name(className.serialize());

		// TODO: need to handle trait refs?
		if (traits.externalizable) {
			// U29O-traits-ext = 0b0111 = 0x07
			buf.push_back(0x07);
			// class-name
			buf.insert(buf.end(), name.begin() + 1, name.end());

			// externalized value = *(U8)
			// note: this may throw if externalizer is not properly initialized
			std::vector<u8> externalized(traits.externalizer());
			buf.insert(buf.end(), externalized.begin(), externalized.end());
			return buf;
		}

		// U29-traits = 0b0011 = 0x03
		// TODO: make sure .size() is max 25 bit?
		int traitMarker = traits.attributes.size() << 4 | 0x03;
		// dynamic marker = 0b1000 = 0x08
		if (traits.dynamic) traitMarker |= 0x08;

		std::vector<u8> marker(AmfInteger(traitMarker).serialize());
		buf.insert(buf.end(), marker.begin() + 1, marker.end());

		// class-name, skip the AmfString marker
		buf.insert(buf.end(), name.begin() + 1, name.end());

		// sealed property names = *(UTF-8-vr)
		for (const std::string& attribute : traits.attributes) {
			std::vector<u8> attr(AmfString(attribute).serialize());
			// skip AmfString marker
			buf.insert(buf.end(), attr.begin() + 1, attr.end());
		}

		// sealed property values = *(value-type)
		for (const std::string& attribute : traits.attributes) {
			AmfItem* property = sealedProperties.at(attribute);
			std::vector<u8> value(property->serialize());
			buf.insert(buf.end(), value.begin(), value.end());
		}

		// dynamic-members = UTF-8-vr value-type
		for (const auto& it : dynamicProperties) {
			AmfString attribute(it.first);
			std::vector<u8> name(attribute.serialize());
			std::vector<u8> value(it.second->serialize());

			// skip AmfString marker again
			buf.insert(buf.end(), name.begin() + 1, name.end());
			buf.insert(buf.end(), value.begin(), value.end());
		}

		// final dynamic member = UTF-8-empty
		buf.push_back(0x01);

		return buf;
	}

	std::map<std::string, AmfItem*> sealedProperties;
	std::map<std::string, AmfItem*> dynamicProperties;

private:
	AmfObjectTraits traits;
};

#endif
<commit_msg>Only mark the end of dynamic members if the object is dynamic.<commit_after>#pragma once
#ifndef AMFOBJECT_HPP
#define AMFOBJECT_HPP

#include <functional>
#include <map>

#include "amfitem.hpp"
#include "types/amfinteger.hpp"
#include "types/amfstring.hpp"

// TODO: nested class?
class AmfObjectTraits {
public:
	AmfObjectTraits(std::string className, bool dynamic, bool externalizable) :
		className(className), dynamic(dynamic), externalizable(externalizable) { };

	std::string className;
	std::vector<std::string> attributes;
	bool dynamic;
	bool externalizable;
	std::function<std::vector<u8>()> externalizer;
};

class AmfObject : public AmfItem {
public:
	AmfObject(AmfObjectTraits traits) : traits(traits) { };

	std::vector<u8> serialize() const {
		/* AmfObject is defined as
		 * object-marker
		 * (
		 *   U29O-ref |
		 *   (U29O-traits-ext class-name *(U8)) |
		 *   U29O-traits-ref |
		 *   (U29O-traits class-name *(UTF-8-vr))
		 * )
		 * *(value-type)
		 * *(dynamic-member)
		 */
		std::vector<u8> buf = { AMF_OBJECT };

		AmfString className(traits.className);
		// serialized class name with AmfString marker
		std::vector<u8> name(className.serialize());

		// TODO: need to handle trait refs?
		if (traits.externalizable) {
			// U29O-traits-ext = 0b0111 = 0x07
			buf.push_back(0x07);
			// class-name
			buf.insert(buf.end(), name.begin() + 1, name.end());

			// externalized value = *(U8)
			// note: this may throw if externalizer is not properly initialized
			std::vector<u8> externalized(traits.externalizer());
			buf.insert(buf.end(), externalized.begin(), externalized.end());
			return buf;
		}

		// U29-traits = 0b0011 = 0x03
		// TODO: make sure .size() is max 25 bit?
		int traitMarker = traits.attributes.size() << 4 | 0x03;
		// dynamic marker = 0b1000 = 0x08
		if (traits.dynamic) traitMarker |= 0x08;

		std::vector<u8> marker(AmfInteger(traitMarker).serialize());
		buf.insert(buf.end(), marker.begin() + 1, marker.end());

		// class-name, skip the AmfString marker
		buf.insert(buf.end(), name.begin() + 1, name.end());

		// sealed property names = *(UTF-8-vr)
		for (const std::string& attribute : traits.attributes) {
			std::vector<u8> attr(AmfString(attribute).serialize());
			// skip AmfString marker
			buf.insert(buf.end(), attr.begin() + 1, attr.end());
		}

		// sealed property values = *(value-type)
		for (const std::string& attribute : traits.attributes) {
			AmfItem* property = sealedProperties.at(attribute);
			std::vector<u8> value(property->serialize());
			buf.insert(buf.end(), value.begin(), value.end());
		}

		// dynamic-members = UTF-8-vr value-type
		for (const auto& it : dynamicProperties) {
			AmfString attribute(it.first);
			std::vector<u8> name(attribute.serialize());
			std::vector<u8> value(it.second->serialize());

			// skip AmfString marker again
			buf.insert(buf.end(), name.begin() + 1, name.end());
			buf.insert(buf.end(), value.begin(), value.end());
		}

		// only mark the end of *(dynamic-member) if the object is actually dynamic
		// final dynamic member = UTF-8-empty
		if (traits.dynamic)
			buf.push_back(0x01);

		return buf;
	}

	std::map<std::string, AmfItem*> sealedProperties;
	std::map<std::string, AmfItem*> dynamicProperties;

private:
	AmfObjectTraits traits;
};

#endif
<|endoftext|>


<commit_before> /*
  * jabberresourcepool.cpp
  *
  * Copyright (c) 2004 by Till Gerken <till@tantalo.net>
  *
  * Kopete    (c) by the Kopete developers  <kopete-devel@kde.org>
  *
  * *************************************************************************
  * *                                                                       *
  * * This program is free software; you can redistribute it and/or modify  *
  * * it under the terms of the GNU General Public License as published by  *
  * * the Free Software Foundation; either version 2 of the License, or     *
  * * (at your option) any later version.                                   *
  * *                                                                       *
  * *************************************************************************
  */

#include <qptrlist.h>
#include <kdebug.h>
#include "jabberresourcepool.h"
#include "jabberresource.h"
#include "jabbercontactpool.h"
#include "jabberbasecontact.h"
#include "jabberaccount.h"

/**
 * This resource will be returned if no other resource
 * for a given JID can be found. It's an empty offline
 * resource.
 */
XMPP::Resource JabberResourcePool::EmptyResource ( "", XMPP::Status ( "", "", 0, false ) );

JabberResourcePool::JabberResourcePool ( JabberAccount *account )
{

	// automatically delete all resources in the pool upon removal
	mPool.setAutoDelete (true);

	mAccount = account;

}

JabberResourcePool::~JabberResourcePool ()
{
}

void JabberResourcePool::slotResourceDestroyed (QObject *sender)
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Resource has been destroyed, collecting the pieces." << endl;

	JabberResource *oldResource = static_cast<JabberResource *>(sender);

	// remove this resource from the lock list if it existed
	mLockList.remove ( oldResource );

}

void JabberResourcePool::notifyRelevantContacts ( const XMPP::Jid &jid )
{

	QPtrList<JabberBaseContact> list = mAccount->contactPool()->findRelevantSources ( jid );

	for(JabberBaseContact *mContact = list.first (); mContact; mContact = list.next ())
	{
		mContact->reevaluateStatus ();
	}

}

void JabberResourcePool::addResource ( const XMPP::Jid &jid, const XMPP::Resource &resource )
{

	// see if the resource already exists
	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.userHost().lower()) && (mResource->resource().name().lower() == resource.name().lower()) )
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Updating existing resource " << resource.name() << " for " << jid.userHost() << endl;

			// It exists, update it. Don't do a "lazy" update by deleting
			// it here and readding it with new parameters later on,
			// any possible lockings to this resource will get lost.
			mResource->setResource ( resource );

			// we still need to notify the contact in case the status
			// of this resource changed
			notifyRelevantContacts ( jid );

			return;
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Adding new resource " << resource.name() << " for " << jid.userHost() << endl;

	// create new resource instance and add it to the dictionary
	JabberResource *newResource = new JabberResource(jid, resource);
	connect ( newResource, SIGNAL ( destroyed (QObject *) ), this, SLOT ( slotResourceDestroyed (QObject *) ) );
	mPool.append ( newResource );

	// send notifications out to the relevant contacts that
	// a new resource is available for them
	notifyRelevantContacts ( jid );

}

void JabberResourcePool::removeResource ( const XMPP::Jid &jid, const XMPP::Resource &resource )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Removing resource " << resource.name() << " from " << jid.userHost() << endl;

	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.userHost().lower()) && (mResource->resource().name().lower() == resource.name().lower()) )
		{
			mPool.remove ();
			notifyRelevantContacts ( jid );
			return;
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: No match found!" << endl;

}

void JabberResourcePool::removeAllResources ( const XMPP::Jid &jid )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Removing all resources for " << jid.userHost() << endl;

	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( mResource->jid().userHost().lower() == jid.userHost().lower() )
		{
			// only remove preselected resource in case there is one
			if ( !jid.resource().isEmpty () && ( jid.resource () == mResource->resource().name () ) )
				mPool.remove ();
		}
	}

}

void JabberResourcePool::clear ()
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Clearing the resource pool." << endl;

	/*
	 * Since many contacts can have multiple resources, we can't simply delete
	 * each resource and trigger a notification upon each deletion. This would
	 * cause lots of status updates in the GUI and create unnecessary flicker
	 * and API traffic. Instead, collect all JIDs, clear the dictionary
	 * and then notify all JIDs after the resources have been deleted.
	 */

	QStringList jidList;

	for ( JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next () )
	{
		jidList += mResource->jid().full ();
	}

	/*
	 * Since mPool has autodeletion enabled, this will cause all
	 * items to be deleted. The lock list will be cleaned automatically.
	 */
	mPool.clear ();

	/*
	 * Now go through the list of JIDs and notify each contact
	 * of its status change
	 */
	for ( QStringList::Iterator it = jidList.begin (); it != jidList.end (); ++it )
	{
		notifyRelevantContacts ( XMPP::Jid ( *it ) );
	}

}

void JabberResourcePool::lockToResource ( const XMPP::Jid &jid, const XMPP::Resource &resource )
{

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Locking " << jid.full() << " to " << resource.name() << endl;

	// remove all existing locks first
	removeLock ( jid );

	// find the resource in our dictionary that matches
	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.full().lower()) && (mResource->resource().name().lower() == resource.name().lower()) )
		{
			mLockList.append ( mResource );
			return;
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: No match found!" << endl;

}

void JabberResourcePool::removeLock ( const XMPP::Jid &jid )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Removing resource lock for " << jid.userHost() << endl;

	// find the resource in our dictionary that matches
	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.userHost().lower()) )
		{
			mLockList.remove ();
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "No locks found." << endl;

}

const XMPP::Resource &JabberResourcePool::lockedResource ( const XMPP::Jid &jid )
{

	// check if the JID already carries a resource, then we will have to use that one
	if ( !jid.resource().isEmpty () )
	{
		// we are subscribed to a JID, find the according resource in the pool
		for ( JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next () )
		{
			if ( ( mResource->jid().userHost().lower () == jid.userHost().lower () ) && ( mResource->resource().name () == jid.resource () ) )
			{
				return mResource->resource ();
			}
		}

		kdDebug ( JABBER_DEBUG_GLOBAL ) << k_funcinfo << "WARNING: No resource found in pool, returning as offline." << endl;

		return EmptyResource;
	}

	// see if we have a locked resource
	for(JabberResource *mResource = mLockList.first (); mResource; mResource = mLockList.next ())
	{
		if ( mResource->jid().userHost().lower() == jid.userHost().lower() )
		{
			kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "Current lock for " << jid.userHost () << " is '" << mResource->resource().name () << "'" << endl;
			return mResource->resource ();
		}
	}

	kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "No lock available for " << jid.userHost () << endl;

	// there's no locked resource, return an empty resource
	return EmptyResource;

}

const XMPP::Resource &JabberResourcePool::bestResource ( const XMPP::Jid &jid, bool honourLock )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Determining best resource for " << jid.full () << endl;

	// FIXME: the code below would be more efficient if it would cache results

	if ( honourLock )
	{
		// if we are locked to a certain resource, always return that one
		const XMPP::Resource &mResource = lockedResource ( jid );
		if ( !mResource.name().isEmpty() )
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "We have a locked resource '" << mResource.name () << "' for " << jid.full () << endl;
			return mResource;
		}
	}

	JabberResource *bestResource = 0L;
	JabberResource *currentResource = 0L;

	for(currentResource = mPool.first (); currentResource; currentResource = mPool.next ())
	{
		// make sure we are only looking up resources for the specified JID
		if ( currentResource->jid().userHost().lower() != jid.userHost().lower() )
		{
			continue;
		}

		// take first resource if no resource has been chosen yet
		if(!bestResource)
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Taking '" << currentResource->resource().name () << "' as first available resource." << endl;

			bestResource = currentResource;
			continue;
		}

		if(currentResource->resource().priority() > bestResource->resource().priority())
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Using '" << currentResource->resource().name () << "' due to better priority." << endl;

			// got a better match by priority
			bestResource = currentResource;
		}
		else
		{
			if(currentResource->resource().priority() == bestResource->resource().priority())
			{
				if(currentResource->resource().status().timeStamp() > bestResource->resource().status().timeStamp())
				{
					kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Using '" << currentResource->resource().name () << "' due to better timestamp." << endl;

					// got a better match by timestamp (priorities are equal)
					bestResource = currentResource;
				}
			}
		}
	}

	return (bestResource == 0L) ? EmptyResource : bestResource->resource();

}

void JabberResourcePool::findResources ( const XMPP::Jid &jid, ResourceList &resourceList )
{

	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( mResource->jid().userHost().lower() == jid.userHost().lower() )
		{
			// we found a resource for the JID, let's see if the JID already contains a resource
			if ( !jid.resource().isEmpty() && ( jid.resource().lower() != mResource->resource().name().lower() ) )
				// the JID contains a resource but it's not the one we have in the dictionary,
				// thus we have to ignore this resource
				continue;

			resourceList.append ( mResource->resource() );
		}
	}

}

#include "jabberresourcepool.moc"
<commit_msg>Make removeLock actually work. Fixes a crash on logout.<commit_after> /*
  * jabberresourcepool.cpp
  *
  * Copyright (c) 2004 by Till Gerken <till@tantalo.net>
  *
  * Kopete    (c) by the Kopete developers  <kopete-devel@kde.org>
  *
  * *************************************************************************
  * *                                                                       *
  * * This program is free software; you can redistribute it and/or modify  *
  * * it under the terms of the GNU General Public License as published by  *
  * * the Free Software Foundation; either version 2 of the License, or     *
  * * (at your option) any later version.                                   *
  * *                                                                       *
  * *************************************************************************
  */

#include <qptrlist.h>
#include <kdebug.h>
#include "jabberresourcepool.h"
#include "jabberresource.h"
#include "jabbercontactpool.h"
#include "jabberbasecontact.h"
#include "jabberaccount.h"

/**
 * This resource will be returned if no other resource
 * for a given JID can be found. It's an empty offline
 * resource.
 */
XMPP::Resource JabberResourcePool::EmptyResource ( "", XMPP::Status ( "", "", 0, false ) );

JabberResourcePool::JabberResourcePool ( JabberAccount *account )
{

	// automatically delete all resources in the pool upon removal
	mPool.setAutoDelete (true);

	mAccount = account;

}

JabberResourcePool::~JabberResourcePool ()
{
}

void JabberResourcePool::slotResourceDestroyed (QObject *sender)
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Resource has been destroyed, collecting the pieces." << endl;

	JabberResource *oldResource = static_cast<JabberResource *>(sender);

	// remove this resource from the lock list if it existed
	mLockList.remove ( oldResource );

}

void JabberResourcePool::notifyRelevantContacts ( const XMPP::Jid &jid )
{

	QPtrList<JabberBaseContact> list = mAccount->contactPool()->findRelevantSources ( jid );

	for(JabberBaseContact *mContact = list.first (); mContact; mContact = list.next ())
	{
		mContact->reevaluateStatus ();
	}

}

void JabberResourcePool::addResource ( const XMPP::Jid &jid, const XMPP::Resource &resource )
{

	// see if the resource already exists
	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.userHost().lower()) && (mResource->resource().name().lower() == resource.name().lower()) )
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Updating existing resource " << resource.name() << " for " << jid.userHost() << endl;

			// It exists, update it. Don't do a "lazy" update by deleting
			// it here and readding it with new parameters later on,
			// any possible lockings to this resource will get lost.
			mResource->setResource ( resource );

			// we still need to notify the contact in case the status
			// of this resource changed
			notifyRelevantContacts ( jid );

			return;
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Adding new resource " << resource.name() << " for " << jid.userHost() << endl;

	// create new resource instance and add it to the dictionary
	JabberResource *newResource = new JabberResource(jid, resource);
	connect ( newResource, SIGNAL ( destroyed (QObject *) ), this, SLOT ( slotResourceDestroyed (QObject *) ) );
	mPool.append ( newResource );

	// send notifications out to the relevant contacts that
	// a new resource is available for them
	notifyRelevantContacts ( jid );

}

void JabberResourcePool::removeResource ( const XMPP::Jid &jid, const XMPP::Resource &resource )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Removing resource " << resource.name() << " from " << jid.userHost() << endl;

	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.userHost().lower()) && (mResource->resource().name().lower() == resource.name().lower()) )
		{
			mPool.remove ();
			notifyRelevantContacts ( jid );
			return;
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: No match found!" << endl;

}

void JabberResourcePool::removeAllResources ( const XMPP::Jid &jid )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Removing all resources for " << jid.userHost() << endl;

	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( mResource->jid().userHost().lower() == jid.userHost().lower() )
		{
			// only remove preselected resource in case there is one
			if ( !jid.resource().isEmpty () && ( jid.resource () == mResource->resource().name () ) )
				mPool.remove ();
		}
	}

}

void JabberResourcePool::clear ()
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Clearing the resource pool." << endl;

	/*
	 * Since many contacts can have multiple resources, we can't simply delete
	 * each resource and trigger a notification upon each deletion. This would
	 * cause lots of status updates in the GUI and create unnecessary flicker
	 * and API traffic. Instead, collect all JIDs, clear the dictionary
	 * and then notify all JIDs after the resources have been deleted.
	 */

	QStringList jidList;

	for ( JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next () )
	{
		jidList += mResource->jid().full ();
	}

	/*
	 * Since mPool has autodeletion enabled, this will cause all
	 * items to be deleted. The lock list will be cleaned automatically.
	 */
	mPool.clear ();

	/*
	 * Now go through the list of JIDs and notify each contact
	 * of its status change
	 */
	for ( QStringList::Iterator it = jidList.begin (); it != jidList.end (); ++it )
	{
		notifyRelevantContacts ( XMPP::Jid ( *it ) );
	}

}

void JabberResourcePool::lockToResource ( const XMPP::Jid &jid, const XMPP::Resource &resource )
{

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Locking " << jid.full() << " to " << resource.name() << endl;

	// remove all existing locks first
	removeLock ( jid );

	// find the resource in our dictionary that matches
	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.full().lower()) && (mResource->resource().name().lower() == resource.name().lower()) )
		{
			mLockList.append ( mResource );
			return;
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: No match found!" << endl;

}

void JabberResourcePool::removeLock ( const XMPP::Jid &jid )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Removing resource lock for " << jid.userHost() << endl;

	// find the resource in our dictionary that matches
	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( (mResource->jid().userHost().lower() == jid.userHost().lower()) )
		{
			mLockList.remove (mResource);
		}
	}

	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "No locks found." << endl;

}

const XMPP::Resource &JabberResourcePool::lockedResource ( const XMPP::Jid &jid )
{

	// check if the JID already carries a resource, then we will have to use that one
	if ( !jid.resource().isEmpty () )
	{
		// we are subscribed to a JID, find the according resource in the pool
		for ( JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next () )
		{
			if ( ( mResource->jid().userHost().lower () == jid.userHost().lower () ) && ( mResource->resource().name () == jid.resource () ) )
			{
				return mResource->resource ();
			}
		}

		kdDebug ( JABBER_DEBUG_GLOBAL ) << k_funcinfo << "WARNING: No resource found in pool, returning as offline." << endl;

		return EmptyResource;
	}

	// see if we have a locked resource
	for(JabberResource *mResource = mLockList.first (); mResource; mResource = mLockList.next ())
	{
		if ( mResource->jid().userHost().lower() == jid.userHost().lower() )
		{
			kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "Current lock for " << jid.userHost () << " is '" << mResource->resource().name () << "'" << endl;
			return mResource->resource ();
		}
	}

	kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "No lock available for " << jid.userHost () << endl;

	// there's no locked resource, return an empty resource
	return EmptyResource;

}

const XMPP::Resource &JabberResourcePool::bestResource ( const XMPP::Jid &jid, bool honourLock )
{
	kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Determining best resource for " << jid.full () << endl;

	// FIXME: the code below would be more efficient if it would cache results

	if ( honourLock )
	{
		// if we are locked to a certain resource, always return that one
		const XMPP::Resource &mResource = lockedResource ( jid );
		if ( !mResource.name().isEmpty() )
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "We have a locked resource '" << mResource.name () << "' for " << jid.full () << endl;
			return mResource;
		}
	}

	JabberResource *bestResource = 0L;
	JabberResource *currentResource = 0L;

	for(currentResource = mPool.first (); currentResource; currentResource = mPool.next ())
	{
		// make sure we are only looking up resources for the specified JID
		if ( currentResource->jid().userHost().lower() != jid.userHost().lower() )
		{
			continue;
		}

		// take first resource if no resource has been chosen yet
		if(!bestResource)
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Taking '" << currentResource->resource().name () << "' as first available resource." << endl;

			bestResource = currentResource;
			continue;
		}

		if(currentResource->resource().priority() > bestResource->resource().priority())
		{
			kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Using '" << currentResource->resource().name () << "' due to better priority." << endl;

			// got a better match by priority
			bestResource = currentResource;
		}
		else
		{
			if(currentResource->resource().priority() == bestResource->resource().priority())
			{
				if(currentResource->resource().status().timeStamp() > bestResource->resource().status().timeStamp())
				{
					kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "Using '" << currentResource->resource().name () << "' due to better timestamp." << endl;

					// got a better match by timestamp (priorities are equal)
					bestResource = currentResource;
				}
			}
		}
	}

	return (bestResource == 0L) ? EmptyResource : bestResource->resource();

}

void JabberResourcePool::findResources ( const XMPP::Jid &jid, ResourceList &resourceList )
{

	for(JabberResource *mResource = mPool.first (); mResource; mResource = mPool.next ())
	{
		if ( mResource->jid().userHost().lower() == jid.userHost().lower() )
		{
			// we found a resource for the JID, let's see if the JID already contains a resource
			if ( !jid.resource().isEmpty() && ( jid.resource().lower() != mResource->resource().name().lower() ) )
				// the JID contains a resource but it's not the one we have in the dictionary,
				// thus we have to ignore this resource
				continue;

			resourceList.append ( mResource->resource() );
		}
	}

}

#include "jabberresourcepool.moc"
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <os>
#include <net/inet4>
#include <statman>
#include <profile>
#include <cstdio>
#include <timers>

#define CLIENT_PORT 1337
#define SERVER_PORT 1338
#define NCAT_RECEIVE_PORT 9000

#define SEND_BUF_LEN 1300
#define SERVER_TEST_LEN 10
#define PACKETS_PER_INTERVAL 50000

using namespace net::ip4;

uint64_t  packets_rx{0};
uint64_t  packets_tx{0};
uint64_t  initial_packets_rx{0};
uint64_t  initial_packets_tx{0};
uint64_t  prev_packets_rx{0};
uint64_t  prev_packets_tx{0};
uint64_t  total_packets_rx{0};
uint64_t  total_packets_tx{0};
uint64_t  data_len{0};
bool      timestamps{true};
bool      first_time{true};
bool      data_received{false};
std::chrono::milliseconds dack{40};
uint64_t  first_ts = 0;
uint64_t  sample_ts = 0;
uint64_t  last_ts = 0;

struct activity {
  void reset() {
  }
  void print(activity& other) {
    auto tdiff = total - other.total;
    auto sdiff = asleep - other.asleep;
    if (tdiff > 0) {
      double idle = sdiff / (float) tdiff;
      printf("* CPU was %.2f%% idle\n", idle * 100.0);
    }
  }
  uint64_t total;
  uint64_t asleep;
};
activity activity_before;
activity activity_after;

void init_sample_stats()
{
    data_len = 0;
    initial_packets_rx = Statman::get().get_by_name("eth0.ethernet.packets_rx").get_uint64();
    initial_packets_tx = Statman::get().get_by_name("eth0.ethernet.packets_tx").get_uint64();
    prev_packets_rx  = initial_packets_rx;
    prev_packets_tx = initial_packets_tx;
    first_ts = OS::nanos_since_boot();
    sample_ts = last_ts = first_ts;
    activity_before.reset();
}

void measure_sample_stats()
{
    static uint64_t diff;
    auto prev_diff = diff;

    diff = last_ts - first_ts;
    activity_after.reset();

    activity_after.print(activity_before);

    uint64_t now_rx = Statman::get().get_by_name("eth0.ethernet.packets_rx").get_uint64();
    uint64_t now_tx = Statman::get().get_by_name("eth0.ethernet.packets_tx").get_uint64();

    packets_rx  = now_rx - prev_packets_rx;
    packets_tx  = now_tx - prev_packets_tx;
    prev_packets_rx = now_rx;
    prev_packets_tx = now_tx;
    total_packets_rx = now_rx - initial_packets_rx;
    total_packets_tx = now_tx - initial_packets_tx;

    printf("-------------------Start-----------------\n");
    printf("Packets RX [%llu] TX [%llu]\n", packets_rx, packets_tx);
    printf("Total Packets RX [%llu] TX [%llu]\n", total_packets_rx, total_packets_tx);

    double prev_durs = ((double) (diff - prev_diff) / 1000000000L);
    double total_durs   = ((double)diff) / 1000000000L;
    double mbits  = (data_len/(1024*1024)*8) / total_durs;
    printf("Duration: %.2fs, Total Duration: %.2fs, "
          " Payload: %lld MB %.2f MBit/s\n\n",
          prev_durs, total_durs, data_len /(1024*1024), mbits);
    printf("-------------------End-------------------\n");
}

void send_cb() {
    data_len += SEND_BUF_LEN;
}

void send_data(net::UDPSocket& client, net::Inet<net::IP4>& inet) {
    for (size_t i = 0; i < PACKETS_PER_INTERVAL; i++) {
        const char c = 'A' + (i % 26);
        std::string buff(SEND_BUF_LEN, c);
        client.sendto(inet.gateway(), NCAT_RECEIVE_PORT, buff.data(), buff.size(), send_cb);
    }
    sample_ts = last_ts;
    last_ts = OS::nanos_since_boot();
    printf("Done sending data\n");
}
void Service::start(const std::string& input) {
#ifdef USERSPACE_LINUX
    extern void create_network_device(int N, const char* route, const char* ip);
    create_network_device(0, "10.0.0.0/24", "10.0.0.1");

    // Get the first IP stack configured from config.json
    auto& inet = net::Super_stack::get<net::IP4>(0);
    inet.network_config({10,0,0,42}, {255,255,255,0}, {10,0,0,1});
#else
    auto& inet = net::Super_stack::get<net::IP4>(0);
#endif
    auto& udp = inet.udp();

    if (input.find("client") != std::string::npos) {
        auto& client = udp.bind(CLIENT_PORT);
        printf("Running as Client\n");

        init_sample_stats();
        printf("Sending to %s!\n", inet.gateway().str().c_str());
        send_data(client, inet);
        int timer = Timers::periodic(1s, 2s,
          [&timer, &inet, &client] (uint32_t) {
            static int secs = 0;
            measure_sample_stats();
            send_data(client, inet);
              /* Run the test for 10 seconds */
              if (secs++ == 10) {
                  Timers::stop(timer);
                  printf("Stopping test\n");
              }
          });
    } else {
        auto& server = udp.bind(SERVER_PORT);
        printf("Running as Server. Waiting for data...\n");
        server.on_read(
            []([[maybe_unused]]auto addr,
                      [[maybe_unused]]auto port,
                      const char* buf, int len)
        {
            auto data = std::string(buf, len);
            using namespace std::chrono;
            if (first_time) {
                printf("Received data..\n");
                init_sample_stats();
                first_time = false;
            }
            //CHECK(1, "Getting UDP data from %s:  %d -> %s",
            //    addr.str().c_str(), port, data.c_str());
            data_len += data.size();
            data_received = true;
            sample_ts = last_ts;
            last_ts = OS::nanos_since_boot();
      });

      Timers::periodic(5s, 5s,
      [] (uint32_t) {
        if (data_received) {
            measure_sample_stats();
            data_received = false;
        }
      });
    }
}
<commit_msg>examples: Fixed timer crash in UDP perf<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <os>
#include <net/inet4>
#include <statman>
#include <profile>
#include <cstdio>
#include <timers>

#define CLIENT_PORT 1337
#define SERVER_PORT 1338
#define NCAT_RECEIVE_PORT 9000

#define SEND_BUF_LEN 1300
#define SERVER_TEST_LEN 10
#define PACKETS_PER_INTERVAL 50000

using namespace net::ip4;

uint64_t  packets_rx{0};
uint64_t  packets_tx{0};
uint64_t  initial_packets_rx{0};
uint64_t  initial_packets_tx{0};
uint64_t  prev_packets_rx{0};
uint64_t  prev_packets_tx{0};
uint64_t  total_packets_rx{0};
uint64_t  total_packets_tx{0};
uint64_t  data_len{0};
bool      timestamps{true};
bool      first_time{true};
bool      data_received{false};
std::chrono::milliseconds dack{40};
uint64_t  first_ts = 0;
uint64_t  sample_ts = 0;
uint64_t  last_ts = 0;

struct activity {
  void reset() {
  }
  void print(activity& other) {
    auto tdiff = total - other.total;
    auto sdiff = asleep - other.asleep;
    if (tdiff > 0) {
      double idle = sdiff / (float) tdiff;
      printf("* CPU was %.2f%% idle\n", idle * 100.0);
    }
  }
  uint64_t total;
  uint64_t asleep;
};
activity activity_before;
activity activity_after;

void init_sample_stats()
{
    data_len = 0;
    initial_packets_rx = Statman::get().get_by_name("eth0.ethernet.packets_rx").get_uint64();
    initial_packets_tx = Statman::get().get_by_name("eth0.ethernet.packets_tx").get_uint64();
    prev_packets_rx  = initial_packets_rx;
    prev_packets_tx = initial_packets_tx;
    first_ts = OS::nanos_since_boot();
    sample_ts = last_ts = first_ts;
    activity_before.reset();
}

void measure_sample_stats()
{
    static uint64_t diff;
    auto prev_diff = diff;

    diff = last_ts - first_ts;
    activity_after.reset();

    activity_after.print(activity_before);

    uint64_t now_rx = Statman::get().get_by_name("eth0.ethernet.packets_rx").get_uint64();
    uint64_t now_tx = Statman::get().get_by_name("eth0.ethernet.packets_tx").get_uint64();

    packets_rx  = now_rx - prev_packets_rx;
    packets_tx  = now_tx - prev_packets_tx;
    prev_packets_rx = now_rx;
    prev_packets_tx = now_tx;
    total_packets_rx = now_rx - initial_packets_rx;
    total_packets_tx = now_tx - initial_packets_tx;

    printf("-------------------Start-----------------\n");
    printf("Packets RX [%llu] TX [%llu]\n", packets_rx, packets_tx);
    printf("Total Packets RX [%llu] TX [%llu]\n", total_packets_rx, total_packets_tx);

    double prev_durs = ((double) (diff - prev_diff) / 1000000000L);
    double total_durs   = ((double)diff) / 1000000000L;
    double mbits  = (data_len/(1024*1024)*8) / total_durs;
    printf("Duration: %.2fs, Total Duration: %.2fs, "
          " Payload: %lld MB %.2f MBit/s\n\n",
          prev_durs, total_durs, data_len /(1024*1024), mbits);
    printf("-------------------End-------------------\n");
}

void send_cb() {
    data_len += SEND_BUF_LEN;
}

void send_data(net::UDPSocket& client, net::Inet<net::IP4>& inet) {
    for (size_t i = 0; i < PACKETS_PER_INTERVAL; i++) {
        const char c = 'A' + (i % 26);
        std::string buff(SEND_BUF_LEN, c);
        client.sendto(inet.gateway(), NCAT_RECEIVE_PORT, buff.data(), buff.size(), send_cb);
    }
    sample_ts = last_ts;
    last_ts = OS::nanos_since_boot();
    printf("Done sending data\n");
}
void Service::start(const std::string& input) {
#ifdef USERSPACE_LINUX
    extern void create_network_device(int N, const char* route, const char* ip);
    create_network_device(0, "10.0.0.0/24", "10.0.0.1");

    // Get the first IP stack configured from config.json
    auto& inet = net::Super_stack::get<net::IP4>(0);
    inet.network_config({10,0,0,42}, {255,255,255,0}, {10,0,0,1});
#else
    auto& inet = net::Super_stack::get<net::IP4>(0);
#endif
    auto& udp = inet.udp();

    if (input.find("client") != std::string::npos) {
        auto& client = udp.bind(CLIENT_PORT);
        printf("Running as Client\n");

        init_sample_stats();
        printf("Sending to %s!\n", inet.gateway().str().c_str());
        send_data(client, inet);
        Timers::periodic(1s, 1s,
          [&inet, &client] (uint32_t timer) {
            static int secs = 0;
            measure_sample_stats();
            send_data(client, inet);
              /* Run the test for 10 seconds */
              if (secs++ == 10) {
                  Timers::stop(timer);
                  printf("Stopping test\n");
              }
          });
    } else {
        auto& server = udp.bind(SERVER_PORT);
        printf("Running as Server. Waiting for data...\n");
        server.on_read(
            []([[maybe_unused]]auto addr,
                      [[maybe_unused]]auto port,
                      const char* buf, int len)
        {
            auto data = std::string(buf, len);
            using namespace std::chrono;
            if (first_time) {
                printf("Received data..\n");
                init_sample_stats();
                first_time = false;
            }
            //CHECK(1, "Getting UDP data from %s:  %d -> %s",
            //    addr.str().c_str(), port, data.c_str());
            data_len += data.size();
            data_received = true;
            sample_ts = last_ts;
            last_ts = OS::nanos_since_boot();
      });

      Timers::periodic(5s, 5s,
      [] (uint32_t) {
        if (data_received) {
            measure_sample_stats();
            data_received = false;
        }
      });
    }
}
<|endoftext|>


<commit_before>/*
    This file is part of KDE.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "listmodel.h"

#include <klocale.h>
#include <kdebug.h>

using namespace KXForms;

ListModel::ListModel( QObject *parent ) : QAbstractTableModel( parent )
{
}

ListModel::~ListModel()
{
  qDeleteAll( mItems );
}

int ListModel::rowCount( const QModelIndex &parent ) const
{
  Q_UNUSED( parent );
  return mItems.size();
}

int ListModel::columnCount( const QModelIndex &parent ) const
{
  Q_UNUSED( parent );
  return 2;
}

QVariant ListModel::data( const QModelIndex & index, int role ) const
{
  if ( role == Qt::DisplayRole ) {
    Item *item = mItems.at( index.row() );
    if ( index.column() == 0 ) return item->label;
    else if ( index.column() == 1 ) return item->ref.toString();
  }
  return QVariant();
}

QVariant ListModel::headerData ( int section, Qt::Orientation orientation,
  int role ) const
{
  if ( orientation == Qt::Horizontal ) {
    if ( role == Qt::DisplayRole ) {
      if ( section == 0 ) {
        if ( mLabel.isEmpty() ) return i18n("Label");
        else return mLabel;
      } else if ( section == 1 ) {
        return i18n("Reference");
      }
    }
  }
  return QVariant();
}

void ListModel::addItem( const QString &label, const Reference &ref )
{
  beginInsertRows( QModelIndex(), mItems.size(), mItems.size() );

  Item *item = new Item;
  item->label = label;
  item->ref = ref;
  mItems.append( item );

  endInsertRows();
}

int ListModel::itemCount( const QString &itemClass )
{
  int count = 0;

  foreach( Item *item, mItems ) {
    if ( item->ref.lastSegment().name() == itemClass ) count++;
  }

  return count;
}

bool ListModel::removeRows( int row, int count, const QModelIndex &parent )
{
  beginRemoveRows( parent, row, row + count - 1 );

  for( int i = 0; i < count; ++i ) {
    Item *item = mItems.at( row );
    mItems.removeAt( row );
    delete item;
  }

  endRemoveRows();

  return true;
}

void ListModel::recalculateSegmentCounts()
{
  int startRow = 0;
  int endRow = 0;

  QMap<QString, int> counts;

  foreach( Item *item, mItems ) {
    int count = 1;
    Reference::Segment segment = item->ref.segments().last();
    QMap<QString, int>::ConstIterator it = counts.find( segment.name() );
    if ( it != counts.end() ) count = it.value();

    if ( count != segment.count() ) {
      item->ref.lastSegment().setCount( count );
    } else {
      startRow++;
    }

    endRow++;

    counts.insert( segment.name(), ++count );
  }

  emit dataChanged( createIndex( startRow, 1 ), createIndex( endRow, 1 ) );
}

ListModel::Item *ListModel::item( const QModelIndex &index )
{
  return mItems.at( index.row() );
}

void ListModel::setLabel( const QString &label )
{
  mLabel = label;
}

QString ListModel::label() const
{
  return mLabel;
}

void ListModel::clear()
{
  removeRows( 0, rowCount() );
}

<commit_msg>crash--<commit_after>/*
    This file is part of KDE.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "listmodel.h"

#include <klocale.h>
#include <kdebug.h>

using namespace KXForms;

ListModel::ListModel( QObject *parent ) : QAbstractTableModel( parent )
{
}

ListModel::~ListModel()
{
  qDeleteAll( mItems );
}

int ListModel::rowCount( const QModelIndex &parent ) const
{
  Q_UNUSED( parent );
  return mItems.size();
}

int ListModel::columnCount( const QModelIndex &parent ) const
{
  Q_UNUSED( parent );
  return 2;
}

QVariant ListModel::data( const QModelIndex & index, int role ) const
{
  if ( role == Qt::DisplayRole ) {
    Item *item = mItems.at( index.row() );
    if ( index.column() == 0 ) return item->label;
    else if ( index.column() == 1 ) return item->ref.toString();
  }
  return QVariant();
}

QVariant ListModel::headerData ( int section, Qt::Orientation orientation,
  int role ) const
{
  if ( orientation == Qt::Horizontal ) {
    if ( role == Qt::DisplayRole ) {
      if ( section == 0 ) {
        if ( mLabel.isEmpty() ) return i18n("Label");
        else return mLabel;
      } else if ( section == 1 ) {
        return i18n("Reference");
      }
    }
  }
  return QVariant();
}

void ListModel::addItem( const QString &label, const Reference &ref )
{
  beginInsertRows( QModelIndex(), mItems.size(), mItems.size() );

  Item *item = new Item;
  item->label = label;
  item->ref = ref;
  mItems.append( item );

  endInsertRows();
}

int ListModel::itemCount( const QString &itemClass )
{
  int count = 0;

  foreach( Item *item, mItems ) {
    if ( item->ref.lastSegment().name() == itemClass ) count++;
  }

  return count;
}

bool ListModel::removeRows( int row, int count, const QModelIndex &parent )
{
  beginRemoveRows( parent, row, row + count - 1 );

  for( int i = 0; i < count; ++i ) {
    Item *item = mItems.at( row );
    mItems.removeAt( row );
    delete item;
  }

  endRemoveRows();

  return true;
}

void ListModel::recalculateSegmentCounts()
{
  int startRow = 0;
  int endRow = 0;

  QMap<QString, int> counts;

  foreach( Item *item, mItems ) {
    int count = 1;
    Reference::Segment segment = item->ref.segments().last();
    QMap<QString, int>::ConstIterator it = counts.find( segment.name() );
    if ( it != counts.end() ) count = it.value();

    if ( count != segment.count() ) {
      item->ref.lastSegment().setCount( count );
    } else {
      startRow++;
    }

    endRow++;

    counts.insert( segment.name(), ++count );
  }

  emit dataChanged( createIndex( startRow, 1 ), createIndex( endRow, 1 ) );
}

ListModel::Item *ListModel::item( const QModelIndex &index )
{
  return mItems.at( index.row() );
}

void ListModel::setLabel( const QString &label )
{
  mLabel = label;
}

QString ListModel::label() const
{
  return mLabel;
}

void ListModel::clear()
{
  if( rowCount() > 0 )
    removeRows( 0, rowCount() );
}

<|endoftext|>


<commit_before>#include "ThreadsPool.h"

ThreadsPool::ThreadsPool(int thread_num,int request_max):_thread_num(thread_num),_conn_max(request_max),is_work(true){
    threads.clear();
    threads.resize(_thread_num);
    for(int i=0; i< _thread_num; i++){
        std::cout<<"create thread "<<i<<"."<<std::endl;
        if(pthread_create(&threads[i],NULL,worker,this)!=0){
            threads.clear();
            break;
        }
        else if(pthread_detach(threads[i])){
            threads.clear();
            break;
        }
    }
    std::cout<<"threads create complete."<<std::endl;
}

ThreadsPool::~ThreadsPool(){
    threads.clear();
	while(!conn_pool.empty()){
		conn_pool.pop();
	}
	req_pool.clear();
	res_pool.clear();
    is_work = false;
}

bool ThreadsPool::add(int conn,char *read_buff,int buff_size,int req_or_res){
    locker.lock();
    if(conn_pool.size() >= _conn_max){
        locker.unlock();
        return false;
    }
	if(req_or_res == 0){//request
		connection con;
		con.conn = conn;
		con.request_or_response = 0;
		conn_pool.push(con);

		//add to request pool
		std::map<int,Request*>::iterator it;
		it = req_pool.find(conn);
		std::cout<<"inin"<<std::endl;
		if(it != req_pool.end()){//found
			int old_size = req_pool[conn]->content_size;
			char *old_buff = req_pool[conn]->content;
			char *new_buff = new char[old_size+buff_size];
			strncpy(new_buff,old_buff,old_size);
			strncpy(new_buff+old_size,read_buff,buff_size);
			delete[] old_buff;
			req_pool[conn]->content = new_buff;
			req_pool[conn]->content_size = old_size+buff_size;
			return true;
		}
		else{
			Request *r;
			request_init(r);
			r->content_size = buff_size;
			r->content = read_buff;
			req_pool.insert(std::make_pair<int,Request*>(conn,r));
			return true;
		}

	}
    locker.unlock();
    status_queue.post();
    return true;
}

void* ThreadsPool::worker(void* arg){
    ThreadsPool *tp = (ThreadsPool*)arg;
    tp->run();
    return tp;
}

void ThreadsPool::run(){
    while(is_work){
        status_queue.wait();
        locker.lock();
        if(conn_pool.empty()){
            locker.unlock();
            continue;
        }
		connection c = conn_pool.front();
		conn_pool.pop();
		if(c.request_or_response == 0){//request
			std::map<int,Request*>::iterator it;
			it = req_pool.find(c.conn);
			if(it!=req_pool.end()){//found
				Request *req = it->second;
				//parser request
			}
			else{
				continue;
			}
		}

        locker.unlock();
        //if(c){
        //    std::cout<<"ok"<<std::endl;
            //r->process();
        //}
    }
}

<commit_msg>add main<commit_after>#include "ThreadsPool.h"

ThreadsPool::ThreadsPool(int thread_num,int request_max):_thread_num(thread_num),_conn_max(request_max),is_work(true){
    threads.clear();
    threads.resize(_thread_num);
    for(int i=0; i< _thread_num; i++){
        std::cout<<"create thread "<<i<<"."<<std::endl;
        if(pthread_create(&threads[i],NULL,worker,this)!=0){
            threads.clear();
            break;
        }
        else if(pthread_detach(threads[i])){
            threads.clear();
            break;
        }
    }
    std::cout<<"threads create complete."<<std::endl;
}

ThreadsPool::~ThreadsPool(){
    threads.clear();
	while(!conn_pool.empty()){
		conn_pool.pop();
	}
	req_pool.clear();
	res_pool.clear();
    is_work = false;
}

bool ThreadsPool::add(int conn,char *read_buff,int buff_size,int req_or_res){
    locker.lock();
    if(conn_pool.size() >= _conn_max){
        locker.unlock();
        return false;
    }
	if(req_or_res == 0){//request
		connection con;
		con.conn = conn;
		con.request_or_response = 0;
		conn_pool.push(con);

		//add to request pool
		std::map<int,Request*>::iterator it;
		it = req_pool.find(conn);
		std::cout<<"inin"<<std::endl;
		if(it != req_pool.end()){//found
			int old_size = req_pool[conn]->content_size;
			char *old_buff = req_pool[conn]->content;
			char *new_buff = new char[old_size+buff_size];
			strncpy(new_buff,old_buff,old_size);
			strncpy(new_buff+old_size,read_buff,buff_size);
			delete[] old_buff;
			req_pool[conn]->content = new_buff;
			req_pool[conn]->content_size = old_size+buff_size;
			return true;
		}
		else{
			Request *r;
			request_init(r);
			r->content_size = buff_size;
			r->content = read_buff;
			std::cout<<"insert null"<<std::endl;
			req_pool.insert(std::make_pair<int,Request*>(conn,r));
			std::cout<<"insert null"<<std::endl;
			return true;
		}

	}
    locker.unlock();
    status_queue.post();
    return true;
}

void* ThreadsPool::worker(void* arg){
    ThreadsPool *tp = (ThreadsPool*)arg;
    tp->run();
    return tp;
}

void ThreadsPool::run(){
    while(is_work){
        status_queue.wait();
        locker.lock();
        if(conn_pool.empty()){
            locker.unlock();
            continue;
        }
		connection c = conn_pool.front();
		conn_pool.pop();
		if(c.request_or_response == 0){//request
			std::map<int,Request*>::iterator it;
			it = req_pool.find(c.conn);
			if(it!=req_pool.end()){//found
				Request *req = it->second;
				//parser request
			}
			else{
				continue;
			}
		}

        locker.unlock();
        //if(c){
        //    std::cout<<"ok"<<std::endl;
            //r->process();
        //}
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Firestore/core/src/util/log.h"

#include <atomic>
#include <cstdio>
#include <string>

#include "Firestore/core/src/util/hard_assert.h"

namespace firebase {
namespace firestore {
namespace util {
namespace {

std::atomic<LogLevel> g_log_level(kLogLevelNotice);

}  // namespace

void LogSetLevel(LogLevel level) {
  g_log_level = level;
}

bool LogIsLoggable(LogLevel level) {
  return level >= g_log_level;
}

void LogMessage(LogLevel log_level, const std::string& message) {
  if (log_level < g_log_level) {
    return;
  }

  const char* level_word;

  switch (log_level) {
    case kLogLevelDebug:
      level_word = "DEBUG";
      break;
    case kLogLevelWarning:
      level_word = "WARNING";
      break;
    case kLogLevelError:
      level_word = "ERROR";
      break;
    default:
      UNREACHABLE();
      break;
  }

  printf("%s: %s\n", level_word, message.c_str());
}

}  // namespace util
}  // namespace firestore
}  // namespace firebase
<commit_msg>log_stdio.cc: add missing switch block for kLogLevelNotice (#8951)<commit_after>/*
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Firestore/core/src/util/log.h"

#include <atomic>
#include <cstdio>
#include <string>

#include "Firestore/core/src/util/hard_assert.h"

namespace firebase {
namespace firestore {
namespace util {
namespace {

std::atomic<LogLevel> g_log_level(kLogLevelNotice);

}  // namespace

void LogSetLevel(LogLevel level) {
  g_log_level = level;
}

bool LogIsLoggable(LogLevel level) {
  return level >= g_log_level;
}

void LogMessage(LogLevel log_level, const std::string& message) {
  if (log_level < g_log_level) {
    return;
  }

  const char* level_word;

  switch (log_level) {
    case kLogLevelDebug:
      level_word = "DEBUG";
      break;
    case kLogLevelWarning:
      level_word = "WARNING";
      break;
    case kLogLevelError:
      level_word = "ERROR";
      break;
    case kLogLevelNotice:
      level_word = "INFO";
      break;
    default:
      UNREACHABLE();
      break;
  }

  printf("%s: %s\n", level_word, message.c_str());
}

}  // namespace util
}  // namespace firestore
}  // namespace firebase
<|endoftext|>


<commit_before><commit_msg>disable a failing test (ExtensionApiTest.Overrides) TBR: tony<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: SharedConnection.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: oj $ $Date: 2002-08-12 09:21:58 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBA_CORE_SHARED_CONNECTION_HXX
#include "SharedConnection.hxx"
#endif

namespace dbaccess
{
    using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
//  using namespace ::com::sun::star::reflection;
using namespace connectivity;

Reference< XStatement > SAL_CALL OSharedConnection::createStatement(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->createStatement();
}
// --------------------------------------------------------------------------------
Reference< XPreparedStatement > SAL_CALL OSharedConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->prepareStatement(sql);
}
// --------------------------------------------------------------------------------
Reference< XPreparedStatement > SAL_CALL OSharedConnection::prepareCall( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->prepareCall(sql);
}
// --------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OSharedConnection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->nativeSQL(sql);
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL OSharedConnection::getAutoCommit(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getAutoCommit();
}
// --------------------------------------------------------------------------------
void SAL_CALL OSharedConnection::commit(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    m_xConnection->commit();
}
// --------------------------------------------------------------------------------
void SAL_CALL OSharedConnection::rollback(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    m_xConnection->rollback();
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL OSharedConnection::isClosed(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    return m_xConnection->isClosed();
}
// --------------------------------------------------------------------------------
Reference< XDatabaseMetaData > SAL_CALL OSharedConnection::getMetaData(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getMetaData();
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL OSharedConnection::isReadOnly(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->isReadOnly();
}
// --------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OSharedConnection::getCatalog(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getCatalog();
}
// --------------------------------------------------------------------------------
sal_Int32 SAL_CALL OSharedConnection::getTransactionIsolation(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getTransactionIsolation();
}
// --------------------------------------------------------------------------------
Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OSharedConnection::getTypeMap(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getTypeMap();
}
// -----------------------------------------------------------------------------

//........................................................................
}   // namespace dbaccess
//........................................................................

<commit_msg>INTEGRATION: CWS insight01 (1.2.110); FILE MERGED 2004/02/18 14:45:21 oj 1.2.110.1: #111075# fix rfcount problem<commit_after>/*************************************************************************
 *
 *  $RCSfile: SharedConnection.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 15:06:11 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBA_CORE_SHARED_CONNECTION_HXX
#include "SharedConnection.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

namespace dbaccess
{
    using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
//  using namespace ::com::sun::star::reflection;
using namespace connectivity;

DBG_NAME(OSharedConnection)
OSharedConnection::OSharedConnection(Reference< XAggregation >& _rxProxyConnection)
            : OSharedConnection_BASE(m_aMutex)
{
    DBG_CTOR(OSharedConnection,NULL);
    setDelegation(_rxProxyConnection,m_refCount);
}
// -----------------------------------------------------------------------------
OSharedConnection::~OSharedConnection()
{
    DBG_DTOR(OSharedConnection,NULL);
}
// -----------------------------------------------------------------------------
void SAL_CALL OSharedConnection::disposing(void)
{
    OSharedConnection_BASE::disposing();
    OConnectionWrapper::disposing();
}
// -----------------------------------------------------------------------------
Reference< XStatement > SAL_CALL OSharedConnection::createStatement(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->createStatement();
}
// --------------------------------------------------------------------------------
Reference< XPreparedStatement > SAL_CALL OSharedConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->prepareStatement(sql);
}
// --------------------------------------------------------------------------------
Reference< XPreparedStatement > SAL_CALL OSharedConnection::prepareCall( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->prepareCall(sql);
}
// --------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OSharedConnection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->nativeSQL(sql);
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL OSharedConnection::getAutoCommit(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getAutoCommit();
}
// --------------------------------------------------------------------------------
void SAL_CALL OSharedConnection::commit(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    m_xConnection->commit();
}
// --------------------------------------------------------------------------------
void SAL_CALL OSharedConnection::rollback(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    m_xConnection->rollback();
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL OSharedConnection::isClosed(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    return m_xConnection->isClosed();
}
// --------------------------------------------------------------------------------
Reference< XDatabaseMetaData > SAL_CALL OSharedConnection::getMetaData(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getMetaData();
}
// --------------------------------------------------------------------------------
sal_Bool SAL_CALL OSharedConnection::isReadOnly(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->isReadOnly();
}
// --------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OSharedConnection::getCatalog(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getCatalog();
}
// --------------------------------------------------------------------------------
sal_Int32 SAL_CALL OSharedConnection::getTransactionIsolation(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getTransactionIsolation();
}
// --------------------------------------------------------------------------------
Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OSharedConnection::getTypeMap(  ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    checkDisposed(rBHelper.bDisposed);

    return m_xConnection->getTypeMap();
}
// -----------------------------------------------------------------------------

//........................................................................
}   // namespace dbaccess
//........................................................................

<|endoftext|>