Commit b965d031 authored by Antony T Curtis's avatar Antony T Curtis

Merge OQGraph3 into MariaDB 5.5.27

parents a0efc4bd 0fee6ce7
/* Copyright (C) 2009-2011 Arjen G Lentz & Antony T Curtis for Open Query
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; 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.III implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#include "graphcore-graph.h"
......@@ -27,22 +27,142 @@
#ifndef oq_graphcore_graph_h_
#define oq_graphcore_graph_h_
typedef adjacency_list
<
vecS,
vecS,
bidirectionalS,
VertexInfo,
EdgeInfo
> Graph;
#define GRAPH_WEIGHTMAP(G) get(&EdgeInfo::weight, G)
typedef property_map<Graph, EdgeWeight EdgeInfo::*>::type weightmap_type;
#define GRAPH_INDEXMAP(G) get(vertex_index, G)
typedef property_map<Graph, vertex_index_t>::type indexmap_type;
#define GRAPH_IDMAP(G) get(&VertexInfo::id, G)
typedef property_map<Graph, VertexID VertexInfo::*>::type idmap_type;
#include "oqgraph_shim.h"
#include <boost/graph/two_bit_color_map.hpp>
namespace boost
{
typedef oqgraph3::graph Graph;
template<typename IndexMap = identity_property_map>
struct two_bit_judy_map
{
typedef typename property_traits<IndexMap>::key_type key_type;
typedef two_bit_color_type value_type;
typedef void reference;
typedef read_write_property_map_tag category;
open_query::judy_bitset msb;
open_query::judy_bitset lsb;
IndexMap index;
two_bit_judy_map(const IndexMap& i)
: index(i)
{ }
friend two_bit_color_type get(
const two_bit_judy_map<IndexMap>& pm,
typename property_traits<IndexMap>::key_type key)
{
typename property_traits<IndexMap>::value_type i = get(pm.index, key);
return two_bit_color_type((2*int(pm.msb.test(i))) | int(pm.lsb.test(i)));
}
friend void put(
two_bit_judy_map<IndexMap>& pm,
typename property_traits<IndexMap>::key_type key,
two_bit_color_type value)
{
typename property_traits<IndexMap>::value_type i = get(pm.index, key);
pm.msb.set(i, value & 2);
pm.lsb.set(i, value & 1);
}
};
template<typename IndexMap>
inline two_bit_judy_map<IndexMap>
make_two_bit_judy_map(const IndexMap& index)
{
return two_bit_judy_map<IndexMap>(index);
}
template <typename Type>
struct default_lazy_initializer
{
template <typename Key>
Type operator()(const Key&) const { return Type(); }
};
template <typename Type>
struct copy_initializer
{
copy_initializer(const Type& value) : _(value) { }
template <typename Key>
const Type& operator()(const Key&) const { return _; }
const Type& _;
};
template <typename Type>
copy_initializer<Type> make_copy_initializer(const Type& value)
{ return copy_initializer<Type>(value); }
template <typename Type>
struct value_initializer
{
value_initializer(const Type& value) : _(value) { }
template <typename Key>
const Type& operator()(const Key&) const { return _; }
const Type _;
};
template <typename Type>
value_initializer<Type> make_value_initializer(const Type& value)
{ return value_initializer<Type>(value); }
template <typename Key>
struct identity_initializer
{
const Key& operator()(const Key& _) const { return _; }
};
template <class Container, class Generator>
struct lazy_property_map
{
typedef lazy_property_map<Container, Generator> self;
typedef typename Container::key_type key_type;
typedef typename Container::value_type::second_type value_type;
typedef value_type& reference;
typedef lvalue_property_map_tag category;
lazy_property_map(Container& m, Generator g= Generator())
: _m(m)
, _g(g)
{ }
reference operator[](const key_type& k) const
{
typename Container::iterator found= _m.find(k);
if (_m.end() == found)
{
found= _m.insert(std::make_pair(k, _g(k))).first;
}
return found->second;
}
void set(const key_type& k, const value_type& v)
{ _m[k] = v; }
friend reference get(const self& s, const key_type& k)
{
return s[k];
}
friend void put(self& s, const key_type& k, const value_type& v)
{ s.set(k, v); }
Container& _m;
Generator _g;
};
template <class Container, class Generator>
lazy_property_map<Container, Generator>
make_lazy_property_map(Container& c, Generator g)
{ return lazy_property_map<Container, Generator>(c, g); }
}
#endif
......@@ -26,6 +26,7 @@
#ifndef oq_graphcore_types_h_
#define oq_graphcore_types_h_
namespace open_query
{
......@@ -33,4 +34,9 @@ namespace open_query
typedef double EdgeWeight;
}
class Field;
typedef struct st_table TABLE;
#endif
This diff is collapsed.
......@@ -104,7 +104,7 @@ namespace open_query
void row_ref(void*) throw();
static oqgraph* create(oqgraph_share*) throw();
static oqgraph_share *create() throw();
static oqgraph_share *create(TABLE*,Field*,Field*,Field*) throw();
static void free(oqgraph*) throw();
static void free(oqgraph_share*) throw();
......
This diff is collapsed.
......@@ -37,19 +37,21 @@ namespace open_query
{
struct row;
class oqgraph;
class oqgraph_share;
}
/* class for the the Open Query Graph handler */
class ha_oqgraph: public handler
{
OQGRAPH_INFO *share;
TABLE_SHARE share[1];
TABLE edges[1];
Field *origid;
Field *destid;
Field *weight;
open_query::oqgraph_share *graph_share;
open_query::oqgraph *graph;
THR_LOCK_DATA lock;
/* number of records changed since last statistics update */
uint records_changed;
uint key_stat_version;
bool replace_dups, ignore_dups, insert_dups;
int fill_record(byte*, const open_query::row&);
......@@ -61,7 +63,7 @@ class ha_oqgraph: public handler
ha_oqgraph(TABLE *table);
Table_flags table_flags() const;
#endif
~ha_oqgraph() {}
~ha_oqgraph();
const char *table_type() const
{
return "OQGRAPH";
......@@ -107,6 +109,12 @@ class ha_oqgraph: public handler
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
int cmp_ref(const byte *ref1, const byte *ref2);
bool get_error_message(int error, String* buf);
void print_error(const char* fmt, ...);
private:
void update_key_stats();
String error_message;
};
/* Copyright (C) 2009-2011 Arjen G Lentz & Antony T Curtis for Open Query
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; 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.III implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#include "oqgraph_judy.h"
#include <Judy.h>
void open_query::judy_bitset::clear()
{
int rc;
J1FA(rc, array);
}
bool open_query::judy_bitset::test(size_type n) const
{
int rc;
J1T(rc, array, n);
return rc == 1;
}
open_query::judy_bitset& open_query::judy_bitset::setbit(size_type n)
{
int rc;
J1S(rc, array, n);
return *this;
}
open_query::judy_bitset& open_query::judy_bitset::reset(size_type n)
{
int rc;
J1U(rc, array, n);
return *this;
}
open_query::judy_bitset& open_query::judy_bitset::flip(size_type n)
{
int rc;
J1U(rc, array, n);
if (!rc)
{
J1S(rc, array, n);
}
return *this;
}
open_query::judy_bitset::size_type open_query::judy_bitset::num_blocks() const
{
Word_t rc;
J1MU(rc, array);
return rc;
}
open_query::judy_bitset::size_type open_query::judy_bitset::size() const
{
int rc;
Word_t index = (Word_t) -1;
J1L(rc, array, index);
if (!rc)
return index;
else
return npos;
}
open_query::judy_bitset::size_type open_query::judy_bitset::count() const
{
Word_t rc;
J1C(rc, array, 0, -1);
return rc;
}
open_query::judy_bitset& open_query::judy_bitset::set(const judy_bitset& src)
{
if (!src.empty())
{
for (size_type pos= src.find_first(); pos != npos; pos= src.find_next(pos))
{
set(pos);
}
}
return *this;
}
open_query::judy_bitset::size_type open_query::judy_bitset::find_first() const
{
int rc;
Word_t index = 0;
J1F(rc, array, index);
if (!rc)
return index;
else
return npos;
}
open_query::judy_bitset::size_type open_query::judy_bitset::find_next(size_type n) const
{
int rc;
Word_t index = (Word_t) n;
J1N(rc, array, index);
if (!rc)
return index;
else
return npos;
}
/* Copyright (C) 2009-2011 Arjen G Lentz & Antony T Curtis for Open Query
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; 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.III implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#pragma once
#include <cstddef>
namespace open_query
{
class judy_bitset
{
public:
typedef std::size_t size_type;
enum { npos = (size_type) -1 };
judy_bitset()
: array(0)
{ }
judy_bitset(const judy_bitset& src)
: array(0)
{
set(src);
}
~judy_bitset()
{ clear(); }
judy_bitset& operator=(const judy_bitset& src)
{
clear();
return set(src);
}
void clear();
bool empty() const { return !array; }
bool none() const { return npos == find_first(); }
inline judy_bitset& set(size_type n, bool val = true)
{
if (!val)
return reset(n);
else
return setbit(n);
}
judy_bitset& set(const judy_bitset& src);
judy_bitset& reset(size_type n);
judy_bitset& flip(size_type n);
bool test(size_type) const;
size_type count() const;
size_type size() const;
size_type num_blocks() const;
class reference
{
friend class judy_bitset;
reference(judy_bitset& array, size_type pos)
: j(array)
, n(pos)
{ }
void operator&(); // not defined
public:
reference& operator=(bool value)
{ j.set(n, value); return *this; }
reference& operator=(const reference& ref)
{ j.set(n, ref); return *this; }
reference& operator|=(bool value)
{ if (value) j.set(n); return *this; }
reference& operator&=(bool value)
{ if (!value) j.reset(n); return *this; }
reference& operator^=(bool value)
{ if (value) j.flip(n); return *this; }
reference& operator-=(bool value)
{ if (value) j.reset(n); return *this; }
bool operator~() const { return !j.test(n); }
operator bool() const { return j.test(n); }
reference& flip() { j.flip(n); return *this; }
private:
judy_bitset& j;
size_type n;
};
reference operator[](size_type n) { return reference(*this, n); }
bool operator[](size_type n) const { return test(n); }
size_type find_first() const;
size_type find_next(size_type n) const;
private:
mutable void* array;
judy_bitset& setbit(size_type n);
};
}
/* Copyright (C) 2009-2011 Arjen G Lentz & Antony T Curtis for Open Query
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; 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.III implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#include "oqgraph_shim.h"
bool oqgraph3::edge_iterator::seek()
{
if (!_graph->_cursor ||
_graph->_rnd_pos > _offset ||
_graph->_cursor != _graph->_rnd_cursor.operator->())
{
_graph->_rnd_pos= 0;
_graph->_rnd_cursor= new cursor(_graph);
if (_graph->_rnd_cursor->seek_to(boost::none, boost::none))
_graph->_rnd_pos= size_t(-1);
}
while (_graph->_rnd_pos < _offset)
{
if (_graph->_rnd_cursor->seek_next())
{
_offset = size_t(-1);
return true;
}
_graph->_rnd_pos++;
}
return false;
}
oqgraph3::edge_iterator::value_type oqgraph3::edge_iterator::operator*()
{
seek();
return *_graph->_rnd_cursor;
}
bool oqgraph3::edge_iterator::operator==(const self& x)
{
if (_offset == size_t(-1) && x._offset != size_t(-1))
return const_cast<edge_iterator&>(x).seek();
if (_offset != size_t(-1) && x._offset == size_t(-1))
return seek();
return _offset == x._offset;
}
bool oqgraph3::edge_iterator::operator!=(const self& x)
{
if (_offset == size_t(-1) && x._offset != size_t(-1))
return !const_cast<edge_iterator&>(x).seek();
if (_offset != size_t(-1) && x._offset == size_t(-1))
return !seek();
return _offset != x._offset;
}
This diff is collapsed.
This diff is collapsed.
/* Copyright (C) 2009-2011 Arjen G Lentz & Antony T Curtis for Open Query
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; 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* ======================================================================
Open Query Graph Computation Engine, based on a concept by Arjen Lentz
Mk.III implementation by Antony Curtis & Arjen Lentz
For more information, documentation, support, enhancement engineering,
and non-GPL licensing, see http://openquery.com/graph
or contact graph@openquery.com
For packaged binaries, see http://ourdelta.org
======================================================================
*/
#pragma once
#include <list>
#include <queue>
#include <string>
#include <utility>
#include <boost/intrusive_ptr.hpp>
#include <boost/optional.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <boost/pending/queue.hpp>
#include <boost/ptr_container/ptr_deque.hpp>
#include "graphcore-types.h"
namespace oqgraph3
{
typedef open_query::VertexID vertex_id;
typedef open_query::EdgeWeight weight_t;
typedef size_t vertices_size_type;
typedef size_t edges_size_type;
typedef size_t degree_size_type;
struct graph;
struct cursor;
typedef boost::intrusive_ptr<graph> graph_ptr;
struct cursor_ptr : public boost::intrusive_ptr<cursor>
{
cursor_ptr() : boost::intrusive_ptr<cursor>() { }
cursor_ptr(cursor* pos) : boost::intrusive_ptr<cursor>(pos) { }
operator const std::string&() const;
bool operator==(const cursor_ptr&) const;
bool operator!=(const cursor_ptr&) const;
};
struct edge_info
{
cursor_ptr _cursor;
edge_info() : _cursor(0) { }
explicit edge_info(const cursor_ptr& pos) : _cursor(pos) { }
edge_info& operator=(const cursor_ptr& pos) { _cursor= pos; return *this; }
vertex_id origid() const;
vertex_id destid() const;
weight_t weight() const;
bool operator==(const edge_info&) const;
bool operator!=(const edge_info&) const;
};
struct cursor
{
mutable int _ref_count;
graph_ptr _graph;
int _index;
unsigned _parts;
std::string _key;
std::string _position;
int _debugid;
boost::optional<vertex_id> _origid;
boost::optional<vertex_id> _destid;
cursor(const graph_ptr& graph);
cursor(const cursor& src);
~cursor();
operator bool() const
{ return !_position.empty(); }
operator edge_info() const
{ return edge_info(const_cast<cursor*>(this)); }
vertex_id get_origid();
vertex_id get_destid();
weight_t get_weight();
int seek_to(
boost::optional<vertex_id> origid,
boost::optional<vertex_id> destid);
int seek_next();
int seek_prev();
void save_position();
int restore_position();
const std::string& record_position() const;
void clear_position();
int clear_position(int rc) { clear_position(); return rc; }
bool operator==(const cursor& x) const;
bool operator!=(const cursor& x) const;
friend void intrusive_ptr_add_ref(cursor* ptr)
{ ++ptr->_ref_count; }
friend void intrusive_ptr_release(cursor* ptr)
{ if (!--(ptr->_ref_count)) delete ptr; }
};
struct graph
{
mutable int _ref_count;
cursor* _cursor;
bool _stale;
cursor_ptr _rnd_cursor;
size_t _rnd_pos;
::TABLE* _table;
::Field* _source;
::Field* _target;
::Field* _weight;
graph(
::TABLE* table,
::Field* source,
::Field* target,
::Field* weight= 0);
~graph();
edges_size_type num_edges() const;
friend edges_size_type num_edges(const graph& g)
{ return g.num_edges(); }
friend void intrusive_ptr_add_ref(graph* ptr)
{ ptr->_ref_count++; }
friend void intrusive_ptr_release(graph* ptr)
{ ptr->_ref_count--; }
};
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment