* eet: reduce memory used by Eet dictionary.

SVN revision: 55016
This commit is contained in:
Cedric BAIL 2010-11-26 14:40:53 +00:00
parent 5c9cb60854
commit a453783e68
4 changed files with 120 additions and 72 deletions

View File

@ -457,3 +457,8 @@
2010-11-25 Cedric BAIL
* Add EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING.
2010-11-26 Cedric BAIL
* Reduce memory used by Eet dictionary.

View File

@ -7,18 +7,30 @@ typedef enum _Eet_Convert_Type Eet_Convert_Type;
enum _Eet_Convert_Type
{
EET_D_NOT_CONVERTED = 0,
EET_D_NOTHING = 0,
EET_D_FLOAT = 1 << 1,
EET_D_DOUBLE = 1 << 2,
EET_D_FIXED_POINT = 1 << 4
};
typedef struct _Eet_String Eet_String;
typedef struct _Eet_Convert Eet_Convert;
struct _Eet_Convert
{
float f;
double d;
Eina_F32p32 fp;
Eet_Convert_Type type;
};
struct _Eet_String
{
const char *mmap;
char *str;
union {
const char *mmap;
char *str;
} u;
int hash;
int len;
@ -26,15 +38,12 @@ struct _Eet_String
int next;
int prev;
float f;
double d;
Eina_F32p32 fp;
Eet_Convert_Type type;
unsigned char allocated : 1;
};
struct _Eet_Dictionary
{
Eet_String *all;
Eina_Hash *converts;
int size;
int offset;

View File

@ -33,11 +33,13 @@ eet_dictionary_free(Eet_Dictionary *ed)
int i;
for (i = 0; i < ed->count; ++i)
if (ed->all[i].str)
free(ed->all[i].str);
if (ed->all[i].allocated)
free(ed->all[i].u.str);
if (ed->all)
free(ed->all);
free(ed->all);
if (ed->converts) eina_hash_free(ed->converts);
free(ed);
}
@ -59,15 +61,16 @@ _eet_dictionary_lookup(Eet_Dictionary *ed,
{
if (ed->all[current].len == len)
{
if (ed->all[current].str)
if (strcmp(ed->all[current].str, string) == 0)
{
found = EINA_TRUE;
break;
}
if (ed->all[current].mmap)
if (strcmp(ed->all[current].mmap, string) == 0)
if (ed->all[current].allocated)
{
if (strcmp(ed->all[current].u.str, string) == 0)
{
found = EINA_TRUE;
break;
}
}
else if (ed->all[current].u.mmap
&& strcmp(ed->all[current].u.mmap, string) == 0)
{
found = EINA_TRUE;
break;
@ -104,13 +107,13 @@ eet_dictionary_string_add(Eet_Dictionary *ed,
if (idx != -1)
{
if (ed->all[idx].str)
if (strcmp(ed->all[idx].str, string) == 0)
return idx;
if (ed->all[idx].mmap)
if (strcmp(ed->all[idx].mmap, string) == 0)
return idx;
if (ed->all[idx].allocated)
{
if (strcmp(ed->all[idx].u.str, string) == 0)
return idx;
}
else if (ed->all[idx].u.mmap && strcmp(ed->all[idx].u.mmap, string) == 0)
return idx;
}
if (ed->total == ed->count)
@ -134,13 +137,12 @@ eet_dictionary_string_add(Eet_Dictionary *ed,
current = ed->all + ed->count;
current->type = EET_D_NOT_CONVERTED;
current->allocated = EINA_TRUE;
current->hash = hash;
current->str = str;
current->u.str = str;
current->len = len;
current->mmap = NULL;
if (idx == -1)
{
@ -211,18 +213,18 @@ eet_dictionary_string_get_char(const Eet_Dictionary *ed,
{
#ifdef _WIN32
/* Windows file system could change the mmaped file when replacing a file. So we need to copy all string in memory to avoid bugs. */
if (!ed->all[idx].str)
if (!ed->all[idx].allocated)
{
ed->all[idx].str = strdup(ed->all[idx].mmap);
ed->all[idx].mmap = NULL;
ed->all[idx].u.str = strdup(ed->all[idx].u.mmap);
ed->all[idx].allocated = EINA_TRUE;
}
#else /* ifdef _WIN32 */
if (ed->all[idx].mmap)
return ed->all[idx].mmap;
if (!(ed->all[idx].allocated) && ed->all[idx].u.mmap)
return ed->all[idx].u.mmap;
#endif /* ifdef _WIN32 */
return ed->all[idx].str;
return ed->all[idx].u.str;
}
return NULL;
@ -307,22 +309,50 @@ _eet_dictionary_test(const Eet_Dictionary *ed,
return EINA_TRUE;
} /* _eet_dictionary_test */
static Eet_Convert *
eet_dictionary_convert_get(const Eet_Dictionary *ed,
int idx,
const char **str)
{
Eet_Convert *result;
*str = ed->all[idx].allocated ? ed->all[idx].u.str : ed->all[idx].u.mmap;
if (!ed->converts)
{
((Eet_Dictionary*)ed)->converts = eina_hash_int32_new(free);
goto add_convert;
}
result = eina_hash_find(ed->converts, &idx);
if (result) return result;
add_convert:
result = calloc(1, sizeof (Eet_Convert));
eina_hash_add(ed->converts, &idx, result);
return result;
}
Eina_Bool
eet_dictionary_string_get_float(const Eet_Dictionary *ed,
int idx,
float *result)
{
Eet_Convert *convert;
const char *str;
if (!_eet_dictionary_test(ed, idx, result))
return EINA_FALSE;
if (!(ed->all[idx].type & EET_D_FLOAT))
convert = eet_dictionary_convert_get(ed, idx, &str);
if (!convert) return EINA_FALSE;
if (!(convert->type & EET_D_FLOAT))
{
const char *str;
str = ed->all[idx].str ? ed->all[idx].str : ed->all[idx].mmap;
if (!_eet_dictionary_string_get_float_cache(str, ed->all[idx].len,
&ed->all[idx].f))
&convert->f))
{
long long mantisse = 0;
long exponent = 0;
@ -331,13 +361,13 @@ eet_dictionary_string_get_float(const Eet_Dictionary *ed,
&exponent) == EINA_FALSE)
return EINA_FALSE;
ed->all[idx].f = ldexpf((float)mantisse, exponent);
convert->f = ldexpf((float)mantisse, exponent);
}
ed->all[idx].type |= EET_D_FLOAT;
convert->type |= EET_D_FLOAT;
}
*result = ed->all[idx].f;
*result = convert->f;
return EINA_TRUE;
} /* eet_dictionary_string_get_float */
@ -346,17 +376,19 @@ eet_dictionary_string_get_double(const Eet_Dictionary *ed,
int idx,
double *result)
{
Eet_Convert *convert;
const char *str;
if (!_eet_dictionary_test(ed, idx, result))
return EINA_FALSE;
if (!(ed->all[idx].type & EET_D_DOUBLE))
convert = eet_dictionary_convert_get(ed, idx, &str);
if (!convert) return EINA_FALSE;
if (!(convert->type & EET_D_DOUBLE))
{
const char *str;
str = ed->all[idx].str ? ed->all[idx].str : ed->all[idx].mmap;
if (!_eet_dictionary_string_get_double_cache(str, ed->all[idx].len,
&ed->all[idx].d))
&convert->d))
{
long long mantisse = 0;
long exponent = 0;
@ -365,13 +397,13 @@ eet_dictionary_string_get_double(const Eet_Dictionary *ed,
&exponent) == EINA_FALSE)
return EINA_FALSE;
ed->all[idx].d = ldexp((double)mantisse, exponent);
convert->d = ldexp((double)mantisse, exponent);
}
ed->all[idx].type |= EET_D_DOUBLE;
convert->type |= EET_D_DOUBLE;
}
*result = ed->all[idx].d;
*result = convert->d;
return EINA_TRUE;
} /* eet_dictionary_string_get_double */
@ -380,24 +412,27 @@ eet_dictionary_string_get_fp(const Eet_Dictionary *ed,
int idx,
Eina_F32p32 *result)
{
Eet_Convert *convert;
const char *str;
if (!_eet_dictionary_test(ed, idx, result))
return EINA_FALSE;
if (!(ed->all[idx].type & EET_D_FIXED_POINT))
{
const char *str;
Eina_F32p32 fp;
convert = eet_dictionary_convert_get(ed, idx, &str);
if (!convert) return EINA_FALSE;
str = ed->all[idx].str ? ed->all[idx].str : ed->all[idx].mmap;
if (!(convert->type & EET_D_FIXED_POINT))
{
Eina_F32p32 fp;
if (!eina_convert_atofp(str, ed->all[idx].len, &fp))
return EINA_FALSE;
ed->all[idx].fp = fp;
ed->all[idx].type |= EET_D_FIXED_POINT;
convert->fp = fp;
convert->type |= EET_D_FIXED_POINT;
}
*result = ed->all[idx].fp;
*result = convert->fp;
return EINA_TRUE;
} /* eet_dictionary_string_get_fp */
@ -414,8 +449,8 @@ eet_dictionary_string_check(Eet_Dictionary *ed,
return 1;
for (i = 0; i < ed->count; ++i)
if (ed->all[i].str == string)
return 1;
if ((ed->all[i].allocated) && ed->all[i].u.str == string)
return 1;
return 0;
} /* eet_dictionary_string_check */

View File

@ -636,12 +636,12 @@ eet_flush2(Eet_File *ef)
if (ef->ed)
for (j = 0; j < ef->ed->count; ++j)
{
if (ef->ed->all[j].str)
if (ef->ed->all[j].allocated)
{
if (fwrite(ef->ed->all[j].str, ef->ed->all[j].len, 1, fp) != 1)
if (fwrite(ef->ed->all[j].u.str, ef->ed->all[j].len, 1, fp) != 1)
goto write_error;
}
else if (fwrite(ef->ed->all[j].mmap, ef->ed->all[j].len, 1, fp) != 1)
else if (fwrite(ef->ed->all[j].u.mmap, ef->ed->all[j].len, 1, fp) != 1)
goto write_error;
}
@ -1082,14 +1082,13 @@ eet_internal_read2(Eet_File *ef)
ef->data_size)), ef))
return NULL;
ef->ed->all[j].mmap = start + offset;
ef->ed->all[j].str = NULL;
ef->ed->all[j].u.mmap = start + offset;
if (ef->ed->all[j].mmap + ef->ed->all[j].len > ef->ed->end)
ef->ed->end = ef->ed->all[j].mmap + ef->ed->all[j].len;
if (ef->ed->all[j].u.mmap + ef->ed->all[j].len > ef->ed->end)
ef->ed->end = ef->ed->all[j].u.mmap + ef->ed->all[j].len;
/* Check '\0' at the end of the string */
if (eet_test_close(ef->ed->all[j].mmap[ef->ed->all[j].len - 1] !=
if (eet_test_close(ef->ed->all[j].u.mmap[ef->ed->all[j].len - 1] !=
'\0', ef))
return NULL;