Plan 9 from Bell Labs’s /usr/web/sources/contrib/de0u/root/sys/src/cmd/divergefs/dictionary.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.



#include <u.h>
#include <libc.h>
#include "common.h"
#include "debug.h"
#include "collection.h"
#include "function.h"
#include "array.h"
#include "set.h"
#include "dictionary.h"


enum { DEBUG_PAIR = false };

struct Dictionary
{
  collectionhash hash;
  collectionisequal isequal;
  Set *elements;
};

typedef struct Pair
{
  void *key;
  void *value;
  Dictionary *container;
} Pair;

Pair *pair_new(void *key, void *value, Dictionary *container)
{
  Pair *result = (Pair *)emalloc_fs(sizeof(Pair));
  result->key = key;
  result->value = value;
  result->container = container;
  return result;
}

uint pair_hash(void *p)
{
  Pair *self = (Pair *)p;
  return self->container->hash(self->key);
}

bool pair_isequal(void *p1, void *p2)
{
  Pair *self = (Pair *)p1;
  Pair *object = (Pair *)p2;
  return self->container->isequal(self->key, object->key);
}


enum { DEBUG_DICTIONARY = false };

Dictionary *dictionary_new(collectionisequal isequal, collectionhash hash)
{
  Dictionary *result = (Dictionary *)emalloc_fs(sizeof(Dictionary));
  result->hash = hash;
  result->isequal = isequal;
  result->elements = set_new(pair_isequal, pair_hash);
  return result;
}

void dictionary_free(Dictionary *self)
{
  if(self == nil)
  {
    return;
  }

  set_free_with(self->elements, free);
  free(self);
}


typedef struct DictionaryFreeWithData
{
  functionunary free_key;
  functionunary free_value;
} DictionaryFreeWithData;

collection_do_ret dictionary_free_with_each(void *p, void *arg)
{
  Pair *pair = (Pair *)p;
  DictionaryFreeWithData *data = (DictionaryFreeWithData *)arg;
  if(data->free_key != nil)
  {
    data->free_key(pair->key);
  }

  if(data->free_value != nil)
  {
    data->free_value(pair->value);
  }
  return COLLECTION_DO_CONTINUE;
}

void dictionary_free_with(Dictionary *self, 
  functionunary free_key, functionunary free_value)
{
  DictionaryFreeWithData data = (DictionaryFreeWithData) {free_key, free_value};
  set_do(self->elements, dictionary_free_with_each, &data);
  dictionary_free(self);
}

uint dictionary_size(Dictionary *self)
{
  return set_size(self->elements);
}

bool dictionary_add(Dictionary *self, void *key, void *value)
{
  Pair temp = (Pair) {key, value, self};
  Pair *item = &temp;
  assert_valid(self);

  if(set_find(self->elements, &item))
  {
    item->value = value;
    return false;
  }

  item = pair_new(key, value, self);
  set_add(self->elements, item);
  return true;
}

bool dictionary_remove(Dictionary *self, void *key)
{
  Pair p = (Pair) {key, nil, self};
  assert_valid(self);
  return set_remove(self->elements, &p);
}

void *dictionary_at(Dictionary *self, void *key)
{
  bool result;
  void *value;
  assert_valid(self);

  result = dictionary_get_key_value(self, &key, &value);
  assert(result);
  return value;
}

bool dictionary_get_key_value(Dictionary *self, void **key, void **value)
{
  Pair p = (Pair) {nil, nil, self};
  Pair *result = &p;
  assert_valid(key);
  assert_valid(self);

  result->key = *key;
  if(!set_find(self->elements, &result))
  {
    return false;
  }

  *key = result->key;
  if(value != nil)
  {
    *value = result->value;
  }
  return true;
}

bool dictionary_get(Dictionary *self, void *key, void **value)
{
  return dictionary_get_key_value(self, &key, value);
}

bool dictionary_includes(Dictionary *self, void *key)
{
  return dictionary_get(self, key, nil);
}




Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.