Add new files missed in last commit.

pull/8303/head
Mark D. Roth 8 years ago
parent 4c3a4688bb
commit 2e8920873d
  1. 214
      src/core/ext/client_config/method_config.c
  2. 85
      src/core/ext/client_config/method_config.h

@ -0,0 +1,214 @@
//
// Copyright 2015, Google Inc.
// 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 Google Inc. 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.
//
#include "src/core/ext/client_config/method_config.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/transport/metadata.h"
//
// grpc_method_config
//
struct grpc_method_config {
gpr_refcount refs;
bool* wait_for_ready;
gpr_timespec* timeout;
int32_t* max_request_message_bytes;
int32_t* max_response_message_bytes;
};
grpc_method_config* grpc_method_config_create(
bool* wait_for_ready, gpr_timespec* timeout,
int32_t* max_request_message_bytes, int32_t* max_response_message_bytes) {
grpc_method_config* config = gpr_malloc(sizeof(*config));
memset(config, 0, sizeof(*config));
gpr_ref_init(&config->refs, 1);
if (wait_for_ready != NULL) {
config->wait_for_ready = gpr_malloc(sizeof(*wait_for_ready));
*config->wait_for_ready = *wait_for_ready;
}
if (timeout != NULL) {
config->timeout = gpr_malloc(sizeof(*timeout));
*config->timeout = *timeout;
}
if (max_request_message_bytes != NULL) {
config->max_request_message_bytes =
gpr_malloc(sizeof(*max_request_message_bytes));
*config->max_request_message_bytes = *max_request_message_bytes;
}
if (max_response_message_bytes != NULL) {
config->max_response_message_bytes =
gpr_malloc(sizeof(*max_response_message_bytes));
*config->max_response_message_bytes = *max_response_message_bytes;
}
return config;
}
grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config) {
gpr_ref(&method_config->refs);
return method_config;
}
void grpc_method_config_unref(grpc_method_config* method_config) {
if (gpr_unref(&method_config->refs)) {
gpr_free(method_config->wait_for_ready);
gpr_free(method_config->timeout);
gpr_free(method_config->max_request_message_bytes);
gpr_free(method_config->max_response_message_bytes);
gpr_free(method_config);
}
}
bool* grpc_method_config_get_wait_for_ready(grpc_method_config* method_config) {
return method_config->wait_for_ready;
}
gpr_timespec* grpc_method_config_get_timeout(
grpc_method_config* method_config) {
return method_config->timeout;
}
int32_t* grpc_method_config_get_max_request_message_bytes(
grpc_method_config* method_config) {
return method_config->max_request_message_bytes;
}
int32_t* grpc_method_config_get_max_response_message_bytes(
grpc_method_config* method_config) {
return method_config->max_response_message_bytes;
}
//
// grpc_method_config_table
//
typedef struct grpc_method_config_table_entry {
grpc_mdstr* path;
grpc_method_config* method_config;
} grpc_method_config_table_entry;
#define METHOD_CONFIG_TABLE_SIZE 128
struct grpc_method_config_table {
gpr_refcount refs;
grpc_method_config_table_entry entries[METHOD_CONFIG_TABLE_SIZE];
};
grpc_method_config_table* grpc_method_config_table_create() {
grpc_method_config_table* table = gpr_malloc(sizeof(*table));
memset(table, 0, sizeof(*table));
gpr_ref_init(&table->refs, 1);
return table;
}
grpc_method_config_table* grpc_method_config_table_ref(
grpc_method_config_table* table) {
if (table != NULL) gpr_ref(&table->refs);
return table;
}
void grpc_method_config_table_unref(grpc_method_config_table* table) {
if (table != NULL && gpr_unref(&table->refs)) {
for (size_t i = 0; i < GPR_ARRAY_SIZE(table->entries); ++i) {
grpc_method_config_table_entry* entry = &table->entries[i];
if (entry->path != NULL) {
GRPC_MDSTR_UNREF(entry->path);
grpc_method_config_unref(entry->method_config);
}
}
}
}
// Helper function for insert and get operations that performs quadratic
// probing (https://en.wikipedia.org/wiki/Quadratic_probing).
static size_t grpc_method_config_table_find_index(
grpc_method_config_table* table, grpc_mdstr* path, bool find_empty) {
for (size_t i = 0; i < GPR_ARRAY_SIZE(table->entries); ++i) {
const size_t idx = (path->hash + i * i) % GPR_ARRAY_SIZE(table->entries);
if (table->entries[idx].path == NULL)
return find_empty ? idx : GPR_ARRAY_SIZE(table->entries);
if (table->entries[idx].path == path) return idx;
}
return GPR_ARRAY_SIZE(table->entries) + 1; // Not found.
}
static void grpc_method_config_table_insert(grpc_method_config_table* table,
grpc_mdstr* path,
grpc_method_config* config) {
const size_t idx =
grpc_method_config_table_find_index(table, path, true /* find_empty */);
// This can happen if the table is full.
GPR_ASSERT(idx != GPR_ARRAY_SIZE(table->entries));
grpc_method_config_table_entry* entry = &table->entries[idx];
entry->path = GRPC_MDSTR_REF(path);
entry->method_config = grpc_method_config_ref(config);
}
static grpc_method_config* grpc_method_config_table_get(
grpc_method_config_table* table, grpc_mdstr* path) {
const size_t idx =
grpc_method_config_table_find_index(table, path, false /* find_empty */);
if (idx == GPR_ARRAY_SIZE(table->entries)) return NULL; // Not found.
return table->entries[idx].method_config;
}
void grpc_method_config_table_add_method_config(
grpc_method_config_table* table, grpc_mdstr** paths, size_t num_paths,
grpc_method_config* method_config) {
for (size_t i = 0; i < num_paths; ++i) {
grpc_method_config_table_insert(table, paths[i], method_config);
}
}
grpc_method_config* grpc_method_config_table_get_method_config(
grpc_method_config_table* table, grpc_mdstr* path) {
grpc_method_config* method_config = grpc_method_config_table_get(table, path);
// If we didn't find a match for the path, try looking for a wildcard
// entry (i.e., change "/service/method" to "/service/*").
if (method_config == NULL) {
const char* path_str = grpc_mdstr_as_c_string(path);
const char* sep = strrchr(path_str, '/') + 1;
const size_t len = (size_t)(sep - path_str);
char buf[len + 2]; // '*' and NUL
memcpy(buf, path_str, len);
buf[len] = '*';
buf[len + 1] = '\0';
grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf);
method_config = grpc_method_config_table_get(table, wildcard_path);
GRPC_MDSTR_UNREF(wildcard_path);
}
return grpc_method_config_ref(method_config);
}

@ -0,0 +1,85 @@
//
// Copyright 2016, Google Inc.
// 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 Google Inc. 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 GRPC_CORE_EXT_CLIENT_CONFIG_METHOD_CONFIG_H
#define GRPC_CORE_EXT_CLIENT_CONFIG_METHOD_CONFIG_H
#include <stdbool.h>
#include <grpc/impl/codegen/gpr_types.h>
#include "src/core/lib/transport/metadata.h"
/// Per-method configuration.
typedef struct grpc_method_config grpc_method_config;
/// Any parameter may be NULL to indicate that the value is unset.
grpc_method_config* grpc_method_config_create(
bool* wait_for_ready, gpr_timespec* timeout,
int32_t* max_request_message_bytes, int32_t* max_response_message_bytes);
grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config);
void grpc_method_config_unref(grpc_method_config* method_config);
/// These methods return NULL if the requested field is unset.
/// The caller does NOT take ownership of the result.
bool* grpc_method_config_get_wait_for_ready(grpc_method_config* method_config);
gpr_timespec* grpc_method_config_get_timeout(grpc_method_config* method_config);
int32_t* grpc_method_config_get_max_request_message_bytes(
grpc_method_config* method_config);
int32_t* grpc_method_config_get_max_response_message_bytes(
grpc_method_config* method_config);
/// A table of method configs.
typedef struct grpc_method_config_table grpc_method_config_table;
grpc_method_config_table* grpc_method_config_table_create();
grpc_method_config_table* grpc_method_config_table_ref(
grpc_method_config_table* table);
void grpc_method_config_table_unref(grpc_method_config_table* table);
/// Adds \a method_config to \a table. \a paths indicates the set of path
/// names for which this config applies. Each name is of one of the
/// following forms:
/// service/method -- specifies exact service and method name
/// service/* -- matches all methods for the specified service
/// Takes new references to all elements of \a paths and to \a method_config.
void grpc_method_config_table_add_method_config(
grpc_method_config_table* table, grpc_mdstr** paths, size_t num_paths,
grpc_method_config* method_config);
/// Returns NULL if the method has no config.
/// Caller owns a reference to result.
grpc_method_config* grpc_method_config_table_get_method_config(
grpc_method_config_table* table, grpc_mdstr* path);
#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_METHOD_CONFIG_H */
Loading…
Cancel
Save