Skip to content
Snippets Groups Projects
Commit 4445aaa3 authored by Jonathan Schöbel's avatar Jonathan Schöbel
Browse files

Validator: ordered tags

As the access must be fast, the tags are sorted when inserted, so that
the search can take place in log-time.
parent ed8b399c
No related branches found
No related tags found
No related merge requests found
......@@ -60,7 +60,7 @@ FILE_NAME_27=900;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fpr
FILE_NAME_28=1867;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext_mark_static.c;0;8
FILE_NAME_29=1798;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.c;0;8
FILE_NAME_30=24;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.h;0;8
FILE_NAME_31=10810;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.c;0;8
FILE_NAME_31=6351;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.c;0;8
FILE_NAME_32=1148;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.h;0;8
FILE_NAME_33=924;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fstatus.h;0;8
FILE_NAME_34=18;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Flog.h;0;4
......@@ -76,7 +76,7 @@ FILE_NAME_43=5714;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp
FILE_NAME_44=24;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_attr.c;0;8
FILE_NAME_45=4221;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
FILE_NAME_46=994;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text_mark.c;0;8
FILE_NAME_47=6893;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
FILE_NAME_47=3101;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
FILE_NAME_48=536;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
FILE_NAME_49=201;YAML;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitlab-ci.yml;0;4
FILE_NAME_50=71;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Fupload.sh.in;0;8
......
......@@ -82,10 +82,18 @@ free_tags (/*@special@*/ struct SH_Validator * validator)
/*@modifies validator->tags@*/
/*@releases validator->tags@*/;
static inline
bool
find_tag (const struct SH_Validator * validator,
const char * tag,
/*@out@*/ size_t * index)
/*@modifies index@*/;
static inline
Tag
add_tag (struct SH_Validator * validator,
const char * tag,
size_t index,
/*@null@*/ /*@out@*/ struct SH_Status * status)
/*@modifies validator->tags@*/
/*@modifies validator->tag_n@*/
......@@ -119,8 +127,9 @@ get_tag_name_by_id (const struct SH_Validator * validator, Tag id,
static inline
Tag
get_tag_id_by_name (const struct SH_Validator * validator,
const char * name)
/*@*/;
const char * name,
/*@out@*/ size_t * index)
/*@modifies index@*/;
static inline
bool
......@@ -242,10 +251,51 @@ free_tags (/*@special@*/ struct SH_Validator * validator)
return;
}
static inline
bool
find_tag (const struct SH_Validator * validator,
const char * tag,
/*@out@*/ size_t * index)
/*@modifies index@*/
{
size_t start;
size_t end;
size_t pivot;
start = 0;
end = validator->tag_n;
pivot = (end - start) / 2;
while (start != end)
{
int cmp = strcmp (tag, validator->tags[pivot].name);
if (0 > cmp)
{
end = pivot;
pivot = (pivot - start) / 2 + start;
}
else if (0 == cmp)
{
*index = pivot;
return TRUE;
}
else
{
start = pivot + 1;
pivot = (end - pivot) / 2 + pivot;
}
}
*index = start;
return FALSE;
}
static inline
Tag
add_tag (struct SH_Validator * validator,
const char * tag,
size_t index,
/*@null@*/ /*@out@*/ struct SH_Status * status)
/*@modifies validator->tags@*/
/*@modifies validator->tag_n@*/
......@@ -255,7 +305,7 @@ add_tag (struct SH_Validator * validator,
/*@modifies status@*/
{
Tag tag_id;
size_t index;
char * name;
struct tag_info * new_tags;
/* abort on overflow:
......@@ -292,18 +342,23 @@ add_tag (struct SH_Validator * validator,
}
validator->tags = new_tags;
index = validator->tag_n;
tag_id = NEXT_TAG (validator->last_tag);
validator->tags[index].id = tag_id;
validator->tags[index].name = strdup (tag);
if (NULL == validator->tags[index].name)
name = strdup (tag);
if (NULL == name)
{
set_status (status, E_ALLOC, 4, "strdup failed");
return TAG_ERR;
}
for (size_t index2 = validator->tag_n; index2 > index; index2--)
{
validator->tags[index2] = validator->tags[index2-1];
}
validator->tags[index].id = tag_id;
validator->tags[index].name = name;
/* commit changes */
validator->tag_n++;
validator->last_tag = tag_id;
......@@ -337,16 +392,7 @@ is_tag_name (const struct SH_Validator * validator, const char * name)
/*@*/
{
size_t index;
for (index = 0; index < validator->tag_n; index++)
{
if (0 == strcmp (name, validator->tags[index].name))
{
return TRUE;
}
}
return FALSE;
return find_tag (validator, name, &index);
}
/*@unused@*/
......@@ -385,20 +431,16 @@ get_tag_name_by_id (const struct SH_Validator * validator, Tag id,
static inline
Tag
get_tag_id_by_name (const struct SH_Validator * validator,
const char * name)
/*@*/
const char * name,
/*@out@*/ size_t * index)
/*@modifies index@*/
{
size_t index;
for (index = 0; index < validator->tag_n; index++)
if (!find_tag (validator, name, index))
{
if (0 == strcmp (name, validator->tags[index].name))
{
return validator->tags[index].id;
}
return TAG_ERR;
}
return TAG_ERR;
return validator->tags[*index].id;
}
static inline
......@@ -487,17 +529,18 @@ SH_Validator_register_tag (struct SH_Validator * validator,
/*@modifies fileSystem@*/
/*@modifies status@*/
{
size_t index;
Tag tag_id;
/* tag already registered */
tag_id = get_tag_id_by_name (validator, tag);
tag_id = get_tag_id_by_name (validator, tag, &index);
if (tag_id != TAG_ERR)
{
set_success (status);
return tag_id;
}
return add_tag (validator, tag, status);
return add_tag (validator, tag, index, status);
}
bool
......
......@@ -77,6 +77,9 @@ START_TEST(test_validator_tag_register_no_status)
struct SH_Validator * validator;
const char * tag1 = "html";
const char * tag2 = "head";
const char * tag3 = "article";
const char * tag4 = "p";
const char * tag5 = "img";
char * tagN;
Tag tag;
Tag tag_;
......@@ -105,6 +108,23 @@ START_TEST(test_validator_tag_register_no_status)
ck_assert_int_eq (validator->tags[0].id, tag);
ck_assert_str_eq (validator->tags[0].name, tag1);
/* test - order */
tag = SH_Validator_register_tag (validator, tag3, NULL);
ck_assert_int_eq (tag, 2);
tag = SH_Validator_register_tag (validator, tag4, NULL);
ck_assert_int_eq (tag, 3);
tag = SH_Validator_register_tag (validator, tag5, NULL);
ck_assert_int_eq (tag, 4);
ck_assert_int_eq (validator->tag_n, 4);
ck_assert_str_eq (validator->tags[0].name, tag3);
ck_assert_str_eq (validator->tags[1].name, tag1);
ck_assert_str_eq (validator->tags[2].name, tag5);
ck_assert_str_eq (validator->tags[3].name, tag4);
/* test - overflow detection */
/* make method fail by filling with garbage until
* upper boundary is reached */
......@@ -154,6 +174,9 @@ START_TEST(test_validator_tag_register_with_status)
struct SH_Validator * validator;
const char * tag1 = "html";
const char * tag2 = "head";
const char * tag3 = "article";
const char * tag4 = "p";
const char * tag5 = "img";
char * tagN;
Tag tag;
Tag tag_;
......@@ -186,6 +209,29 @@ START_TEST(test_validator_tag_register_with_status)
ck_assert_int_eq (validator->tags[0].id, tag);
ck_assert_str_eq (validator->tags[0].name, tag1);
/* test - order */
_status_preinit (status);
tag = SH_Validator_register_tag (validator, tag3, &status);
ck_assert_int_eq (tag, 2);
ck_assert_int_eq (status.status, SUCCESS);
_status_preinit (status);
tag = SH_Validator_register_tag (validator, tag4, &status);
ck_assert_int_eq (tag, 3);
ck_assert_int_eq (status.status, SUCCESS);
_status_preinit (status);
tag = SH_Validator_register_tag (validator, tag5, &status);
ck_assert_int_eq (tag, 4);
ck_assert_int_eq (status.status, SUCCESS);
ck_assert_int_eq (validator->tag_n, 4);
ck_assert_str_eq (validator->tags[0].name, tag3);
ck_assert_str_eq (validator->tags[1].name, tag1);
ck_assert_str_eq (validator->tags[2].name, tag5);
ck_assert_str_eq (validator->tags[3].name, tag4);
/* test - overflow detection */
/* make method fail by filling with garbage until
* upper boundary is reached */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment