Example #1
0
grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *buf,
                                   size_t length) {
  gpr_uint32 hash = gpr_murmur_hash3(buf, length, ctx->hash_seed);
  internal_string *s;

  lock(ctx);

  /* search for an existing string */
  for (s = ctx->strtab[hash % ctx->strtab_capacity]; s; s = s->bucket_next) {
    if (s->hash == hash && GPR_SLICE_LENGTH(s->slice) == length &&
        0 == memcmp(buf, GPR_SLICE_START_PTR(s->slice), length)) {
      internal_string_ref(s);
      unlock(ctx);
      return (grpc_mdstr *)s;
    }
  }

  /* not found: create a new string */
  if (length + 1 < GPR_SLICE_INLINED_SIZE) {
    /* string data goes directly into the slice */
    s = gpr_malloc(sizeof(internal_string));
    s->refs = 1;
    s->slice.refcount = NULL;
    memcpy(s->slice.data.inlined.bytes, buf, length);
    s->slice.data.inlined.bytes[length] = 0;
    s->slice.data.inlined.length = length;
  } else {
    /* string data goes after the internal_string header, and we +1 for null
       terminator */
    s = gpr_malloc(sizeof(internal_string) + length + 1);
    s->refs = 1;
    s->refcount.ref = slice_ref;
    s->refcount.unref = slice_unref;
    s->slice.refcount = &s->refcount;
    s->slice.data.refcounted.bytes = (gpr_uint8 *)(s + 1);
    s->slice.data.refcounted.length = length;
    memcpy(s->slice.data.refcounted.bytes, buf, length);
    /* add a null terminator for cheap c string conversion when desired */
    s->slice.data.refcounted.bytes[length] = 0;
  }
  s->has_base64_and_huffman_encoded = 0;
  s->hash = hash;
  s->context = ctx;
  s->bucket_next = ctx->strtab[hash % ctx->strtab_capacity];
  ctx->strtab[hash % ctx->strtab_capacity] = s;

  ctx->strtab_count++;

  if (ctx->strtab_count > ctx->strtab_capacity * 2) {
    grow_strtab(ctx);
  }

  unlock(ctx);

  return (grpc_mdstr *)s;
}
Example #2
0
void grpc_mdctx_global_init(void) {
  size_t i, j;
  if (!g_forced_hash_seed) {
    g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
  }
  g_static_strtab_maxprobe = 0;
  g_static_mdtab_maxprobe = 0;
  /* build static tables */
  memset(g_static_mdtab, 0, sizeof(g_static_mdtab));
  memset(g_static_strtab, 0, sizeof(g_static_strtab));
  for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
    grpc_mdstr *elem = &grpc_static_mdstr_table[i];
    const char *str = grpc_static_metadata_strings[i];
    uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed);
    *(gpr_slice *)&elem->slice = gpr_slice_from_static_string(str);
    *(uint32_t *)&elem->hash = hash;
    for (j = 0;; j++) {
      size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_strtab);
      if (g_static_strtab[idx] == NULL) {
        g_static_strtab[idx] = &grpc_static_mdstr_table[i];
        break;
      }
    }
    if (j > g_static_strtab_maxprobe) {
      g_static_strtab_maxprobe = j;
    }
  }
  for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) {
    grpc_mdelem *elem = &grpc_static_mdelem_table[i];
    grpc_mdstr *key =
        &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]];
    grpc_mdstr *value =
        &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]];
    uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash);
    *(grpc_mdstr **)&elem->key = key;
    *(grpc_mdstr **)&elem->value = value;
    for (j = 0;; j++) {
      size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab);
      if (g_static_mdtab[idx] == NULL) {
        g_static_mdtab[idx] = elem;
        break;
      }
    }
    if (j > g_static_mdtab_maxprobe) {
      g_static_mdtab_maxprobe = j;
    }
  }
  /* initialize shards */
  for (i = 0; i < STRTAB_SHARD_COUNT; i++) {
    strtab_shard *shard = &g_strtab_shard[i];
    gpr_mu_init(&shard->mu);
    shard->count = 0;
    shard->capacity = INITIAL_STRTAB_CAPACITY;
    shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity);
    memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity);
  }
  for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
    mdtab_shard *shard = &g_mdtab_shard[i];
    gpr_mu_init(&shard->mu);
    shard->count = 0;
    gpr_atm_no_barrier_store(&shard->free_estimate, 0);
    shard->capacity = INITIAL_MDTAB_CAPACITY;
    shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity);
    memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity);
  }
}
Example #3
0
static uint64_t hash64(const void *k) {
  size_t len = strlen(k);
  uint64_t higher = gpr_murmur_hash3((const char *)k, len / 2, 0);
  return higher << 32 |
         gpr_murmur_hash3((const char *)(k) + len / 2, len - len / 2, 0);
}
Example #4
0
static void assert_passthrough(grpc_slice value,
                               grpc_compression_algorithm algorithm,
                               grpc_slice_split_mode uncompressed_split_mode,
                               grpc_slice_split_mode compressed_split_mode,
                               compressability compress_result_check) {
  grpc_slice_buffer input;
  grpc_slice_buffer compressed_raw;
  grpc_slice_buffer compressed;
  grpc_slice_buffer output;
  grpc_slice final;
  int was_compressed;
  char *algorithm_name;

  GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algorithm_name) != 0);
  gpr_log(
      GPR_INFO, "assert_passthrough: value_length=%" PRIuPTR
                " value_hash=0x%08x "
                "algorithm='%s' uncompressed_split='%s' compressed_split='%s'",
      GRPC_SLICE_LENGTH(value), gpr_murmur_hash3(GRPC_SLICE_START_PTR(value),
                                                 GRPC_SLICE_LENGTH(value), 0),
      algorithm_name, grpc_slice_split_mode_name(uncompressed_split_mode),
      grpc_slice_split_mode_name(compressed_split_mode));

  grpc_slice_buffer_init(&input);
  grpc_slice_buffer_init(&compressed_raw);
  grpc_slice_buffer_init(&compressed);
  grpc_slice_buffer_init(&output);

  grpc_split_slices_to_buffer(uncompressed_split_mode, &value, 1, &input);

  {
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    was_compressed =
        grpc_msg_compress(&exec_ctx, algorithm, &input, &compressed_raw);
    grpc_exec_ctx_finish(&exec_ctx);
  }
  GPR_ASSERT(input.count > 0);

  switch (compress_result_check) {
    case SHOULD_NOT_COMPRESS:
      GPR_ASSERT(was_compressed == 0);
      break;
    case SHOULD_COMPRESS:
      GPR_ASSERT(was_compressed == 1);
      break;
    case MAYBE_COMPRESSES:
      /* no check */
      break;
  }

  grpc_split_slice_buffer(compressed_split_mode, &compressed_raw, &compressed);

  {
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    GPR_ASSERT(grpc_msg_decompress(
        &exec_ctx, was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed,
        &output));
    grpc_exec_ctx_finish(&exec_ctx);
  }

  final = grpc_slice_merge(output.slices, output.count);
Example #5
0
/* TODO(hongyu): replace it with cityhash64 */
static gpr_uint64 simple_hash(const void* k) {
  size_t len = strlen(k);
  gpr_uint64 higher = gpr_murmur_hash3((const char*)k, len / 2, 0);
  return higher << 32 |
         gpr_murmur_hash3((const char*)k + len / 2, len - len / 2, 0);
}
Example #6
0
uint32_t grpc_slice_default_hash_impl(grpc_slice s) {
  return gpr_murmur_hash3(GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s),
                          g_hash_seed);
}