<commit_before>////////////////////////////////////////////////////////////////////////////////
// taskd - Task Server
//
// Copyright 2010 - 2012, Göteborg Bit Factory.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <taskd.h>
#include <text.h>

////////////////////////////////////////////////////////////////////////////////
int command_init (Config& config, const std::vector <std::string>& args)
{
  int status = 0;

  // Standard argument processing.
  bool verbose     = true;
  bool debug       = false;
  std::string root = "";

  std::vector <std::string>::const_iterator i;
  for (i = ++(args.begin ()); i != args.end (); ++i)
  {
         if (closeEnough ("--quiet",  *i, 3)) verbose = false;
    else if (closeEnough ("--debug",  *i, 3)) debug   = true;
    else if (closeEnough ("--data",   *i, 3)) root    = *(++i);
    else if (taskd_applyOverride (config, *i))   ;
    else
      throw std::string ("ERROR: Unrecognized argument '") + *i + "'";

    // Verify that root exists.
    if (root == "")
      throw std::string ("The '--data' option is required.");

    Directory root_dir (root);
    if (!root_dir.exists ())
      throw std::string ("The '--data' path does not exist.");

    if (!root_dir.is_directory ())
      throw std::string ("The '--data' path is not a directory.");

    if (!root_dir.readable ())
      throw std::string ("The '--data' directory is not readable.");

    if (!root_dir.writable ())
      throw std::string ("The '--data' directory is not writable.");

    if (!root_dir.executable ())
      throw std::string ("The '--data' directory is not executable.");

    // Create the data structure.
    Directory sub (root_dir);
    sub.cd ();
    sub += "orgs";
    if (!sub.create ())
      throw std::string ("Could not create '") + sub._data + "'.";

    // TODO Dump the config file?
  }

  return status;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Bug<commit_after>////////////////////////////////////////////////////////////////////////////////
// taskd - Task Server
//
// Copyright 2010 - 2012, Göteborg Bit Factory.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <taskd.h>
#include <text.h>

////////////////////////////////////////////////////////////////////////////////
int command_init (Config& config, const std::vector <std::string>& args)
{
  int status = 0;

  // Standard argument processing.
  bool verbose     = true;
  bool debug       = false;
  std::string root = "";

  std::vector <std::string>::const_iterator i;
  for (i = ++(args.begin ()); i != args.end (); ++i)
  {
         if (closeEnough ("--quiet",  *i, 3)) verbose = false;
    else if (closeEnough ("--debug",  *i, 3)) debug   = true;
    else if (closeEnough ("--data",   *i, 3)) root    = *(++i);
    else if (taskd_applyOverride (config, *i))   ;
    else
      throw std::string ("ERROR: Unrecognized argument '") + *i + "'";
  }

  // Verify that root exists.
  if (root == "")
    throw std::string ("The '--data' option is required.");

  Directory root_dir (root);
  if (!root_dir.exists ())
    throw std::string ("The '--data' path does not exist.");

  if (!root_dir.is_directory ())
     throw std::string ("The '--data' path is not a directory.");

  if (!root_dir.readable ())
    throw std::string ("The '--data' directory is not readable.");

  if (!root_dir.writable ())
    throw std::string ("The '--data' directory is not writable.");

  if (!root_dir.executable ())
    throw std::string ("The '--data' directory is not executable.");

  // Create the data structure.
  Directory sub (root_dir);
  sub.cd ();
  sub += "orgs";
  if (!sub.create ())
    throw std::string ("Could not create '") + sub._data + "'.";

  // TODO Dump the config file?

  return status;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>#include "proc.h"
#include "serv.h"

struct BytesEqual{
	bool operator()(const Bytes &s1, const Bytes &s2) const {
		return (bool)(s1.compare(s2) == 0);
	}
};
struct BytesHash{
	size_t operator()(const Bytes &s1) const {
		unsigned long __h = 0;
		const char *p = s1.data();
		for (int i=0 ; i<s1.size(); i++)
			__h = 5*__h + p[i];
		return size_t(__h);
	}
};

#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#if GCC_VERSION >= 403
	#include <tr1/unordered_map>
	typedef std::tr1::unordered_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;
#else
	#ifdef NEW_MAC
		#include <unordered_map>
		typedef std::unordered_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;
	#else
		#include <ext/hash_map>
		typedef __gnu_cxx::hash_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;
	#endif
#endif

#define DEF_PROC(f) int proc_##f(Server *serv, Link *link, const Request &req, Response *resp)
	DEF_PROC(get);
	DEF_PROC(set);
	DEF_PROC(setx);
	DEF_PROC(setnx);
	DEF_PROC(getset);
	DEF_PROC(getbit);
	DEF_PROC(setbit);
	DEF_PROC(countbit);
	DEF_PROC(substr);
	DEF_PROC(getrange);
	DEF_PROC(strlen);
	DEF_PROC(redis_bitcount);
	DEF_PROC(del);
	DEF_PROC(incr);
	DEF_PROC(decr);
	DEF_PROC(scan);
	DEF_PROC(rscan);
	DEF_PROC(keys);
	DEF_PROC(exists);
	DEF_PROC(multi_exists);
	DEF_PROC(multi_get);
	DEF_PROC(multi_set);
	DEF_PROC(multi_del);

	DEF_PROC(hsize);
	DEF_PROC(hget);
	DEF_PROC(hset);
	DEF_PROC(hdel);
	DEF_PROC(hincr);
	DEF_PROC(hdecr);
	DEF_PROC(hclear);
	DEF_PROC(hgetall);
	DEF_PROC(hscan);
	DEF_PROC(hrscan);
	DEF_PROC(hkeys);
	DEF_PROC(hvals);
	DEF_PROC(hlist);
	DEF_PROC(hrlist);
	DEF_PROC(hexists);
	DEF_PROC(multi_hexists);
	DEF_PROC(multi_hsize);
	DEF_PROC(multi_hget);
	DEF_PROC(multi_hset);
	DEF_PROC(multi_hdel);

	DEF_PROC(zrank);
	DEF_PROC(zrrank);
	DEF_PROC(zrange);
	DEF_PROC(zrrange);
	DEF_PROC(zsize);
	DEF_PROC(zget);
	DEF_PROC(zset);
	DEF_PROC(zdel);
	DEF_PROC(zincr);
	DEF_PROC(zdecr);
	DEF_PROC(zclear);
	DEF_PROC(zscan);
	DEF_PROC(zrscan);
	DEF_PROC(zkeys);
	DEF_PROC(zlist);
	DEF_PROC(zrlist);
	DEF_PROC(zcount);
	DEF_PROC(zsum);
	DEF_PROC(zavg);
	DEF_PROC(zexists);
	DEF_PROC(zremrangebyrank);
	DEF_PROC(zremrangebyscore);
	DEF_PROC(multi_zexists);
	DEF_PROC(multi_zsize);
	DEF_PROC(multi_zget);
	DEF_PROC(multi_zset);
	DEF_PROC(multi_zdel);

	DEF_PROC(qsize);
	DEF_PROC(qfront);
	DEF_PROC(qback);
	DEF_PROC(qpush);
	DEF_PROC(qpush_front);
	DEF_PROC(qpush_back);
	DEF_PROC(qpop);
	DEF_PROC(qpop_front);
	DEF_PROC(qpop_back);
	DEF_PROC(qtrim_front);
	DEF_PROC(qtrim_back);
	DEF_PROC(qfix);
	DEF_PROC(qclear);
	DEF_PROC(qlist);
	DEF_PROC(qrlist);
	DEF_PROC(qslice);
	DEF_PROC(qrange);
	DEF_PROC(qget);
	DEF_PROC(qset);

	DEF_PROC(dump);
	DEF_PROC(sync140);
	DEF_PROC(info);
	DEF_PROC(compact);
	DEF_PROC(key_range);
	DEF_PROC(set_key_range);
	DEF_PROC(ttl);
	DEF_PROC(expire);
	DEF_PROC(clear_binlog);
	DEF_PROC(ping);
	DEF_PROC(auth);
#undef DEF_PROC

#define PROC(c, f)     {#c, f, 0, proc_##c, 0, 0, 0, 0}
#define PROC_KP1(c, f) {#c, f, 0, proc_##c, 0, 0, 0, 1}

static Command commands[] = {
	PROC_KP1(get, "r"),
	PROC_KP1(set, "wt"),
	PROC(setx, "wt"),
	PROC(setnx, "wt"),
	PROC(getset, "wt"),
	PROC(getbit, "r"),
	PROC(setbit, "wt"),
	PROC(countbit, "r"),
	PROC(substr, "r"),
	PROC(getrange, "r"),
	PROC(strlen, "r"),
	PROC(redis_bitcount, "r"),
	PROC(del, "wt"),
	PROC(incr, "wt"),
	PROC(decr, "wt"),
	PROC(scan, "rt"),
	PROC(rscan, "rt"),
	PROC(keys, "rt"),
	PROC(exists, "r"),
	PROC(multi_exists, "r"),
	PROC(multi_get, "rt"),
	PROC(multi_set, "wt"),
	PROC(multi_del, "wt"),

	PROC(hsize, "r"),
	PROC(hget, "r"),
	PROC(hset, "wt"),
	PROC(hdel, "wt"),
	PROC(hincr, "wt"),
	PROC(hdecr, "wt"),
	PROC(hclear, "wt"),
	PROC(hgetall, "rt"),
	PROC(hscan, "rt"),
	PROC(hrscan, "rt"),
	PROC(hkeys, "rt"),
	PROC(hvals, "rt"),
	PROC(hlist, "rt"),
	PROC(hrlist, "rt"),
	PROC(hexists, "r"),
	PROC(multi_hexists, "r"),
	PROC(multi_hsize, "r"),
	PROC(multi_hget, "rt"),
	PROC(multi_hset, "wt"),
	PROC(multi_hdel, "wt"),

	// because zrank may be extremly slow, execute in a seperate thread
	PROC(zrank, "rt"),
	PROC(zrrank, "rt"),
	PROC(zrange, "rt"),
	PROC(zrrange, "rt"),
	PROC(zsize, "r"),
	PROC(zget, "rt"),
	PROC(zset, "wt"),
	PROC(zdel, "wt"),
	PROC(zincr, "wt"),
	PROC(zdecr, "wt"),
	PROC(zclear, "wt"),
	PROC(zscan, "rt"),
	PROC(zrscan, "rt"),
	PROC(zkeys, "rt"),
	PROC(zlist, "rt"),
	PROC(zrlist, "rt"),
	PROC(zcount, "rt"),
	PROC(zsum, "rt"),
	PROC(zavg, "rt"),
	PROC(zremrangebyrank, "wt"),
	PROC(zremrangebyscore, "wt"),
	PROC(zexists, "r"),
	PROC(multi_zexists, "r"),
	PROC(multi_zsize, "r"),
	PROC(multi_zget, "rt"),
	PROC(multi_zset, "wt"),
	PROC(multi_zdel, "wt"),

	PROC(qsize, "r"),
	PROC(qfront, "r"),
	PROC(qback, "r"),
	PROC(qpush, "wt"),
	PROC(qpush_front, "wt"),
	PROC(qpush_back, "wt"),
	PROC(qpop, "wt"),
	PROC(qpop_front, "wt"),
	PROC(qpop_back, "wt"),
	PROC(qtrim_front, "wt"),
	PROC(qtrim_back, "wt"),
	PROC(qfix, "wt"),
	PROC(qclear, "wt"),
	PROC(qlist, "rt"),
	PROC(qrlist, "rt"),
	PROC(qslice, "rt"),
	PROC(qrange, "rt"),
	PROC(qget, "r"),
	PROC(qset, "wt"),

	PROC(clear_binlog, "wt"),

	PROC(dump, "b"),
	PROC(sync140, "b"),
	PROC(info, "r"),
	// doing compaction in a reader thread, because we have only one
	// writer thread(for performance reason), we don't want to block writes
	PROC(compact, "rt"),
	PROC(key_range, "r"),
	PROC(set_key_range, "w"),

	PROC(ttl, "r"),
	PROC(expire, "wt"),
	PROC(ping, "r"),
	PROC(auth, "r"),

	{NULL, NULL, 0, NULL}
};
#undef PROC

static proc_map_t proc_map;

ProcMap::ProcMap(){
	for(Command *cmd=commands; cmd->name; cmd++){
		for(const char *p=cmd->sflags; *p!='\0'; p++){
			switch(*p){
				case 'r':
					cmd->flags |= Command::FLAG_READ;
					break;
				case 'w':
					cmd->flags |= Command::FLAG_WRITE;
					break;
				case 'b':
					cmd->flags |= Command::FLAG_BACKEND;
					break;
				case 't':
					cmd->flags |= Command::FLAG_THREAD;
					break;
			}
		}
		proc_map[cmd->name] = cmd;
	}
	// for k-v data, list === keys
	proc_map["list"] = proc_map["keys"];
}

ProcMap::~ProcMap(){
}

Command* ProcMap::find(const Bytes &str){
	proc_map_t::iterator it = proc_map.find(str);
	if(it != proc_map.end()){
		return it->second;
	}
	return NULL;
}

int proc_info(Server *serv, Link *link, const Request &req, Response *resp){
	resp->push_back("ok");
	resp->push_back("ssdb-server");
	resp->push_back("version");
	resp->push_back(SSDB_VERSION);
	{
		resp->push_back("links");
		resp->add(serv->link_count);
	}
	{
		int64_t calls = 0;
		for(Command *cmd=commands; cmd->name; cmd++){
			calls += cmd->calls;
		}
		resp->push_back("total_calls");
		resp->add(calls);
	}

	if(req.size() > 1 && req[1] == "cmd"){
		for(Command *cmd=commands; cmd->name; cmd++){
			char buf[128];
			snprintf(buf, sizeof(buf), "cmd.%s", cmd->name);
			resp->push_back(buf);
			snprintf(buf, sizeof(buf), "calls: %" PRIu64 "\ttime_wait: %.0f\ttime_proc: %.0f",
				cmd->calls, cmd->time_wait, cmd->time_proc);
			resp->push_back(buf);
		}
	}

	if(req.size() == 1 || req[1] == "range"){
		std::vector<std::string> tmp;
		int ret = serv->ssdb->key_range(&tmp);
		if(ret == 0){
			char buf[512];

			resp->push_back("key_range.kv");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[0].data(), tmp[0].size()).c_str(),
				hexmem(tmp[1].data(), tmp[1].size()).c_str()
				);
			resp->push_back(buf);

			resp->push_back("key_range.hash");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[2].data(), tmp[2].size()).c_str(),
				hexmem(tmp[3].data(), tmp[3].size()).c_str()
				);
			resp->push_back(buf);

			resp->push_back("key_range.zset");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[4].data(), tmp[4].size()).c_str(),
				hexmem(tmp[5].data(), tmp[5].size()).c_str()
				);
			resp->push_back(buf);

			resp->push_back("key_range.list");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[6].data(), tmp[6].size()).c_str(),
				hexmem(tmp[7].data(), tmp[7].size()).c_str()
				);
			resp->push_back(buf);
		}
	}

	if(req.size() == 1 || req[1] == "leveldb"){
		std::vector<std::string> tmp = serv->ssdb->info();
		for(int i=0; i<(int)tmp.size(); i++){
			std::string block = tmp[i];
			resp->push_back(block);
		}
	}

	return 0;
}

<commit_msg>udpate<commit_after>#include "proc.h"
#include "serv.h"

struct BytesEqual{
	bool operator()(const Bytes &s1, const Bytes &s2) const {
		return (bool)(s1.compare(s2) == 0);
	}
};
struct BytesHash{
	size_t operator()(const Bytes &s1) const {
		unsigned long __h = 0;
		const char *p = s1.data();
		for (int i=0 ; i<s1.size(); i++)
			__h = 5*__h + p[i];
		return size_t(__h);
	}
};

#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#if GCC_VERSION >= 403
	#include <tr1/unordered_map>
	typedef std::tr1::unordered_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;
#else
	#ifdef NEW_MAC
		#include <unordered_map>
		typedef std::unordered_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;
	#else
		#include <ext/hash_map>
		typedef __gnu_cxx::hash_map<Bytes, Command *, BytesHash, BytesEqual> proc_map_t;
	#endif
#endif

#define DEF_PROC(f) int proc_##f(Server *serv, Link *link, const Request &req, Response *resp)
	DEF_PROC(get);
	DEF_PROC(set);
	DEF_PROC(setx);
	DEF_PROC(setnx);
	DEF_PROC(getset);
	DEF_PROC(getbit);
	DEF_PROC(setbit);
	DEF_PROC(countbit);
	DEF_PROC(substr);
	DEF_PROC(getrange);
	DEF_PROC(strlen);
	DEF_PROC(redis_bitcount);
	DEF_PROC(del);
	DEF_PROC(incr);
	DEF_PROC(decr);
	DEF_PROC(scan);
	DEF_PROC(rscan);
	DEF_PROC(keys);
	DEF_PROC(exists);
	DEF_PROC(multi_exists);
	DEF_PROC(multi_get);
	DEF_PROC(multi_set);
	DEF_PROC(multi_del);

	DEF_PROC(hsize);
	DEF_PROC(hget);
	DEF_PROC(hset);
	DEF_PROC(hdel);
	DEF_PROC(hincr);
	DEF_PROC(hdecr);
	DEF_PROC(hclear);
	DEF_PROC(hgetall);
	DEF_PROC(hscan);
	DEF_PROC(hrscan);
	DEF_PROC(hkeys);
	DEF_PROC(hvals);
	DEF_PROC(hlist);
	DEF_PROC(hrlist);
	DEF_PROC(hexists);
	DEF_PROC(multi_hexists);
	DEF_PROC(multi_hsize);
	DEF_PROC(multi_hget);
	DEF_PROC(multi_hset);
	DEF_PROC(multi_hdel);

	DEF_PROC(zrank);
	DEF_PROC(zrrank);
	DEF_PROC(zrange);
	DEF_PROC(zrrange);
	DEF_PROC(zsize);
	DEF_PROC(zget);
	DEF_PROC(zset);
	DEF_PROC(zdel);
	DEF_PROC(zincr);
	DEF_PROC(zdecr);
	DEF_PROC(zclear);
	DEF_PROC(zscan);
	DEF_PROC(zrscan);
	DEF_PROC(zkeys);
	DEF_PROC(zlist);
	DEF_PROC(zrlist);
	DEF_PROC(zcount);
	DEF_PROC(zsum);
	DEF_PROC(zavg);
	DEF_PROC(zexists);
	DEF_PROC(zremrangebyrank);
	DEF_PROC(zremrangebyscore);
	DEF_PROC(multi_zexists);
	DEF_PROC(multi_zsize);
	DEF_PROC(multi_zget);
	DEF_PROC(multi_zset);
	DEF_PROC(multi_zdel);

	DEF_PROC(qsize);
	DEF_PROC(qfront);
	DEF_PROC(qback);
	DEF_PROC(qpush);
	DEF_PROC(qpush_front);
	DEF_PROC(qpush_back);
	DEF_PROC(qpop);
	DEF_PROC(qpop_front);
	DEF_PROC(qpop_back);
	DEF_PROC(qtrim_front);
	DEF_PROC(qtrim_back);
	DEF_PROC(qfix);
	DEF_PROC(qclear);
	DEF_PROC(qlist);
	DEF_PROC(qrlist);
	DEF_PROC(qslice);
	DEF_PROC(qrange);
	DEF_PROC(qget);
	DEF_PROC(qset);

	DEF_PROC(dump);
	DEF_PROC(sync140);
	DEF_PROC(info);
	DEF_PROC(compact);
	DEF_PROC(key_range);
	DEF_PROC(set_key_range);
	DEF_PROC(ttl);
	DEF_PROC(expire);
	DEF_PROC(clear_binlog);
	DEF_PROC(ping);
	DEF_PROC(auth);
#undef DEF_PROC

#define PROC(c, f)     {#c, f, 0, proc_##c, 0, 0, 0, 0}
#define PROC_KP1(c, f) {#c, f, 0, proc_##c, 0, 0, 0, 1}

static Command commands[] = {
	PROC_KP1(get, "r"),
	PROC_KP1(set, "wt"),
	PROC(setx, "wt"),
	PROC(setnx, "wt"),
	PROC(getset, "wt"),
	PROC(getbit, "r"),
	PROC(setbit, "wt"),
	PROC(countbit, "r"),
	PROC(substr, "r"),
	PROC(getrange, "r"),
	PROC(strlen, "r"),
	PROC(redis_bitcount, "r"),
	PROC(del, "wt"),
	PROC(incr, "wt"),
	PROC(decr, "wt"),
	PROC(scan, "rt"),
	PROC(rscan, "rt"),
	PROC(keys, "rt"),
	PROC(exists, "r"),
	PROC(multi_exists, "r"),
	PROC(multi_get, "rt"),
	PROC(multi_set, "wt"),
	PROC(multi_del, "wt"),

	PROC(hsize, "r"),
	PROC(hget, "r"),
	PROC(hset, "wt"),
	PROC(hdel, "wt"),
	PROC(hincr, "wt"),
	PROC(hdecr, "wt"),
	PROC(hclear, "wt"),
	PROC(hgetall, "rt"),
	PROC(hscan, "rt"),
	PROC(hrscan, "rt"),
	PROC(hkeys, "rt"),
	PROC(hvals, "rt"),
	PROC(hlist, "rt"),
	PROC(hrlist, "rt"),
	PROC(hexists, "r"),
	PROC(multi_hexists, "r"),
	PROC(multi_hsize, "r"),
	PROC(multi_hget, "rt"),
	PROC(multi_hset, "wt"),
	PROC(multi_hdel, "wt"),

	// because zrank may be extremly slow, execute in a seperate thread
	PROC(zrank, "rt"),
	PROC(zrrank, "rt"),
	PROC(zrange, "rt"),
	PROC(zrrange, "rt"),
	PROC(zsize, "r"),
	PROC(zget, "rt"),
	PROC(zset, "wt"),
	PROC(zdel, "wt"),
	PROC(zincr, "wt"),
	PROC(zdecr, "wt"),
	PROC(zclear, "wt"),
	PROC(zscan, "rt"),
	PROC(zrscan, "rt"),
	PROC(zkeys, "rt"),
	PROC(zlist, "rt"),
	PROC(zrlist, "rt"),
	PROC(zcount, "rt"),
	PROC(zsum, "rt"),
	PROC(zavg, "rt"),
	PROC(zremrangebyrank, "wt"),
	PROC(zremrangebyscore, "wt"),
	PROC(zexists, "r"),
	PROC(multi_zexists, "r"),
	PROC(multi_zsize, "r"),
	PROC(multi_zget, "rt"),
	PROC(multi_zset, "wt"),
	PROC(multi_zdel, "wt"),

	PROC(qsize, "r"),
	PROC(qfront, "r"),
	PROC(qback, "r"),
	PROC(qpush, "wt"),
	PROC(qpush_front, "wt"),
	PROC(qpush_back, "wt"),
	PROC(qpop, "wt"),
	PROC(qpop_front, "wt"),
	PROC(qpop_back, "wt"),
	PROC(qtrim_front, "wt"),
	PROC(qtrim_back, "wt"),
	PROC(qfix, "wt"),
	PROC(qclear, "wt"),
	PROC(qlist, "rt"),
	PROC(qrlist, "rt"),
	PROC(qslice, "rt"),
	PROC(qrange, "rt"),
	PROC(qget, "r"),
	PROC(qset, "wt"),

	PROC(clear_binlog, "wt"),

	PROC(dump, "b"),
	PROC(sync140, "b"),
	PROC(info, "r"),
	// doing compaction in a reader thread, because we have only one
	// writer thread(for performance reason), we don't want to block writes
	PROC(compact, "rt"),
	PROC(key_range, "r"),
	// set_key_range must run in the main thread
	PROC(set_key_range, "r"),

	PROC(ttl, "r"),
	PROC(expire, "wt"),
	PROC(ping, "r"),
	PROC(auth, "r"),

	{NULL, NULL, 0, NULL}
};
#undef PROC

static proc_map_t proc_map;

ProcMap::ProcMap(){
	for(Command *cmd=commands; cmd->name; cmd++){
		for(const char *p=cmd->sflags; *p!='\0'; p++){
			switch(*p){
				case 'r':
					cmd->flags |= Command::FLAG_READ;
					break;
				case 'w':
					cmd->flags |= Command::FLAG_WRITE;
					break;
				case 'b':
					cmd->flags |= Command::FLAG_BACKEND;
					break;
				case 't':
					cmd->flags |= Command::FLAG_THREAD;
					break;
			}
		}
		proc_map[cmd->name] = cmd;
	}
	// for k-v data, list === keys
	proc_map["list"] = proc_map["keys"];
}

ProcMap::~ProcMap(){
}

Command* ProcMap::find(const Bytes &str){
	proc_map_t::iterator it = proc_map.find(str);
	if(it != proc_map.end()){
		return it->second;
	}
	return NULL;
}

int proc_info(Server *serv, Link *link, const Request &req, Response *resp){
	resp->push_back("ok");
	resp->push_back("ssdb-server");
	resp->push_back("version");
	resp->push_back(SSDB_VERSION);
	{
		resp->push_back("links");
		resp->add(serv->link_count);
	}
	{
		int64_t calls = 0;
		for(Command *cmd=commands; cmd->name; cmd++){
			calls += cmd->calls;
		}
		resp->push_back("total_calls");
		resp->add(calls);
	}

	if(req.size() > 1 && req[1] == "cmd"){
		for(Command *cmd=commands; cmd->name; cmd++){
			char buf[128];
			snprintf(buf, sizeof(buf), "cmd.%s", cmd->name);
			resp->push_back(buf);
			snprintf(buf, sizeof(buf), "calls: %" PRIu64 "\ttime_wait: %.0f\ttime_proc: %.0f",
				cmd->calls, cmd->time_wait, cmd->time_proc);
			resp->push_back(buf);
		}
	}

	if(req.size() == 1 || req[1] == "range"){
		std::vector<std::string> tmp;
		int ret = serv->ssdb->key_range(&tmp);
		if(ret == 0){
			char buf[512];

			resp->push_back("key_range.kv");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[0].data(), tmp[0].size()).c_str(),
				hexmem(tmp[1].data(), tmp[1].size()).c_str()
				);
			resp->push_back(buf);

			resp->push_back("key_range.hash");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[2].data(), tmp[2].size()).c_str(),
				hexmem(tmp[3].data(), tmp[3].size()).c_str()
				);
			resp->push_back(buf);

			resp->push_back("key_range.zset");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[4].data(), tmp[4].size()).c_str(),
				hexmem(tmp[5].data(), tmp[5].size()).c_str()
				);
			resp->push_back(buf);

			resp->push_back("key_range.list");
			snprintf(buf, sizeof(buf), "\"%s\" - \"%s\"",
				hexmem(tmp[6].data(), tmp[6].size()).c_str(),
				hexmem(tmp[7].data(), tmp[7].size()).c_str()
				);
			resp->push_back(buf);
		}
	}

	if(req.size() == 1 || req[1] == "leveldb"){
		std::vector<std::string> tmp = serv->ssdb->info();
		for(int i=0; i<(int)tmp.size(); i++){
			std::string block = tmp[i];
			resp->push_back(block);
		}
	}

	return 0;
}

<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2005-2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Trolltech ASA
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.

*/
#include "audiooutput.h"
#include "audiooutput_p.h"
#include "factory_p.h"
#include "objectdescription.h"
#include "audiooutputadaptor_p.h"
#include "globalconfig_p.h"
#include "audiooutputinterface.h"
#include "phononnamespace_p.h"
#include "platform_p.h"

#include <qmath.h>

#define PHONON_CLASSNAME AudioOutput
#define IFACES2 AudioOutputInterface42
#define IFACES1 IFACES2
#define IFACES0 AudioOutputInterface40, IFACES1
#define PHONON_INTERFACENAME IFACES0

QT_BEGIN_NAMESPACE

namespace Phonon
{

static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(AudioOutputDevice::fromIndex(index));
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(index);
}

static inline bool callSetOutputDevice(MediaNodePrivate *const d, const AudioOutputDevice &dev)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(dev);
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(dev.index());
}

AudioOutput::AudioOutput(Phonon::Category category, QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(category);
}

AudioOutput::AudioOutput(QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(NoCategory);
}

void AudioOutputPrivate::init(Phonon::Category c)
{
    Q_Q(AudioOutput);
    category = c;

    // select hardware device according to the category
    device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices));

    createBackendObject();
#ifndef QT_NO_DBUS
    adaptor = new AudioOutputAdaptor(q);
    static unsigned int number = 0;
    const QString &path = QLatin1String("/AudioOutputs/") + QString::number(number++);
    QDBusConnection con = QDBusConnection::sessionBus();
    con.registerObject(path, q);
    emit adaptor->newOutputAvailable(con.baseService(), path);
    q->connect(q, SIGNAL(volumeChanged(qreal)), adaptor, SIGNAL(volumeChanged(qreal)));
    q->connect(q, SIGNAL(mutedChanged(bool)), adaptor, SIGNAL(mutedChanged(bool)));
#endif

    q->connect(Factory::sender(), SIGNAL(availableAudioOutputDevicesChanged()), SLOT(_k_deviceListChanged()));
}

void AudioOutputPrivate::createBackendObject()
{
    if (m_backendObject)
        return;
    Q_Q(AudioOutput);
    m_backendObject = Factory::createAudioOutput(q);
    if (m_backendObject) {
        setupBackendObject();
    }
}

QString AudioOutput::name() const
{
    K_D(const AudioOutput);
    return d->name;
}

void AudioOutput::setName(const QString &newName)
{
    K_D(AudioOutput);
    if (d->name == newName) {
        return;
    }
    d->name = newName;
    setVolume(Platform::loadVolume(newName));
#ifndef QT_NO_DBUS
    emit d->adaptor->nameChanged(newName);
#endif
}

static const qreal LOUDNESS_TO_VOLTAGE_EXPONENT = qreal(0.67);
static const qreal VOLTAGE_TO_LOUDNESS_EXPONENT = qreal(1.0/LOUDNESS_TO_VOLTAGE_EXPONENT);

void AudioOutput::setVolume(qreal volume)
{
    K_D(AudioOutput);
    d->volume = volume;
    if (k_ptr->backendObject() && !d->muted) {
        // using Stevens' power law loudness is proportional to (sound pressure)^0.67
        // sound pressure is proportional to voltage:
        // p² \prop P \prop V²
        // => if a factor for loudness of x is requested
        INTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
    } else {
        emit volumeChanged(volume);
    }
    Platform::saveVolume(d->name, volume);
}

qreal AudioOutput::volume() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return d->volume;
    }
    return pow(INTERFACE_CALL(volume()), LOUDNESS_TO_VOLTAGE_EXPONENT);
}

#ifndef PHONON_LOG10OVER20
#define PHONON_LOG10OVER20
static const qreal log10over20 = qreal(0.1151292546497022842); // ln(10) / 20
#endif // PHONON_LOG10OVER20

qreal AudioOutput::volumeDecibel() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return log(d->volume) / log10over20;
    }
    return 0.67 * log(INTERFACE_CALL(volume())) / log10over20;
}

void AudioOutput::setVolumeDecibel(qreal newVolumeDecibel)
{
    setVolume(exp(newVolumeDecibel * log10over20));
}

bool AudioOutput::isMuted() const
{
    K_D(const AudioOutput);
    return d->muted;
}

void AudioOutput::setMuted(bool mute)
{
    K_D(AudioOutput);
    if (d->muted != mute) {
        if (mute) {
            d->muted = mute;
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(0.0));
            }
        } else {
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(pow(d->volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
            }
            d->muted = mute;
        }
        emit mutedChanged(mute);
    }
}

Category AudioOutput::category() const
{
    K_D(const AudioOutput);
    return d->category;
}

AudioOutputDevice AudioOutput::outputDevice() const
{
    K_D(const AudioOutput);
    return d->device;
}

bool AudioOutput::setOutputDevice(const AudioOutputDevice &newAudioOutputDevice)
{
    K_D(AudioOutput);
    if (!newAudioOutputDevice.isValid()) {
        d->outputDeviceOverridden = false;
        const int newIndex = GlobalConfig().audioOutputDeviceFor(d->category);
        if (newIndex == d->device.index()) {
            return true;
        }
        d->device = AudioOutputDevice::fromIndex(newIndex);
    } else {
        d->outputDeviceOverridden = true;
        if (d->device == newAudioOutputDevice) {
            return true;
        }
        d->device = newAudioOutputDevice;
    }
    if (k_ptr->backendObject()) {
        return callSetOutputDevice(k_ptr, d->device.index());
    }
    return true;
}

bool AudioOutputPrivate::aboutToDeleteBackendObject()
{
    if (m_backendObject) {
        volume = pINTERFACE_CALL(volume());
    }
    return AbstractAudioOutputPrivate::aboutToDeleteBackendObject();
}

void AudioOutputPrivate::setupBackendObject()
{
    Q_Q(AudioOutput);
    Q_ASSERT(m_backendObject);
    AbstractAudioOutputPrivate::setupBackendObject();

    QObject::connect(m_backendObject, SIGNAL(volumeChanged(qreal)), q, SLOT(_k_volumeChanged(qreal)));
    QObject::connect(m_backendObject, SIGNAL(audioDeviceFailed()), q, SLOT(_k_audioDeviceFailed()));

    // set up attributes
    pINTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));

    // if the output device is not available and the device was not explicitly set
    if (!callSetOutputDevice(this, device) && !outputDeviceOverridden) {
        // fall back in the preference list of output devices
        QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
        if (deviceList.isEmpty()) {
            return;
        }
        foreach (int devIndex, deviceList) {
            const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(devIndex);
            if (callSetOutputDevice(this, dev)) {
                handleAutomaticDeviceChange(dev, AudioOutputPrivate::FallbackChange);
                return; // found one that works
            }
        }
        // if we get here there is no working output device. Tell the backend.
        const AudioOutputDevice none;
        callSetOutputDevice(this, none);
        handleAutomaticDeviceChange(none, FallbackChange);
    }
}

void AudioOutputPrivate::_k_volumeChanged(qreal newVolume)
{
    if (!muted) {
        Q_Q(AudioOutput);
        emit q->volumeChanged(pow(newVolume, qreal(0.67)));
    }
}

void AudioOutputPrivate::_k_revertFallback()
{
    if (deviceBeforeFallback == -1) {
        return;
    }
    device = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    callSetOutputDevice(this, device);
    Q_Q(AudioOutput);
    emit q->outputDeviceChanged(device);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
}

void AudioOutputPrivate::_k_audioDeviceFailed()
{
    pDebug() << Q_FUNC_INFO;
    // outputDeviceIndex identifies a failing device
    // fall back in the preference list of output devices
    QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
    foreach (int devIndex, deviceList) {
        // if it's the same device as the one that failed, ignore it
        if (device.index() != devIndex) {
            const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
            if (callSetOutputDevice(this, info)) {
                handleAutomaticDeviceChange(info, FallbackChange);
                return; // found one that works
            }
        }
    }
    // if we get here there is no working output device. Tell the backend.
    const AudioOutputDevice none;
    callSetOutputDevice(this, none);
    handleAutomaticDeviceChange(none, FallbackChange);
}

void AudioOutputPrivate::_k_deviceListChanged()
{
    pDebug() << Q_FUNC_INFO;
    // let's see if there's a usable device higher in the preference list
    QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings);
    DeviceChangeType changeType = HigherPreferenceChange;
    foreach (int devIndex, deviceList) {
        const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
        if (!info.property("available").toBool()) {
            if (device.index() == devIndex) {
                // we've reached the currently used device and it's not available anymore, so we
                // fallback to the next available device
                changeType = FallbackChange;
            }
            pDebug() << devIndex << "is not available";
            continue;
        }
        pDebug() << devIndex << "is available";
        if (device.index() == devIndex) {
            // we've reached the currently used device, nothing to change
            break;
        }
        if (callSetOutputDevice(this, info)) {
            handleAutomaticDeviceChange(info, changeType);
            break; // found one with higher preference that works
        }
    }
}

static struct
{
    int first;
    int second;
} g_lastFallback = { 0, 0 };

void AudioOutputPrivate::handleAutomaticDeviceChange(const AudioOutputDevice &device2, DeviceChangeType type)
{
    Q_Q(AudioOutput);
    deviceBeforeFallback = device.index();
    device = device2;
    emit q->outputDeviceChanged(device2);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
    const AudioOutputDevice &device1 = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    switch (type) {
    case FallbackChange:
        if (g_lastFallback.first != device1.index() || g_lastFallback.second != device2.index()) {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
            const QString &text = //device2.isValid() ?
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "Falling back to %2.").arg(device1.name()).arg(device2.name()) /*:
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "No other device available.").arg(device1.name())*/;
            Platform::notification("AudioDeviceFallback", text);
#endif //QT_NO_PHONON_PLATFORMPLUGIN
            g_lastFallback.first = device1.index();
            g_lastFallback.second = device2.index();
        }
        break;
    case HigherPreferenceChange:
        {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
        const QString text = AudioOutput::tr("Switching to the audio playback device %1
"
                "which just became available and has higher preference.").arg(device2.name());
        Platform::notification("AudioDeviceFallback", text,
                QStringList(AudioOutput::tr("Revert back to device '%1'").arg(device1.name())),
                q, SLOT(_k_revertFallback()));
#endif //QT_NO_PHONON_PLATFORMPLUGIN
        g_lastFallback.first = 0;
        g_lastFallback.second = 0;
        }
        break;
    }
}

AudioOutputPrivate::~AudioOutputPrivate()
{
#ifndef QT_NO_DBUS
    emit adaptor->outputDestroyed();
#endif
}

} //namespace Phonon

QT_END_NAMESPACE

#include "moc_audiooutput.cpp"

#undef PHONON_CLASSNAME
#undef PHONON_INTERFACENAME
#undef IFACES2
#undef IFACES1
#undef IFACES0
<commit_msg>Fixes:    Crash in Amarok<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2005-2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Trolltech ASA
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.

*/
#include "audiooutput.h"
#include "audiooutput_p.h"
#include "factory_p.h"
#include "objectdescription.h"
#include "audiooutputadaptor_p.h"
#include "globalconfig_p.h"
#include "audiooutputinterface.h"
#include "phononnamespace_p.h"
#include "platform_p.h"

#include <qmath.h>

#define PHONON_CLASSNAME AudioOutput
#define IFACES2 AudioOutputInterface42
#define IFACES1 IFACES2
#define IFACES0 AudioOutputInterface40, IFACES1
#define PHONON_INTERFACENAME IFACES0

QT_BEGIN_NAMESPACE

namespace Phonon
{

static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(AudioOutputDevice::fromIndex(index));
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(index);
}

static inline bool callSetOutputDevice(MediaNodePrivate *const d, const AudioOutputDevice &dev)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(dev);
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(dev.index());
}

AudioOutput::AudioOutput(Phonon::Category category, QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(category);
}

AudioOutput::AudioOutput(QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(NoCategory);
}

void AudioOutputPrivate::init(Phonon::Category c)
{
    Q_Q(AudioOutput);
#ifndef QT_NO_DBUS
    adaptor = new AudioOutputAdaptor(q);
    static unsigned int number = 0;
    const QString &path = QLatin1String("/AudioOutputs/") + QString::number(number++);
    QDBusConnection con = QDBusConnection::sessionBus();
    con.registerObject(path, q);
    emit adaptor->newOutputAvailable(con.baseService(), path);
    q->connect(q, SIGNAL(volumeChanged(qreal)), adaptor, SIGNAL(volumeChanged(qreal)));
    q->connect(q, SIGNAL(mutedChanged(bool)), adaptor, SIGNAL(mutedChanged(bool)));
#endif

    category = c;

    // select hardware device according to the category
    device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices));

    createBackendObject();

    q->connect(Factory::sender(), SIGNAL(availableAudioOutputDevicesChanged()), SLOT(_k_deviceListChanged()));
}

void AudioOutputPrivate::createBackendObject()
{
    if (m_backendObject)
        return;
    Q_Q(AudioOutput);
    m_backendObject = Factory::createAudioOutput(q);
    if (m_backendObject) {
        setupBackendObject();
    }
}

QString AudioOutput::name() const
{
    K_D(const AudioOutput);
    return d->name;
}

void AudioOutput::setName(const QString &newName)
{
    K_D(AudioOutput);
    if (d->name == newName) {
        return;
    }
    d->name = newName;
    setVolume(Platform::loadVolume(newName));
#ifndef QT_NO_DBUS
    emit d->adaptor->nameChanged(newName);
#endif
}

static const qreal LOUDNESS_TO_VOLTAGE_EXPONENT = qreal(0.67);
static const qreal VOLTAGE_TO_LOUDNESS_EXPONENT = qreal(1.0/LOUDNESS_TO_VOLTAGE_EXPONENT);

void AudioOutput::setVolume(qreal volume)
{
    K_D(AudioOutput);
    d->volume = volume;
    if (k_ptr->backendObject() && !d->muted) {
        // using Stevens' power law loudness is proportional to (sound pressure)^0.67
        // sound pressure is proportional to voltage:
        // p² \prop P \prop V²
        // => if a factor for loudness of x is requested
        INTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
    } else {
        emit volumeChanged(volume);
    }
    Platform::saveVolume(d->name, volume);
}

qreal AudioOutput::volume() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return d->volume;
    }
    return pow(INTERFACE_CALL(volume()), LOUDNESS_TO_VOLTAGE_EXPONENT);
}

#ifndef PHONON_LOG10OVER20
#define PHONON_LOG10OVER20
static const qreal log10over20 = qreal(0.1151292546497022842); // ln(10) / 20
#endif // PHONON_LOG10OVER20

qreal AudioOutput::volumeDecibel() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return log(d->volume) / log10over20;
    }
    return 0.67 * log(INTERFACE_CALL(volume())) / log10over20;
}

void AudioOutput::setVolumeDecibel(qreal newVolumeDecibel)
{
    setVolume(exp(newVolumeDecibel * log10over20));
}

bool AudioOutput::isMuted() const
{
    K_D(const AudioOutput);
    return d->muted;
}

void AudioOutput::setMuted(bool mute)
{
    K_D(AudioOutput);
    if (d->muted != mute) {
        if (mute) {
            d->muted = mute;
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(0.0));
            }
        } else {
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(pow(d->volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
            }
            d->muted = mute;
        }
        emit mutedChanged(mute);
    }
}

Category AudioOutput::category() const
{
    K_D(const AudioOutput);
    return d->category;
}

AudioOutputDevice AudioOutput::outputDevice() const
{
    K_D(const AudioOutput);
    return d->device;
}

bool AudioOutput::setOutputDevice(const AudioOutputDevice &newAudioOutputDevice)
{
    K_D(AudioOutput);
    if (!newAudioOutputDevice.isValid()) {
        d->outputDeviceOverridden = false;
        const int newIndex = GlobalConfig().audioOutputDeviceFor(d->category);
        if (newIndex == d->device.index()) {
            return true;
        }
        d->device = AudioOutputDevice::fromIndex(newIndex);
    } else {
        d->outputDeviceOverridden = true;
        if (d->device == newAudioOutputDevice) {
            return true;
        }
        d->device = newAudioOutputDevice;
    }
    if (k_ptr->backendObject()) {
        return callSetOutputDevice(k_ptr, d->device.index());
    }
    return true;
}

bool AudioOutputPrivate::aboutToDeleteBackendObject()
{
    if (m_backendObject) {
        volume = pINTERFACE_CALL(volume());
    }
    return AbstractAudioOutputPrivate::aboutToDeleteBackendObject();
}

void AudioOutputPrivate::setupBackendObject()
{
    Q_Q(AudioOutput);
    Q_ASSERT(m_backendObject);
    AbstractAudioOutputPrivate::setupBackendObject();

    QObject::connect(m_backendObject, SIGNAL(volumeChanged(qreal)), q, SLOT(_k_volumeChanged(qreal)));
    QObject::connect(m_backendObject, SIGNAL(audioDeviceFailed()), q, SLOT(_k_audioDeviceFailed()));

    // set up attributes
    pINTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));

    // if the output device is not available and the device was not explicitly set
    if (!callSetOutputDevice(this, device) && !outputDeviceOverridden) {
        // fall back in the preference list of output devices
        QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
        if (deviceList.isEmpty()) {
            return;
        }
        foreach (int devIndex, deviceList) {
            const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(devIndex);
            if (callSetOutputDevice(this, dev)) {
                handleAutomaticDeviceChange(dev, AudioOutputPrivate::FallbackChange);
                return; // found one that works
            }
        }
        // if we get here there is no working output device. Tell the backend.
        const AudioOutputDevice none;
        callSetOutputDevice(this, none);
        handleAutomaticDeviceChange(none, FallbackChange);
    }
}

void AudioOutputPrivate::_k_volumeChanged(qreal newVolume)
{
    if (!muted) {
        Q_Q(AudioOutput);
        emit q->volumeChanged(pow(newVolume, qreal(0.67)));
    }
}

void AudioOutputPrivate::_k_revertFallback()
{
    if (deviceBeforeFallback == -1) {
        return;
    }
    device = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    callSetOutputDevice(this, device);
    Q_Q(AudioOutput);
    emit q->outputDeviceChanged(device);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
}

void AudioOutputPrivate::_k_audioDeviceFailed()
{
    pDebug() << Q_FUNC_INFO;
    // outputDeviceIndex identifies a failing device
    // fall back in the preference list of output devices
    QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
    foreach (int devIndex, deviceList) {
        // if it's the same device as the one that failed, ignore it
        if (device.index() != devIndex) {
            const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
            if (callSetOutputDevice(this, info)) {
                handleAutomaticDeviceChange(info, FallbackChange);
                return; // found one that works
            }
        }
    }
    // if we get here there is no working output device. Tell the backend.
    const AudioOutputDevice none;
    callSetOutputDevice(this, none);
    handleAutomaticDeviceChange(none, FallbackChange);
}

void AudioOutputPrivate::_k_deviceListChanged()
{
    pDebug() << Q_FUNC_INFO;
    // let's see if there's a usable device higher in the preference list
    QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings);
    DeviceChangeType changeType = HigherPreferenceChange;
    foreach (int devIndex, deviceList) {
        const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
        if (!info.property("available").toBool()) {
            if (device.index() == devIndex) {
                // we've reached the currently used device and it's not available anymore, so we
                // fallback to the next available device
                changeType = FallbackChange;
            }
            pDebug() << devIndex << "is not available";
            continue;
        }
        pDebug() << devIndex << "is available";
        if (device.index() == devIndex) {
            // we've reached the currently used device, nothing to change
            break;
        }
        if (callSetOutputDevice(this, info)) {
            handleAutomaticDeviceChange(info, changeType);
            break; // found one with higher preference that works
        }
    }
}

static struct
{
    int first;
    int second;
} g_lastFallback = { 0, 0 };

void AudioOutputPrivate::handleAutomaticDeviceChange(const AudioOutputDevice &device2, DeviceChangeType type)
{
    Q_Q(AudioOutput);
    deviceBeforeFallback = device.index();
    device = device2;
    emit q->outputDeviceChanged(device2);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
    const AudioOutputDevice &device1 = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    switch (type) {
    case FallbackChange:
        if (g_lastFallback.first != device1.index() || g_lastFallback.second != device2.index()) {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
            const QString &text = //device2.isValid() ?
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "Falling back to %2.").arg(device1.name()).arg(device2.name()) /*:
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "No other device available.").arg(device1.name())*/;
            Platform::notification("AudioDeviceFallback", text);
#endif //QT_NO_PHONON_PLATFORMPLUGIN
            g_lastFallback.first = device1.index();
            g_lastFallback.second = device2.index();
        }
        break;
    case HigherPreferenceChange:
        {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
        const QString text = AudioOutput::tr("Switching to the audio playback device %1
"
                "which just became available and has higher preference.").arg(device2.name());
        Platform::notification("AudioDeviceFallback", text,
                QStringList(AudioOutput::tr("Revert back to device '%1'").arg(device1.name())),
                q, SLOT(_k_revertFallback()));
#endif //QT_NO_PHONON_PLATFORMPLUGIN
        g_lastFallback.first = 0;
        g_lastFallback.second = 0;
        }
        break;
    }
}

AudioOutputPrivate::~AudioOutputPrivate()
{
#ifndef QT_NO_DBUS
    emit adaptor->outputDestroyed();
#endif
}

} //namespace Phonon

QT_END_NAMESPACE

#include "moc_audiooutput.cpp"

#undef PHONON_CLASSNAME
#undef PHONON_INTERFACENAME
#undef IFACES2
#undef IFACES1
#undef IFACES0
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: deferredview.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 04:28:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef CONFIGMGR_DEFERREDVIEW_HXX_
#define CONFIGMGR_DEFERREDVIEW_HXX_

#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_
#include "viewstrategy.hxx"
#endif

namespace configmgr
{
    namespace view
    {
//-----------------------------------------------------------------------------
// View behavior for direct data access
//-----------------------------------------------------------------------------

        class DeferredViewStrategy : public ViewStrategy
        {
            memory::Segment const * m_pSegment;
        public:
            explicit
            DeferredViewStrategy(memory::Segment const * _pSegment)
            : m_pSegment(_pSegment)
            {}

        // ViewStrategy implementation
        private:
            // change handling -required
            virtual bool doHasChanges(Node const& _aNode) const;
            virtual void doMarkChanged(Node const& _aNode);

            // change handling
            virtual void doCollectChanges(Node const& _aNode, configuration::NodeChanges& rChanges) const;

            // commit protocol
            virtual std::auto_ptr<SubtreeChange> doPreCommitChanges(Tree const& _aTree, configuration::ElementList& _rRemovedElements);
            virtual void doFailedCommit(Tree const& _aTree, SubtreeChange& rChanges);
            virtual void doFinishCommit(Tree const& _aTree, SubtreeChange& rChanges);
            virtual void doRevertCommit(Tree const& _aTree, SubtreeChange& rChanges);

            // notification protocol
            virtual configuration::ValueChangeImpl* doAdjustToValueChange(GroupNode const& _aGroupNode, Name const& aName, ValueChange const& rExternalChange);
        //  virtual void doAdjustToElementChanges(configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aNode, SubtreeChange const& rExternalChanges, TreeDepth nDepth);

            // common attributes
            virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const;

            // group member access
            virtual configuration::ValueMemberNode doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const;

            // set element access
            virtual void doInsertElement(SetNode const& _aNode, Name const& aName, configuration::SetEntry const& aNewEntry);
            virtual void doRemoveElement(SetNode const& _aNode, Name const& aName);

            virtual void doReleaseDataSegment() { m_pSegment = NULL; }
            virtual memory::Segment const * doGetDataSegment() const { return m_pSegment; }

            virtual NodeFactory& doGetNodeFactory();
        private:
            void implCollectChangesIn(Node const& _aNode, NodeChanges& rChanges) const;
            // commit protocol
            std::auto_ptr<SubtreeChange> implPreCommitChanges(Node const& _aNode, configuration::ElementList& _rRemovedElements);
            void implFailedCommit(Node const& _aNode, SubtreeChange& rChanges);
            void implFinishCommit(Node const& _aNode, SubtreeChange& rChanges);
            void implRevertCommit(Node const& _aNode, SubtreeChange& rChanges);

            void implPreCommitSubChanges(GroupNode const & _aGroup, configuration::ElementList& _rRemovedElements, SubtreeChange& _rParentChange);
            void implFailedSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);
            void implFinishSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);
            void implRevertSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);

        };
//-----------------------------------------------------------------------------
    }
}

#endif // CONFIGMGR_DEFERREDVIEW_HXX_
<commit_msg>INTEGRATION: CWS configrefactor01 (1.3.84); FILE MERGED 2007/01/16 12:18:25 mmeeks 1.3.84.1: Submitted by: mmeeks Kill 'memory::Segment' - no longer needed. Bin some other (empty / redundant) headers.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: deferredview.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-23 14:41:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef CONFIGMGR_DEFERREDVIEW_HXX_
#define CONFIGMGR_DEFERREDVIEW_HXX_

#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_
#include "viewstrategy.hxx"
#endif

namespace configmgr
{
    namespace view
    {
//-----------------------------------------------------------------------------
// View behavior for direct data access
//-----------------------------------------------------------------------------

        class DeferredViewStrategy : public ViewStrategy
        {
        public:
            explicit
            DeferredViewStrategy() {}

        // ViewStrategy implementation
        private:
            // change handling -required
            virtual bool doHasChanges(Node const& _aNode) const;
            virtual void doMarkChanged(Node const& _aNode);

            // change handling
            virtual void doCollectChanges(Node const& _aNode, configuration::NodeChanges& rChanges) const;

            // commit protocol
            virtual std::auto_ptr<SubtreeChange> doPreCommitChanges(Tree const& _aTree, configuration::ElementList& _rRemovedElements);
            virtual void doFailedCommit(Tree const& _aTree, SubtreeChange& rChanges);
            virtual void doFinishCommit(Tree const& _aTree, SubtreeChange& rChanges);
            virtual void doRevertCommit(Tree const& _aTree, SubtreeChange& rChanges);

            // notification protocol
            virtual configuration::ValueChangeImpl* doAdjustToValueChange(GroupNode const& _aGroupNode, Name const& aName, ValueChange const& rExternalChange);
        //  virtual void doAdjustToElementChanges(configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aNode, SubtreeChange const& rExternalChanges, TreeDepth nDepth);

            // common attributes
            virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const;

            // group member access
            virtual configuration::ValueMemberNode doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const;

            // set element access
            virtual void doInsertElement(SetNode const& _aNode, Name const& aName, configuration::SetEntry const& aNewEntry);
            virtual void doRemoveElement(SetNode const& _aNode, Name const& aName);

            virtual NodeFactory& doGetNodeFactory();
        private:
            void implCollectChangesIn(Node const& _aNode, NodeChanges& rChanges) const;
            // commit protocol
            std::auto_ptr<SubtreeChange> implPreCommitChanges(Node const& _aNode, configuration::ElementList& _rRemovedElements);
            void implFailedCommit(Node const& _aNode, SubtreeChange& rChanges);
            void implFinishCommit(Node const& _aNode, SubtreeChange& rChanges);
            void implRevertCommit(Node const& _aNode, SubtreeChange& rChanges);

            void implPreCommitSubChanges(GroupNode const & _aGroup, configuration::ElementList& _rRemovedElements, SubtreeChange& _rParentChange);
            void implFailedSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);
            void implFinishSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);
            void implRevertSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);

        };
//-----------------------------------------------------------------------------
    }
}

#endif // CONFIGMGR_DEFERREDVIEW_HXX_
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/defaults.h>
#include <iostream>
#include <lib/modelinspect.h>
#include <vespa/vespalib/text/stringtokenizer.h>
#include <vespa/fastos/app.h>

#include <vespa/log/log.h>
LOG_SETUP("vespa-model-inspect");

class Application : public FastOS_Application
{
    ModelInspect::Flags _flags;
    vespalib::string _cfgId;
    vespalib::string _specString;
    int parseOpts();
    vespalib::string getSources();
    config::ConfigUri getConfigUri();
public:
    void usage();
    int Main() override;

    Application();
    ~Application();
};

Application::Application() : _flags(), _cfgId("admin/model"), _specString("") {}
Application::~Application() { }

int
Application::parseOpts()
{
    char c = '?';
    const char *optArg = NULL;
    int optInd = 0;
    while ((c = GetOpt("hvut:c:C:", optArg, optInd)) != -1) {
        switch (c) {
        case 'v':
            _flags.verbose = true;
            break;
        case 'u':
            _flags.makeuri = true;
            break;
        case 't':
            _flags.tagFilter.push_back(optArg);
            _flags.tagfilt = true;
            break;
        case 'C':
            _cfgId = optArg;
            break;
        case 'c':
            _specString = optArg;
            break;
        case 'h':
            return _argc;
        default:
            usage();
            exit(1);
        }
    }
    if (_specString.empty()) {
        _specString = getSources();
    }
    return optInd;
}

vespalib::string
Application::getSources()
{
    vespalib::string specs;
    for (std::string v : vespa::Defaults::vespaConfigSourcesRpcAddrs()) {
        if (! specs.empty()) specs += ",";
        specs += v;
    }
    return specs;
}

config::ConfigUri
Application::getConfigUri()
{
    try {
        return config::ConfigUri::createFromSpec(_cfgId, config::ServerSpec(_specString));
    }
    catch (std::exception &e) {
        LOG(fatal, "Failed to set up model configuration source, will exit: %s", e.what());
        exit(1);
    }
}

void
Application::usage()
{
    std::cerr <<
        "vespa-model-inspect version 2.0"                                  << std::endl <<
        "Usage: " << _argv[0] << " [options] <command> <options>"          << std::endl <<
        "options: [-u] for URLs, [-v] for verbose"                         << std::endl <<
        "         [-c host] or [-c host:port] to specify server"           << std::endl <<
        "         [-t tag] to filter on a port tag"                        << std::endl <<
        "Where command is:"                                                << std::endl <<
        "    hosts - show all hosts"                                       << std::endl <<
        "    services - show all services"                                 << std::endl <<
        "    clusters - show all cluster names"                            << std::endl <<
        "    configids - show all config IDs"                              << std::endl <<
        "    filter:ports - list ports matching filter options"            << std::endl <<
        "    host <hostname> - show services on a given host"              << std::endl <<
        "    service [cluster:]<servicetype>"                                           <<
        " - show all instances of a given servicetype"                     << std::endl <<
        "    cluster <clustername>"                                                     <<
        " - show all services associated with the cluster"                 << std::endl <<
        "    configid <configid>"                                                       <<
        " - show service using configid"                                   << std::endl <<
        "    get-index-of <servicetype> <host>"                                         <<
        " - show all indexes for instances of the servicetype on the host" << std::endl <<
        std::endl;
}

int
Application::Main()
{
    int cnt = parseOpts();
    if (_argc == cnt) {
        usage();
        return 0;
    }

    config::ConfigUri uri = getConfigUri();
    ModelInspect model(_flags, uri, std::cout);
    return model.action(_argc - cnt, &_argv[cnt]);
}

int
main(int argc, char** argv)
{
    vespa::Defaults::bootstrap(argv[0]);
    Application app;
    return app.Entry(argc, argv);
}
<commit_msg>Revert "Use LOG instead of cerr"<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/defaults.h>
#include <iostream>
#include <lib/modelinspect.h>
#include <vespa/vespalib/text/stringtokenizer.h>
#include <vespa/fastos/app.h>

#include <vespa/log/log.h>
LOG_SETUP("vespa-model-inspect");

class Application : public FastOS_Application
{
    ModelInspect::Flags _flags;
    vespalib::string _cfgId;
    vespalib::string _specString;
    int parseOpts();
    vespalib::string getSources();
    config::ConfigUri getConfigUri();
public:
    void usage();
    int Main() override;

    Application();
    ~Application();
};

Application::Application() : _flags(), _cfgId("admin/model"), _specString("") {}
Application::~Application() { }

int
Application::parseOpts()
{
    char c = '?';
    const char *optArg = NULL;
    int optInd = 0;
    while ((c = GetOpt("hvut:c:C:", optArg, optInd)) != -1) {
        switch (c) {
        case 'v':
            _flags.verbose = true;
            break;
        case 'u':
            _flags.makeuri = true;
            break;
        case 't':
            _flags.tagFilter.push_back(optArg);
            _flags.tagfilt = true;
            break;
        case 'C':
            _cfgId = optArg;
            break;
        case 'c':
            _specString = optArg;
            break;
        case 'h':
            return _argc;
        default:
            usage();
            exit(1);
        }
    }
    if (_specString.empty()) {
        _specString = getSources();
    }
    return optInd;
}

vespalib::string
Application::getSources()
{
    vespalib::string specs;
    for (std::string v : vespa::Defaults::vespaConfigSourcesRpcAddrs()) {
        if (! specs.empty()) specs += ",";
        specs += v;
    }
    return specs;
}

config::ConfigUri
Application::getConfigUri()
{
    try {
        return config::ConfigUri::createFromSpec(_cfgId, config::ServerSpec(_specString));
    }
    catch (std::exception &e) {
        std::cerr << "FATAL ERROR: failed to set up model configuration: " << e.what() << "\n";
        exit(1);
    }
}

void
Application::usage()
{
    std::cerr <<
        "vespa-model-inspect version 2.0"                                  << std::endl <<
        "Usage: " << _argv[0] << " [options] <command> <options>"          << std::endl <<
        "options: [-u] for URLs, [-v] for verbose"                         << std::endl <<
        "         [-c host] or [-c host:port] to specify server"           << std::endl <<
        "         [-t tag] to filter on a port tag"                        << std::endl <<
        "Where command is:"                                                << std::endl <<
        "    hosts - show all hosts"                                       << std::endl <<
        "    services - show all services"                                 << std::endl <<
        "    clusters - show all cluster names"                            << std::endl <<
        "    configids - show all config IDs"                              << std::endl <<
        "    filter:ports - list ports matching filter options"            << std::endl <<
        "    host <hostname> - show services on a given host"              << std::endl <<
        "    service [cluster:]<servicetype>"                                           <<
        " - show all instances of a given servicetype"                     << std::endl <<
        "    cluster <clustername>"                                                     <<
        " - show all services associated with the cluster"                 << std::endl <<
        "    configid <configid>"                                                       <<
        " - show service using configid"                                   << std::endl <<
        "    get-index-of <servicetype> <host>"                                         <<
        " - show all indexes for instances of the servicetype on the host" << std::endl <<
        std::endl;
}

int
Application::Main()
{
    int cnt = parseOpts();
    if (_argc == cnt) {
        usage();
        return 0;
    }

    config::ConfigUri uri = getConfigUri();
    ModelInspect model(_flags, uri, std::cout);
    return model.action(_argc - cnt, &_argv[cnt]);
}

int
main(int argc, char** argv)
{
    vespa::Defaults::bootstrap(argv[0]);
    Application app;
    return app.Entry(argc, argv);
}
<|endoftext|>


<commit_before><commit_msg>wrong logic in comment<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Clob.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 01:33:35 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_JAVA_SQL_CLOB_HXX_
#include "java/sql/Clob.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_TOOLS_HXX_
#include "java/tools.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_IO_READER_HXX_
#include "java/io/Reader.hxx"
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include <connectivity/dbexception.hxx>
#endif
using namespace connectivity;
//**************************************************************
//************ Class: java.sql.Clob
//**************************************************************

jclass java_sql_Clob::theClass = 0;

java_sql_Clob::java_sql_Clob( JNIEnv * pEnv, jobject myObj )
    : java_lang_Object( pEnv, myObj )
{
    SDBThreadAttach::addRef();
}
java_sql_Clob::~java_sql_Clob()
{
    SDBThreadAttach::releaseRef();
}

jclass java_sql_Clob::getMyClass()
{
    // die Klasse muss nur einmal geholt werden, daher statisch
    if( !theClass ){
        SDBThreadAttach t;
        if( !t.pEnv ) return (jclass)NULL;
        jclass tempClass = t.pEnv->FindClass( "java/sql/Clob" );
        jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
        t.pEnv->DeleteLocalRef( tempClass );
        saveClassRef( globClass );
    }
    return theClass;
}

void java_sql_Clob::saveClassRef( jclass pClass )
{
    if( pClass==NULL  )
        return;
    // der uebergebe Klassen-Handle ist schon global, daher einfach speichern
    theClass = pClass;
}

sal_Int64 SAL_CALL java_sql_Clob::length(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    jlong out(0);
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    if( t.pEnv )
    {
        // temporaere Variable initialisieren
        static const char * cSignature = "()J";
        static const char * cMethodName = "length";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            out = t.pEnv->CallLongMethod( object, mID );
            ThrowSQLException(t.pEnv,*this);
            // und aufraeumen
        } //mID
    } //t.pEnv
    return (sal_Int64)out;
}

::rtl::OUString SAL_CALL java_sql_Clob::getSubString( sal_Int64 pos, sal_Int32 subStringLength ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    ::rtl::OUString aStr;
    if( t.pEnv ){
        // temporaere Variable initialisieren
        static const char * cSignature = "(JI)Ljava/lang/String;";
        static const char * cMethodName = "getSubString";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            jstring out = (jstring)t.pEnv->CallObjectMethod( object, mID,pos,subStringLength);
            ThrowSQLException(t.pEnv,*this);
            aStr = JavaString2String(t.pEnv,out);
            // und aufraeumen
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return  aStr;
}

::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL java_sql_Clob::getCharacterStream(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    jobject out(0);
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    if( t.pEnv ){
        // temporaere Variable initialisieren
        static const char * cSignature = "()Ljava/io/Reader;";
        static const char * cMethodName = "getCharacterStream";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            out = t.pEnv->CallObjectMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return out==0 ? 0 : new java_io_Reader( t.pEnv, out );
}

sal_Int64 SAL_CALL java_sql_Clob::position( const ::rtl::OUString& searchstr, sal_Int32 start ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    jlong out(0);
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    if( t.pEnv )
    {
        jvalue args[1];
        // Parameter konvertieren
        args[0].l = convertwchar_tToJavaString(t.pEnv,searchstr);
        // temporaere Variable initialisieren
        static const char * cSignature = "(Ljava/lang/String;I)J";
        static const char * cMethodName = "position";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            out = t.pEnv->CallLongMethod( object, mID, args[0].l,start );
            ThrowSQLException(t.pEnv,*this);
            t.pEnv->DeleteLocalRef((jstring)args[0].l);
            // und aufraeumen
        } //mID
    } //t.pEnv
    return (sal_Int64)out;
}

sal_Int64 SAL_CALL java_sql_Clob::positionOfClob( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob >& /*pattern*/, sal_Int64 /*start*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    ::dbtools::throwFeatureNotImplementedException( "XClob::positionOfClob", *this );
    // this was put here in CWS warnings01. The previous implementation was defective, as it did ignore
    // the pattern parameter. Since the effort for proper implementation is rather high - we would need
    // to translated patter into a byte[] -, we defer this functionality for the moment (hey, it was
    // unusable, anyway)
    // 2005-11-15 / #i57457# / frank.schoenheit@sun.com
    return 0;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.8.60); FILE MERGED 2006/09/01 17:22:19 kaib 1.8.60.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Clob.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 02:45:13 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#ifndef _CONNECTIVITY_JAVA_SQL_CLOB_HXX_
#include "java/sql/Clob.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_TOOLS_HXX_
#include "java/tools.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_IO_READER_HXX_
#include "java/io/Reader.hxx"
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include <connectivity/dbexception.hxx>
#endif
using namespace connectivity;
//**************************************************************
//************ Class: java.sql.Clob
//**************************************************************

jclass java_sql_Clob::theClass = 0;

java_sql_Clob::java_sql_Clob( JNIEnv * pEnv, jobject myObj )
    : java_lang_Object( pEnv, myObj )
{
    SDBThreadAttach::addRef();
}
java_sql_Clob::~java_sql_Clob()
{
    SDBThreadAttach::releaseRef();
}

jclass java_sql_Clob::getMyClass()
{
    // die Klasse muss nur einmal geholt werden, daher statisch
    if( !theClass ){
        SDBThreadAttach t;
        if( !t.pEnv ) return (jclass)NULL;
        jclass tempClass = t.pEnv->FindClass( "java/sql/Clob" );
        jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
        t.pEnv->DeleteLocalRef( tempClass );
        saveClassRef( globClass );
    }
    return theClass;
}

void java_sql_Clob::saveClassRef( jclass pClass )
{
    if( pClass==NULL  )
        return;
    // der uebergebe Klassen-Handle ist schon global, daher einfach speichern
    theClass = pClass;
}

sal_Int64 SAL_CALL java_sql_Clob::length(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    jlong out(0);
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    if( t.pEnv )
    {
        // temporaere Variable initialisieren
        static const char * cSignature = "()J";
        static const char * cMethodName = "length";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            out = t.pEnv->CallLongMethod( object, mID );
            ThrowSQLException(t.pEnv,*this);
            // und aufraeumen
        } //mID
    } //t.pEnv
    return (sal_Int64)out;
}

::rtl::OUString SAL_CALL java_sql_Clob::getSubString( sal_Int64 pos, sal_Int32 subStringLength ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    ::rtl::OUString aStr;
    if( t.pEnv ){
        // temporaere Variable initialisieren
        static const char * cSignature = "(JI)Ljava/lang/String;";
        static const char * cMethodName = "getSubString";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            jstring out = (jstring)t.pEnv->CallObjectMethod( object, mID,pos,subStringLength);
            ThrowSQLException(t.pEnv,*this);
            aStr = JavaString2String(t.pEnv,out);
            // und aufraeumen
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return  aStr;
}

::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL java_sql_Clob::getCharacterStream(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    jobject out(0);
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    if( t.pEnv ){
        // temporaere Variable initialisieren
        static const char * cSignature = "()Ljava/io/Reader;";
        static const char * cMethodName = "getCharacterStream";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            out = t.pEnv->CallObjectMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return out==0 ? 0 : new java_io_Reader( t.pEnv, out );
}

sal_Int64 SAL_CALL java_sql_Clob::position( const ::rtl::OUString& searchstr, sal_Int32 start ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    jlong out(0);
    SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
    if( t.pEnv )
    {
        jvalue args[1];
        // Parameter konvertieren
        args[0].l = convertwchar_tToJavaString(t.pEnv,searchstr);
        // temporaere Variable initialisieren
        static const char * cSignature = "(Ljava/lang/String;I)J";
        static const char * cMethodName = "position";
        // Java-Call absetzen
        static jmethodID mID = NULL;
        if ( !mID  )
            mID  = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID ){
            out = t.pEnv->CallLongMethod( object, mID, args[0].l,start );
            ThrowSQLException(t.pEnv,*this);
            t.pEnv->DeleteLocalRef((jstring)args[0].l);
            // und aufraeumen
        } //mID
    } //t.pEnv
    return (sal_Int64)out;
}

sal_Int64 SAL_CALL java_sql_Clob::positionOfClob( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob >& /*pattern*/, sal_Int64 /*start*/ ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
    ::dbtools::throwFeatureNotImplementedException( "XClob::positionOfClob", *this );
    // this was put here in CWS warnings01. The previous implementation was defective, as it did ignore
    // the pattern parameter. Since the effort for proper implementation is rather high - we would need
    // to translated patter into a byte[] -, we defer this functionality for the moment (hey, it was
    // unusable, anyway)
    // 2005-11-15 / #i57457# / frank.schoenheit@sun.com
    return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ECatalog.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:11:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_FLAT_CATALOG_HXX_
#define _CONNECTIVITY_FLAT_CATALOG_HXX_

#ifndef _CONNECTIVITY_FILE_CATALOG_HXX_
#include "file/FCatalog.hxx"
#endif

namespace connectivity
{
    namespace flat
    {
        class OFlatConnection;
        class OFlatCatalog : public file::OFileCatalog
        {
    public:
            virtual void refreshTables();

        public:
            OFlatCatalog(OFlatConnection* _pCon);
        };
    }
}
#endif // _CONNECTIVITY_FLAT_CATALOG_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.2.372); FILE MERGED 2008/04/01 10:53:28 thb 1.2.372.2: #i85898# Stripping all external header guards 2008/03/28 15:24:21 rt 1.2.372.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ECatalog.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_FLAT_CATALOG_HXX_
#define _CONNECTIVITY_FLAT_CATALOG_HXX_

#include "file/FCatalog.hxx"

namespace connectivity
{
    namespace flat
    {
        class OFlatConnection;
        class OFlatCatalog : public file::OFileCatalog
        {
    public:
            virtual void refreshTables();

        public:
            OFlatCatalog(OFlatConnection* _pCon);
        };
    }
}
#endif // _CONNECTIVITY_FLAT_CATALOG_HXX_

<|endoftext|>


<commit_before>#include <string>
#include <vector>
#include "roaring.hh"

#ifndef JILL_QUERY_HEADER_INCLUDED
#define JILL_QUERY_HEADER_INCLUDED

using namespace std;

namespace jill {
namespace query {

enum FilterType {
  EQUAL,
  NOT_EQUAL
};

class Filter {
 private:
  string rval;
  string lval;
  FilterType op;
 public:
  Filter(string rval_, string lval, FilterType op_):
    rval(rval_), lval(lval), op(op_) {}
};

class GroupBy {
	string field;
};

class Aggeration {};

class PostAggregation {};

// QUERY RESULTS

class GroupByResult {
	string key;
	Roaring *bm;
};

class QueryResult {
	private:
  Roaring *filterResult;
  GroupByResult groupByResult;
};

// / QUERY RESULTS

class Query {
 private:
	// filters
	vector<Filter *> filters;
	// groupings
	vector<GroupBy> groupings;
	// aggregations
	vector<Aggeration> aggregations;
	// post-aggregations
	vector<PostAggregation> postAggregations;
	// query result
	QueryResult result;
 public:
	Query() {}
	void addFilter(Filter *filter);
};

} // namespace query
} // namespace jill

#endif
<commit_msg>rename rval to field<commit_after>#include <string>
#include <vector>
#include "roaring.hh"

#ifndef JILL_QUERY_HEADER_INCLUDED
#define JILL_QUERY_HEADER_INCLUDED

using namespace std;

namespace jill {
namespace query {

enum FilterType {
  EQUAL,
  NOT_EQUAL
};

class Filter {
 private:
  string field;
  string lval;
  FilterType op;
 public:
  Filter(string field_, string lval, FilterType op_):
    field(field_), lval(lval), op(op_) {}
};

class GroupBy {
	string field;
};

class Aggeration {};

class PostAggregation {};

// QUERY RESULTS

class GroupByResult {
	string key;
	Roaring *bm;
};

class QueryResult {
	private:
  Roaring *filterResult;
  GroupByResult groupByResult;
};

// / QUERY RESULTS

class Query {
 private:
	// filters
	vector<Filter *> filters;
	// groupings
	vector<GroupBy> groupings;
	// aggregations
	vector<Aggeration> aggregations;
	// post-aggregations
	vector<PostAggregation> postAggregations;
	// query result
	QueryResult result;
 public:
	Query() {}
	void addFilter(Filter *filter);
};

} // namespace query
} // namespace jill

#endif
<|endoftext|>