Skip to content

Commit

Permalink
add a simple set data structure
Browse files Browse the repository at this point in the history
We work with a few sets, so add a data structure for it to avoid
ad-hoc implementations in other modules.  This is simplify a list
as the sets we're working with tends to be quite small: typically
less than 10.  As long as we don't need to support more, the perf
should be good enough.
  • Loading branch information
vapier committed May 21, 2019
1 parent c2303e6 commit ccdacdd
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/module.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ SRC-tmpfiles := \
main.c \

SRC-libtmpfiles.so := \
set.c \

all: tmpfiles
tmpfiles: $(SRC-libtmpfiles.so:.c=.o) $(SRC-tmpfiles:.c=.o)
Expand Down
43 changes: 43 additions & 0 deletions src/set.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2017-2019 Gentoo Foundation
* Copyright 2017-2019 The Chromium OS Authors
* Released under the 2-clause BSD license.
*/

#include "tmpfiles.h"

void ordered_set_init(ordered_set_t *set)
{
set->reserved = 16;
set->count = 0;
set->elements = xmalloc(sizeof(*set->elements) * set->reserved);
}

void ordered_set_add(ordered_set_t *set, const char *element)
{
if (set->count == set->reserved) {
set->reserved *= 2;
set->elements = xrealloc(set->elements, sizeof(*set->elements) * set->reserved);
}

set->elements[set->count] = xstrdup(element);
set->count++;
}

bool ordered_set_exists(ordered_set_t *set, const char *element)
{
for (size_t i = 0; i < set->count; ++i)
if (strcmp(set->elements[i], element) == 0)
return true;

return false;
}

void ordered_set_free(ordered_set_t *set)
{
for (size_t i = 0; i < set->count; ++i)
free(set->elements[i]);

free(set->elements);
set->elements = NULL;
}
36 changes: 36 additions & 0 deletions src/set.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2017-2019 Gentoo Foundation
* Copyright 2017-2019 The Chromium OS Authors
* Released under the 2-clause BSD license.
*/

#ifndef TMPFILES_SET_H
#define TMPFILES_SET_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
char **elements;
size_t reserved;
size_t count;
} ordered_set_t;

/* Initialize a set. Its storage should be declared already. */
extern void ordered_set_init(ordered_set_t *set);

/* Add a string to the set. The string is duplicated. */
extern void ordered_set_add(ordered_set_t *set, const char *element);

/* Test whether the string is in the set. */
extern bool ordered_set_exists(ordered_set_t *set, const char *element);

/* Clear a set. Must call ordered_set_init before using again. */
extern void ordered_set_free(ordered_set_t *set);

#ifdef __cplusplus
}
#endif

#endif
1 change: 1 addition & 0 deletions src/tmpfiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
#include "headers.h"

#include "xfuncs.h"
#include "set.h"

#endif
1 change: 1 addition & 0 deletions test/module.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
LDFLAGS-tmpfiles_test = -pthread
LDLIBS-tmpfiles_test = -lgtest
SRC-tmpfiles_test := \
set_test.cc \
xfuncs_test.cc \

OBJ-tmpfiles_test := $(SRC-tmpfiles_test:.cc=.o)
Expand Down
32 changes: 32 additions & 0 deletions test/set_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2017-2019 Gentoo Foundation
* Copyright 2017-2019 The Chromium OS Authors
* Released under the 2-clause BSD license.
*/

/* Tests for the set module. */

#include "test.h"

/* Make sure we can reinit things. */
TEST(Set, Reinit) {
ordered_set_t set;
ordered_set_init(&set);
ordered_set_free(&set);
ordered_set_init(&set);
ordered_set_free(&set);
ordered_set_init(&set);
ordered_set_free(&set);
}

/* Smoke test for the API. */
TEST(Set, Smoke) {
ordered_set_t set;
ordered_set_init(&set);
ASSERT_FALSE(ordered_set_exists(&set, "foo"));
ASSERT_FALSE(ordered_set_exists(&set, "bar"));
ordered_set_add(&set, "foo");
ASSERT_TRUE(ordered_set_exists(&set, "foo"));
ASSERT_FALSE(ordered_set_exists(&set, "bar"));
ordered_set_free(&set);
}

0 comments on commit ccdacdd

Please sign in to comment.