/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ufdt_prop_dict.h"

#include "libfdt.h"

#include "libufdt_sysdeps.h"

#define UFDT_PROP_DICT_INIT_SZ 4

/* Empirical values for hash functions. */
#define HASH_BASE 13131

#define DICT_LIMIT_NUM 2
#define DICT_LIMIT_DEN 3

static int _ufdt_prop_dict_str_hash(const char *str) {
  unsigned int res = 0;

  for (; *str != '\0'; str++) {
    res *= HASH_BASE;
    res += *str;
  }

  return (int)res;
}

static const struct fdt_property **_ufdt_prop_dict_find_index_by_name(
    const struct ufdt_prop_dict *dict, const char *name) {
  /* size should be 2^k for some k */
  int hash = _ufdt_prop_dict_str_hash(name);
  int size = dict->mem_size;
  int idx = hash & (size - 1);
  /* If collision, use linear probing to find idx in the hash table */
  for (int i = 0; i < size; i++) {
    const struct fdt_property **prop_ptr = &dict->props[idx];
    const struct fdt_property *prop = *prop_ptr;
    if (prop == NULL) return prop_ptr;

    const char *prop_name = fdt_string(dict->fdtp, fdt32_to_cpu(prop->nameoff));
    if (prop_name != NULL && dto_strcmp(prop_name, name) == 0) return prop_ptr;

    idx = (idx + 1) & (size - 1);
  }
  return NULL;
}

static const struct fdt_property **_ufdt_prop_dict_find_index(
    struct ufdt_prop_dict *dict, const struct fdt_property *prop) {
  const char *name = fdt_string(dict->fdtp, fdt32_to_cpu(prop->nameoff));
  if (name == NULL) return NULL;

  return _ufdt_prop_dict_find_index_by_name(dict, name);
}

int _ufdt_prop_dict_construct_int(struct ufdt_prop_dict *dict, void *fdtp,
                                  int size) {
  const size_t entry_size = sizeof(const struct fdt_property *);
  const struct fdt_property **props =
      (const struct fdt_property **)dto_malloc(size * entry_size);
  if (props == NULL) return -1;
  dto_memset(props, 0, size * entry_size);

  dict->mem_size = size;
  dict->num_used = 0;
  dict->fdtp = fdtp;
  dict->props = props;

  return 0;
}

int ufdt_prop_dict_construct(struct ufdt_prop_dict *dict, void *fdtp) {
  return _ufdt_prop_dict_construct_int(dict, fdtp, UFDT_PROP_DICT_INIT_SZ);
}

void ufdt_prop_dict_destruct(struct ufdt_prop_dict *dict) {
  if (dict == NULL) return;

  dto_free(dict->props);
}

static int _ufdt_prop_dict_enlarge_if_needed(struct ufdt_prop_dict *dict) {
  if (dict == NULL) return -1;

  /* Enlarge if the used number over than DICT_LIMIT_NUM / DICT_LIMIT_DEN */
  if (dict->num_used * DICT_LIMIT_DEN <= dict->mem_size * DICT_LIMIT_NUM) {
    return 0;
  }

  int new_size = dict->mem_size * 2;
  struct ufdt_prop_dict temp_dict;
  _ufdt_prop_dict_construct_int(&temp_dict, dict->fdtp, new_size);

  for (int i = 0; i < dict->mem_size; i++) {
    const struct fdt_property *prop = dict->props[i];
    if (prop == NULL) continue;
    const struct fdt_property **new_prop_ptr =
        _ufdt_prop_dict_find_index(&temp_dict, prop);
    if (new_prop_ptr == NULL) {
      dto_error("ufdt_prop_dict: failed to find new index when enlarging.\n");
      ufdt_prop_dict_destruct(&temp_dict);
      return -1;
    }
    *new_prop_ptr = prop;
  }

  dto_free(dict->props);

  dict->mem_size = new_size;
  dict->props = temp_dict.props;

  return 0;
}

int ufdt_prop_dict_add(struct ufdt_prop_dict *dict,
                       const struct fdt_property *prop) {
  const struct fdt_property **prop_ptr = _ufdt_prop_dict_find_index(dict, prop);
  if (prop_ptr == NULL) {
    dto_error("ufdt_prop_dict: failed to find new index when adding.\n");
    return -1;
  }

  if (*prop_ptr == NULL) dict->num_used++;
  *prop_ptr = prop;

  return _ufdt_prop_dict_enlarge_if_needed(dict);
}

const struct fdt_property *ufdt_prop_dict_find(const struct ufdt_prop_dict *dict,
                                               const char *name) {
  const struct fdt_property **prop_ptr =
      _ufdt_prop_dict_find_index_by_name(dict, name);
  return prop_ptr ? *prop_ptr : NULL;
}
