diff --git a/Makefile.am b/Makefile.am index 357d446b..5d27bc5e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,6 +115,7 @@ noinst_HEADERS += common/attribute_check.h noinst_HEADERS += common/attribute.h noinst_HEADERS += common/auth_wallet.h noinst_HEADERS += common/configuration.h +noinst_HEADERS += common/hypercube.h noinst_HEADERS += common/configuration_flags.h noinst_HEADERS += common/coordinator_link.h noinst_HEADERS += common/coordinator_returncode.h @@ -229,6 +230,7 @@ hyperdex_daemon_SOURCES += common/attribute.cc hyperdex_daemon_SOURCES += common/attribute_check.cc hyperdex_daemon_SOURCES += common/auth_wallet.cc hyperdex_daemon_SOURCES += common/configuration.cc +hyperdex_daemon_SOURCES += common/hypercube.cc hyperdex_daemon_SOURCES += common/coordinator_link.cc hyperdex_daemon_SOURCES += common/coordinator_returncode.cc hyperdex_daemon_SOURCES += common/datatype_document.cc @@ -397,6 +399,7 @@ noinst_HEADERS += client/pending_group_del.h noinst_HEADERS += client/pending.h noinst_HEADERS += client/pending_search_describe.h noinst_HEADERS += client/pending_search.h +noinst_HEADERS += client/pending_volume_search.h noinst_HEADERS += client/pending_sorted_search.h noinst_HEADERS += client/util.h @@ -405,6 +408,7 @@ libhyperdex_client_la_SOURCES += common/attribute.cc libhyperdex_client_la_SOURCES += common/attribute_check.cc libhyperdex_client_la_SOURCES += common/auth_wallet.cc libhyperdex_client_la_SOURCES += common/configuration.cc +libhyperdex_client_la_SOURCES += common/hypercube.cc libhyperdex_client_la_SOURCES += common/coordinator_link.cc libhyperdex_client_la_SOURCES += common/datatype_document.cc libhyperdex_client_la_SOURCES += common/datatype_float.cc @@ -447,6 +451,7 @@ libhyperdex_client_la_SOURCES += client/pending_group_del.cc libhyperdex_client_la_SOURCES += client/pending_search.cc libhyperdex_client_la_SOURCES += client/pending_search_describe.cc libhyperdex_client_la_SOURCES += client/pending_sorted_search.cc +libhyperdex_client_la_SOURCES += client/pending_volume_search.cc libhyperdex_client_la_SOURCES += client/util.cc libhyperdex_client_la_LIBADD = libhyperdex_client_la_LIBADD += $(MACAROONS_LIBS) @@ -499,6 +504,7 @@ libhyperdex_admin_la_SOURCES = libhyperdex_admin_la_SOURCES += common/attribute.cc libhyperdex_admin_la_SOURCES += common/attribute_check.cc libhyperdex_admin_la_SOURCES += common/configuration.cc +libhyperdex_admin_la_SOURCES += common/hypercube.cc libhyperdex_admin_la_SOURCES += common/coordinator_link.cc libhyperdex_admin_la_SOURCES += common/datatype_document.cc libhyperdex_admin_la_SOURCES += common/datatype_float.cc diff --git a/client/c.cc b/client/c.cc index 10cb2e14..8cf904e0 100644 --- a/client/c.cc +++ b/client/c.cc @@ -1312,6 +1312,19 @@ hyperdex_client_search(struct hyperdex_client* _cl, ); } +HYPERDEX_API int64_t +hyperdex_client_volume_search(struct hyperdex_client* _cl, + const char* space, + const struct hyperdex_client_attribute_check* checks, size_t checks_sz, + enum hyperdex_client_returncode* status, + const struct hyperdex_client_attribute** attrs, size_t* attrs_sz, + const struct hyperdex_client_hypercube * cbs, size_t cbs_sz) +{ + C_WRAP_EXCEPT( + return cl->volume_search(space, checks, checks_sz, status, attrs, attrs_sz,cbs,cbs_sz); + ); +} + HYPERDEX_API int64_t hyperdex_client_search_describe(struct hyperdex_client* _cl, const char* space, diff --git a/client/client.cc b/client/client.cc index ac8d14c7..83e7fc17 100644 --- a/client/client.cc +++ b/client/client.cc @@ -59,6 +59,7 @@ #include "client/pending_search.h" #include "client/pending_search_describe.h" #include "client/pending_sorted_search.h" +#include "client/pending_volume_search.h" #define ERROR(CODE) \ *status = HYPERDEX_CLIENT_ ## CODE; \ @@ -78,6 +79,7 @@ return false; using hyperdex::client; +using hyperdex::hypercube; client :: client(const char* coordinator, uint16_t port) : m_coord(coordinator, port) @@ -268,9 +270,10 @@ client :: get_partial(const char* space, const char* _key, size_t _key_sz, return -1; \ } \ std::vector checks; \ + std::vector cubes; \ std::vector servers; \ arena_t allocate; \ - int64_t ret = prepare_searchop(*sc, space, chks, chks_sz, &allocate, status, &checks, &servers); \ + int64_t ret = prepare_searchop(*sc, space, chks, chks_sz, NULL, 0, &allocate, status, &checks, &cubes, &servers); \ if (ret < 0) \ { \ return ret; \ @@ -294,6 +297,43 @@ client :: search(const char* space, return perform_aggregation(servers, op, REQ_SEARCH_START, msg, status); } +int64_t +client :: volume_search(const char* space, + const hyperdex_client_attribute_check* chks, size_t chks_sz, + hyperdex_client_returncode* status, + const hyperdex_client_attribute** attrs, size_t* attrs_sz, + const hyperdex_client_hypercube * cbs, size_t cbs_sz) +{ + if (!maintain_coord_connection(status)) + { + return -1; \ + } + const schema* sc = m_coord.config()->get_schema(space); + if (!sc) + { + ERROR(UNKNOWNSPACE) << "space \"" << e::strescape(space) << "\" does not exist"; + return -1; + } + std::vector checks; + std::vector cubes; + std::vector servers; + arena_t allocate; + int64_t ret = prepare_searchop(*sc, space, chks, chks_sz, cbs, cbs_sz, &allocate, status, &checks, &cubes, &servers); + if (ret < 0) + { + return ret; + } + int64_t client_id = m_next_client_id++; + e::intrusive_ptr op; + op = new pending_volume_search(client_id, status, attrs, attrs_sz,cubes); + size_t sz = HYPERDEX_CLIENT_HEADER_SIZE_REQ + + sizeof(uint64_t) + + pack_size(checks); + std::auto_ptr msg(e::buffer::create(sz)); + msg->pack_at(HYPERDEX_CLIENT_HEADER_SIZE_REQ) << client_id << checks; + return perform_aggregation(servers, op, REQ_SEARCH_START, msg, status); +} + int64_t client :: search_describe(const char* space, const hyperdex_client_attribute_check* chks, size_t chks_sz, @@ -728,6 +768,38 @@ client :: attribute_type(const char* space, const char* name, return sc->attrs[attrnum].type; } +size_t +client :: prepare_cubes(const char* space, const schema& sc, + const hyperdex_client_hypercube* cbs, size_t cbs_sz, + arena_t* allocate, + hyperdex_client_returncode* status, + std::vector* cubes) +{ + cubes->reserve(cubes->size() + cbs_sz); + + for (size_t i = 0; i < cbs_sz; ++i) + { + uint16_t attrnum[cbs[i].dims]; + for (size_t j = 0; j < cbs[i].dims; ++j) + { + attrnum[j] = sc.lookup_attr(cbs[i].attrs[j]); + if (attrnum[j] >= sc.attrs_sz) + { + ERROR(UNKNOWNATTR) << "\"" << e::strescape(cbs[i].attrs[j]) + << "\" is not an attribute of space \"" + << e::strescape(space) << "\""; + return i; + } + } + + + hypercube cube(attrnum, cbs[i].dims, cbs[i].lower_coord, cbs[i].upper_coord); + + cubes->push_back(cube); + } + + return cbs_sz; +} size_t client :: prepare_checks(const char* space, const schema& sc, const hyperdex_client_attribute_check* chks, size_t chks_sz, @@ -939,13 +1011,16 @@ client :: prepare_funcs(const char* space, const schema& sc, return mapattrs_sz; } + size_t client :: prepare_searchop(const schema& sc, const char* space, const hyperdex_client_attribute_check* chks, size_t chks_sz, + const hyperdex_client_hypercube* cbs, size_t cbs_sz, arena_t* allocate, hyperdex_client_returncode* status, std::vector* checks, + std::vector* cubes, std::vector* servers) { size_t num_checks = prepare_checks(space, sc, chks, chks_sz, allocate, status, checks); @@ -954,9 +1029,15 @@ client :: prepare_searchop(const schema& sc, { return -1 - num_checks; } + size_t num_cubes= prepare_cubes(space, sc, cbs, cbs_sz, allocate, status, cubes); + + if (num_cubes != cbs_sz) + { + return -1 - num_cubes; + } std::stable_sort(checks->begin(), checks->end()); - m_coord.config()->lookup_search(space, *checks, servers); // XXX search guaranteed empty vs. search encounters offline server + m_coord.config()->lookup_search(space, *checks, *cubes, servers); // XXX search guaranteed empty vs. search encounters offline server if (servers->empty()) { diff --git a/client/client.h b/client/client.h index 281b23f4..8c93e061 100644 --- a/client/client.h +++ b/client/client.h @@ -74,6 +74,11 @@ class client const hyperdex_client_attribute_check* checks, size_t checks_sz, hyperdex_client_returncode* status, const hyperdex_client_attribute** attrs, size_t* attrs_sz); + int64_t volume_search(const char* space, + const hyperdex_client_attribute_check* checks, size_t checks_sz, + hyperdex_client_returncode* status, + const hyperdex_client_attribute** attrs, size_t* attrs_sz, + const hyperdex_client_hypercube * cbs, size_t cbs_sz); int64_t search_describe(const char* space, const hyperdex_client_attribute_check* checks, size_t checks_sz, hyperdex_client_returncode* status, const char** description); @@ -129,9 +134,15 @@ class client friend class pending_get; friend class pending_get_partial; friend class pending_search; + friend class pending_volume_search; friend class pending_sorted_search; private: + size_t prepare_cubes(const char* space, const schema& sc, + const hyperdex_client_hypercube* cbs, size_t cbs_sz, + arena_t* allocate, + hyperdex_client_returncode* status, + std::vector* cubes); size_t prepare_checks(const char* space, const schema& sc, const hyperdex_client_attribute_check* chks, size_t chks_sz, arena_t* allocate, @@ -152,9 +163,11 @@ class client size_t prepare_searchop(const schema& sc, const char* space, const hyperdex_client_attribute_check* chks, size_t chks_sz, + const hyperdex_client_hypercube* cbs, size_t cbs_sz, arena_t* allocate, hyperdex_client_returncode* status, std::vector* checks, + std::vector* cubes, std::vector* servers); int64_t perform_aggregation(const std::vector& servers, e::intrusive_ptr op, diff --git a/client/pending_volume_search.cc b/client/pending_volume_search.cc new file mode 100644 index 00000000..9191085d --- /dev/null +++ b/client/pending_volume_search.cc @@ -0,0 +1,195 @@ +// Copyright (c) 2011-2013, Cornell University +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of HyperDex nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// HyperDex +#include "client/client.h" +#include "client/constants.h" +#include "client/pending_volume_search.h" +#include "client/util.h" +#include "common/hash.h" + +using hyperdex::pending_volume_search; + +pending_volume_search :: pending_volume_search(uint64_t id, + hyperdex_client_returncode* status, + const hyperdex_client_attribute** attrs, size_t* attrs_sz, std::vector cubes) + : pending_aggregation(id, status) + , m_attrs(attrs) + , m_attrs_sz(attrs_sz) + , m_yield(false) + , m_done(false) +{ + *m_attrs = NULL; + *m_attrs_sz = 0; + this->cubes= cubes; +} + +pending_volume_search :: ~pending_volume_search() throw () +{ +} + +bool +pending_volume_search :: can_yield() +{ + return m_yield; +} + +bool +pending_volume_search :: yield(hyperdex_client_returncode* status, e::error* err) +{ + *status = HYPERDEX_CLIENT_SUCCESS; + *err = e::error(); + m_yield = false; + + if (this->aggregation_done() && !m_done) + { + m_yield = true; + m_done = true; + } + else if (m_done) + { + set_status(HYPERDEX_CLIENT_SEARCHDONE); + } + + return true; +} + +void +pending_volume_search :: handle_failure(const server_id& si, + const virtual_server_id& vsi) +{ + m_yield = true; + PENDING_ERROR(RECONFIGURE) << "reconfiguration affecting " + << vsi << "/" << si; + return pending_aggregation::handle_failure(si, vsi); +} + +bool +pending_volume_search :: handle_message(client* cl, + const server_id& si, + const virtual_server_id& vsi, + network_msgtype mt, + std::auto_ptr msg, + e::unpacker up, + hyperdex_client_returncode* status, + e::error* err) +{ + bool handled = pending_aggregation::handle_message(cl, si, vsi, mt, std::auto_ptr(), up, status, err); + assert(handled); + + + *status = HYPERDEX_CLIENT_SUCCESS; + *err = e::error(); + + if (mt == RESP_SEARCH_DONE) + { + if (this->aggregation_done()) + { + m_yield = true; + m_done = true; + } + + return true; + } + else if (mt != RESP_SEARCH_ITEM) + { + PENDING_ERROR(SERVERERROR) << "server " << vsi << " responded to SEARCH with " << mt; + m_yield = true; + return true; + } + + e::slice key; + std::vector value; + up = up >> key >> value; + + if (up.error()) + { + PENDING_ERROR(SERVERERROR) << "communication error: server " + << vsi << " sent corrupt message=" + << msg->as_slice().hex() + << " in response to a SEARCH"; + m_yield = true; + return true; + } + + hyperdex_client_returncode op_status; + e::error op_error; + + const schema* sc =cl->m_coord.config()->get_schema(cl->m_coord.config()->get_region_id(vsi)); + + assert((value.size() + 1) == sc->attrs_sz); + + bool found_matching_cube = false; + for (size_t i = 0; !found_matching_cube && i < cubes.size(); ++i) { + bool matches = true; + for (size_t j = 0; matches&& j < cubes[i].attr.size(); ++j) { + uint16_t attrnum = cubes[i].attr[j] -1; + uint64_t h = hash(sc->attrs[attrnum+1].type, value[attrnum]); + if (cubes[i].lower_coord[j] <= h && h <= cubes[i].upper_coord[j]) { + matches = matches && true; + } else { + matches = false; + } + } + if (matches) { + found_matching_cube = true; + } + } + bool no_yield = false; + if (!found_matching_cube && cubes.size() > 0) { + m_yield = false; + no_yield = true; + } else { + + if (!value_to_attributes(*cl->m_coord.config(), + cl->m_coord.config()->get_region_id(vsi), + key.data(), key.size(), value, + &op_status, &op_error, m_attrs, m_attrs_sz)) + { + set_status(op_status); + set_error(op_error); + m_yield = true; + return true; + } + } + std::auto_ptr smsg(e::buffer::create(HYPERDEX_CLIENT_HEADER_SIZE_REQ + sizeof(uint64_t))); + smsg->pack_at(HYPERDEX_CLIENT_HEADER_SIZE_REQ) << static_cast(client_visible_id()); + + if (!cl->send(REQ_SEARCH_NEXT, vsi, cl->m_next_server_nonce++, smsg, this, status)) + { + PENDING_ERROR(RECONFIGURE) << "could not send SEARCH_NEXT to " << vsi; + m_yield = true; + return true; + } + + set_status(HYPERDEX_CLIENT_SUCCESS); + set_error(e::error()); + if (!no_yield) { + m_yield = true; + } + return true; +} diff --git a/client/pending_volume_search.h b/client/pending_volume_search.h new file mode 100644 index 00000000..e2141de1 --- /dev/null +++ b/client/pending_volume_search.h @@ -0,0 +1,79 @@ +// Copyright (c) 2011-2013, Cornell University +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of HyperDex nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef hyperdex_client_pending_volume_search_h_ +#define hyperdex_client_pending_volume_search_h_ + +// HyperDex +#include "namespace.h" +#include "client/pending_aggregation.h" + +BEGIN_HYPERDEX_NAMESPACE + +class pending_volume_search : public pending_aggregation +{ + public: + pending_volume_search(uint64_t client_visible_id, + hyperdex_client_returncode* status, + const hyperdex_client_attribute** attrs, size_t* attrs_sz, + std::vector cubes); + virtual ~pending_volume_search() throw (); + + // return to client + public: + virtual bool can_yield(); + virtual bool yield(hyperdex_client_returncode* status, e::error* error); + + // events + public: + virtual void handle_failure(const server_id& si, + const virtual_server_id& vsi); + virtual bool handle_message(client*, + const server_id& si, + const virtual_server_id& vsi, + network_msgtype mt, + std::auto_ptr msg, + e::unpacker up, + hyperdex_client_returncode* status, + e::error* error); + + // noncopyable + private: + pending_volume_search(const pending_volume_search& other); + pending_volume_search& operator = (const pending_volume_search& rhs); + + private: + const hyperdex_client_attribute** m_attrs; + size_t* m_attrs_sz; + bool m_yield; + bool m_done; + std::vector cubes; +}; + +END_HYPERDEX_NAMESPACE + +#endif // hyperdex_client_pending_volume_search_h_ diff --git a/common/configuration.cc b/common/configuration.cc index 669d5213..d1a7e0b5 100644 --- a/common/configuration.cc +++ b/common/configuration.cc @@ -737,6 +737,7 @@ configuration :: lookup_region(const subspace_id& ssid, void configuration :: lookup_search(const char* space_name, const std::vector& chks, + const std::vector& cubes, std::vector* servers) const { const space* s = NULL; @@ -784,10 +785,56 @@ configuration :: lookup_search(const char* space_name, continue; } + bool exclude = false; + bool included_in_cube= false; + + for (size_t k = 0; !included_in_cube && k < cubes.size(); ++k) + { + assert(cubes[k].attr.size() == cubes[k].lower_coord.size() && + cubes[k].lower_coord.size()== cubes[k].upper_coord.size()); + bool cube_matches = true; + + for (size_t l = 0; cube_matches && l < cubes[k].attr.size(); ++l) + { + uint16_t attr = cubes[k].attr[l]; + uint16_t dim = UINT16_MAX; + + for (size_t m = 0; m < s->subspaces[i].attrs.size(); ++m) + { + if (s->subspaces[i].attrs[m] == attr) + { + dim = l; + break; + } + } + + if (dim == UINT16_MAX) {continue;} + + uint64_t cl = cubes[k].lower_coord[l]; + uint64_t cu = cubes[k].upper_coord[l]; + uint64_t rl = reg.lower_coord[dim]; + uint64_t ru = reg.upper_coord[dim]; + if (!(rl <= cl && cl <= ru) && !(rl <= cu && cu <= ru) && !(cl <= rl && ru <= cu)) + { + cube_matches = false; + } + } + + if (cube_matches) + { + // there is at least one cube in this region + included_in_cube = true; + } + } + + if (!included_in_cube && cubes.size() > 0) { + exclude = true; + } for (size_t k = 0; !exclude && k < ranges.size(); ++k) { + assert(reg.lower_coord.size() == reg.upper_coord.size()); uint16_t attr = UINT16_MAX; diff --git a/common/configuration.h b/common/configuration.h index 2528242d..49855084 100644 --- a/common/configuration.h +++ b/common/configuration.h @@ -43,6 +43,7 @@ #include "common/attribute.h" #include "common/attribute_check.h" #include "common/hyperspace.h" +#include "common/hypercube.h" #include "common/ids.h" #include "common/schema.h" #include "common/server.h" @@ -118,6 +119,7 @@ class configuration region_id* region) const; void lookup_search(const char* space, const std::vector& chks, + const std::vector& cubes, std::vector* servers) const; public: diff --git a/common/hypercube.cc b/common/hypercube.cc new file mode 100644 index 00000000..8e38744d --- /dev/null +++ b/common/hypercube.cc @@ -0,0 +1,19 @@ + +#include "common/hypercube.h" + + +hyperdex:: hypercube:: hypercube(uint16_t * attrs, size_t attrs_sz, uint64_t * lower_coords, uint64_t * upper_coords) + { + for (size_t i = 0; i < attrs_sz; ++i) + { + attr.push_back(attrs[i]); + lower_coord.push_back(lower_coords[i]); + upper_coord.push_back(upper_coords[i]); + } + + } + +hyperdex:: hypercube :: ~hypercube() throw () + { + } + diff --git a/common/hypercube.h b/common/hypercube.h new file mode 100644 index 00000000..a91f80d2 --- /dev/null +++ b/common/hypercube.h @@ -0,0 +1,28 @@ + +#ifndef hyperdex_common_hypercube_h_ +#define hyperdex_common_hypercube_h_ + +// STL +#include + +#include +//for size_t +#include +#include "namespace.h" + +BEGIN_HYPERDEX_NAMESPACE +class hypercube; + +class hypercube +{ + public: + hypercube(uint16_t * attrs, size_t attrs_sz, uint64_t * lower_coord, uint64_t * upper_coord); + ~hypercube() throw(); + + public: + std::vector attr; + std::vector lower_coord; + std::vector upper_coord; +}; +END_HYPERDEX_NAMESPACE +#endif diff --git a/include/hyperdex/client.h b/include/hyperdex/client.h index 1c305436..f9a3eda8 100644 --- a/include/hyperdex/client.h +++ b/include/hyperdex/client.h @@ -70,6 +70,13 @@ struct hyperdex_client_attribute_check enum hyperpredicate predicate; }; +struct hyperdex_client_hypercube /*temporary struct for temporary c bindings */ +{ + size_t dims; + const char** attrs; /* NULL-terminated */ + uint64_t * lower_coord; + uint64_t * upper_coord; +}; /* hyperdex_client_returncode occupies [8448, 8576) */ enum hyperdex_client_returncode { @@ -660,6 +667,13 @@ hyperdex_client_search(struct hyperdex_client* client, const struct hyperdex_client_attribute_check* checks, size_t checks_sz, enum hyperdex_client_returncode* status, const struct hyperdex_client_attribute** attrs, size_t* attrs_sz); +int64_t +hyperdex_client_volume_search(struct hyperdex_client* client, + const char* space, + const struct hyperdex_client_attribute_check* checks, size_t checks_sz, + enum hyperdex_client_returncode* status, + const struct hyperdex_client_attribute** attrs, size_t* attrs_sz, + const struct hyperdex_client_hypercube * cbs, size_t cbs_sz); int64_t hyperdex_client_search_describe(struct hyperdex_client* client,