forked from enlightenment/efl
eina: add support for in memory only Eina_File.
This commit is contained in:
parent
9ffd451029
commit
f2de8970a1
|
@ -1,3 +1,7 @@
|
|||
2013-07-31 Cedric Bail
|
||||
|
||||
* Eina: add eina_file_virtualize() and eina_file_virtual().
|
||||
|
||||
2013-07-25 ChunEon Park (Hermet)
|
||||
|
||||
* Evas: Skip the map rendering if all points are transparent.
|
||||
|
|
1
NEWS
1
NEWS
|
@ -34,6 +34,7 @@ Additions:
|
|||
- Add eina_tiler_area_size_set(), eina_tiler_strict_set(), eina_tiler_area_size_get()
|
||||
- Add eina_file_map_populate()
|
||||
- Add eina_tiler_empty()
|
||||
- Add eina_file_virtualize() and eina_file_virtual()
|
||||
* Eet:
|
||||
- Add eet_mmap()
|
||||
- Add eet_data_descriptor_name_get()
|
||||
|
|
|
@ -324,27 +324,6 @@ _eina_file_map_close(Eina_File_Map *map)
|
|||
free(map);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_eina_file_map_key_length(const void *key EINA_UNUSED)
|
||||
{
|
||||
return sizeof (unsigned long int) * 2;
|
||||
}
|
||||
|
||||
static int
|
||||
_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length EINA_UNUSED,
|
||||
const unsigned long int *key2, int key2_length EINA_UNUSED)
|
||||
{
|
||||
if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
|
||||
return key1[0] - key2[0];
|
||||
}
|
||||
|
||||
static int
|
||||
_eina_file_map_key_hash(const unsigned long int *key, int key_length EINA_UNUSED)
|
||||
{
|
||||
return eina_hash_int64(&key[0], sizeof (unsigned long int))
|
||||
^ eina_hash_int64(&key[1], sizeof (unsigned long int));
|
||||
}
|
||||
|
||||
#ifndef MAP_POPULATE
|
||||
static unsigned int
|
||||
_eina_file_map_populate(char *map, unsigned int size, Eina_Bool hugetlb)
|
||||
|
@ -880,9 +859,9 @@ eina_file_open(const char *path, Eina_Bool shared)
|
|||
memset(n, 0, sizeof(Eina_File));
|
||||
n->filename = (char*) (n + 1);
|
||||
strcpy((char*) n->filename, filename);
|
||||
n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length),
|
||||
EINA_KEY_CMP(_eina_file_map_key_cmp),
|
||||
EINA_KEY_HASH(_eina_file_map_key_hash),
|
||||
n->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
|
||||
EINA_KEY_CMP(eina_file_map_key_cmp),
|
||||
EINA_KEY_HASH(eina_file_map_key_hash),
|
||||
EINA_FREE_CB(_eina_file_map_close),
|
||||
3);
|
||||
n->rmap = eina_hash_pointer_new(NULL);
|
||||
|
@ -931,6 +910,8 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule)
|
|||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
||||
|
||||
if (file->virtual) return eina_file_virtual_map_all(file);
|
||||
|
||||
// bsd people will lack this feature
|
||||
#ifdef MAP_POPULATE
|
||||
if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE;
|
||||
|
@ -984,6 +965,9 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
|
|||
if (offset == 0 && length == file->length)
|
||||
return eina_file_map_all(file, rule);
|
||||
|
||||
if (file->virtual)
|
||||
return eina_file_virtual_map_new(file, offset, length);
|
||||
|
||||
key[0] = offset;
|
||||
key[1] = length;
|
||||
|
||||
|
@ -1048,6 +1032,9 @@ eina_file_map_free(Eina_File *file, void *map)
|
|||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(file);
|
||||
|
||||
if (file->virtual)
|
||||
return eina_file_virtual_map_free(file, map);
|
||||
|
||||
eina_lock_take(&file->lock);
|
||||
|
||||
if (file->global_map == map)
|
||||
|
@ -1104,6 +1091,8 @@ eina_file_map_faulted(Eina_File *file, void *map)
|
|||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
|
||||
|
||||
if (file->virtual) return EINA_FALSE;
|
||||
|
||||
eina_lock_take(&file->lock);
|
||||
|
||||
if (file->global_map == map)
|
||||
|
@ -1126,6 +1115,8 @@ eina_file_xattr_get(Eina_File *file)
|
|||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
||||
|
||||
if (file->virtual) return NULL;
|
||||
|
||||
return eina_xattr_fd_ls(file->fd);
|
||||
}
|
||||
|
||||
|
@ -1134,6 +1125,8 @@ eina_file_xattr_value_get(Eina_File *file)
|
|||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
||||
|
||||
if (file->virtual) return NULL;
|
||||
|
||||
return eina_xattr_value_fd_ls(file->fd);
|
||||
}
|
||||
|
||||
|
|
|
@ -444,8 +444,6 @@ typedef enum {
|
|||
*/
|
||||
EAPI Eina_Bool eina_file_copy(const char *src, const char *dst, Eina_File_Copy_Flags flags, Eina_File_Copy_Progress cb, const void *cb_data) EINA_ARG_NONNULL(1, 2);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get a read-only handler to a file.
|
||||
*
|
||||
|
@ -461,6 +459,30 @@ EAPI Eina_Bool eina_file_copy(const char *src, const char *dst, Eina_File_Copy_F
|
|||
*/
|
||||
EAPI Eina_File *eina_file_open(const char *name, Eina_Bool shared) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||
|
||||
/**
|
||||
* @brief Create a virtual file from a memory pointer.
|
||||
*
|
||||
* @param data The memory pointer to take data from
|
||||
* @param length The length of the data in memory
|
||||
* @param copy #EINA_TRUE if the data must be copied
|
||||
* @return Eina_File handle to the file
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI Eina_File *
|
||||
eina_file_virtualize(const void *data, unsigned long long length, Eina_Bool copy) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @brief Tell if a file is a real file or only exist in memory
|
||||
*
|
||||
* @param file The file to test
|
||||
* @return #EINA_TRUE if the file is a virtual file
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI Eina_Bool
|
||||
eina_file_virtual(Eina_File *file) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @brief Dup a read-only handler of a previously open file.
|
||||
*
|
||||
|
|
|
@ -129,6 +129,116 @@ _eina_file_escape(char *path, size_t len)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
eina_file_map_key_length(const void *key EINA_UNUSED)
|
||||
{
|
||||
return sizeof (unsigned long int) * 2;
|
||||
}
|
||||
|
||||
int
|
||||
eina_file_map_key_cmp(const unsigned long int *key1, int key1_length EINA_UNUSED,
|
||||
const unsigned long int *key2, int key2_length EINA_UNUSED)
|
||||
{
|
||||
if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
|
||||
return key1[0] - key2[0];
|
||||
}
|
||||
|
||||
int
|
||||
eina_file_map_key_hash(const unsigned long int *key, int key_length EINA_UNUSED)
|
||||
{
|
||||
return eina_hash_int64(&key[0], sizeof (unsigned long int))
|
||||
^ eina_hash_int64(&key[1], sizeof (unsigned long int));
|
||||
}
|
||||
|
||||
void *
|
||||
eina_file_virtual_map_all(Eina_File *file)
|
||||
{
|
||||
eina_lock_take(&file->lock);
|
||||
file->global_refcount++;
|
||||
eina_lock_release(&file->lock);
|
||||
|
||||
return file->global_map;
|
||||
}
|
||||
|
||||
void *
|
||||
eina_file_virtual_map_new(Eina_File *file,
|
||||
unsigned long int offset, unsigned long int length)
|
||||
{
|
||||
Eina_File_Map *map;
|
||||
unsigned long int key[2];
|
||||
|
||||
// offset and length has already been checked by the caller function
|
||||
|
||||
key[0] = offset;
|
||||
key[1] = length;
|
||||
|
||||
eina_lock_take(&file->lock);
|
||||
|
||||
map = eina_hash_find(file->map, &key);
|
||||
if (!map)
|
||||
{
|
||||
map = malloc(sizeof (Eina_File_Map));
|
||||
goto on_error;
|
||||
|
||||
map->map = ((char*) file->global_map) + offset;
|
||||
map->offset = offset;
|
||||
map->length = length;
|
||||
map->refcount = 0;
|
||||
|
||||
eina_hash_add(file->map, &key, map);
|
||||
eina_hash_direct_add(file->rmap, map->map, map);
|
||||
}
|
||||
|
||||
map->refcount++;
|
||||
|
||||
on_error:
|
||||
eina_lock_release(&file->lock);
|
||||
return map ? map->map : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
eina_file_virtual_map_free(Eina_File *file, void *map)
|
||||
{
|
||||
Eina_File_Map *em;
|
||||
|
||||
eina_lock_take(&file->lock);
|
||||
|
||||
// map could equal global_map even if length != file->length
|
||||
em = eina_hash_find(file->rmap, &map);
|
||||
if (em)
|
||||
{
|
||||
unsigned long int key[2];
|
||||
|
||||
em->refcount--;
|
||||
|
||||
if (em->refcount > 0) goto on_exit;
|
||||
|
||||
key[0] = em->offset;
|
||||
key[1] = em->length;
|
||||
|
||||
eina_hash_del(file->rmap, &map, em);
|
||||
eina_hash_del(file->map, &key, em);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (file->global_map == map)
|
||||
{
|
||||
file->global_refcount--;
|
||||
}
|
||||
}
|
||||
|
||||
on_exit:
|
||||
eina_lock_release(&file->lock);
|
||||
}
|
||||
|
||||
// Private to this file API
|
||||
static void
|
||||
_eina_file_map_close(Eina_File_Map *map)
|
||||
{
|
||||
free(map);
|
||||
}
|
||||
|
||||
// Global API
|
||||
|
||||
EAPI char *
|
||||
|
@ -152,10 +262,71 @@ eina_file_path_sanitize(const char *path)
|
|||
return _eina_file_escape(eina_file_cleanup(result), len);
|
||||
}
|
||||
|
||||
EAPI Eina_File *
|
||||
eina_file_virtualize(const void *data, unsigned long long length, Eina_Bool copy)
|
||||
{
|
||||
Eina_File *file;
|
||||
Eina_Nano_Time tp;
|
||||
long int ti;
|
||||
const char *tmpname = "/dev/mem/virtual\\/%16x";
|
||||
|
||||
// Generate an almost uniq filename based on current nsec time.
|
||||
if (_eina_time_get(&tp)) return NULL;
|
||||
ti = _eina_time_convert(&tp);
|
||||
|
||||
file = malloc(sizeof (Eina_File) +
|
||||
strlen(tmpname) + 17 +
|
||||
(copy ? length : 0));
|
||||
if (!file) return NULL;
|
||||
|
||||
memset(file, 0, sizeof(Eina_File));
|
||||
file->filename = (char*) (file + 1);
|
||||
sprintf((char*) file->filename, tmpname, ti);
|
||||
|
||||
eina_lock_new(&file->lock);
|
||||
file->mtime = ti / 1000;
|
||||
file->length = length;
|
||||
file->mtime_nsec = ti;
|
||||
file->refcount = 1;
|
||||
file->fd = -1;
|
||||
file->virtual = EINA_TRUE;
|
||||
file->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
|
||||
EINA_KEY_CMP(eina_file_map_key_cmp),
|
||||
EINA_KEY_HASH(eina_file_map_key_hash),
|
||||
EINA_FREE_CB(_eina_file_map_close),
|
||||
3);
|
||||
file->rmap = eina_hash_pointer_new(NULL);
|
||||
|
||||
if (copy)
|
||||
{
|
||||
file->global_map = (void*)(file->filename +
|
||||
strlen(file->filename) + 1);
|
||||
memcpy((char*) file->global_map, data, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
file->global_map = (void*) data;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eina_file_virtual(Eina_File *file)
|
||||
{
|
||||
if (file) return file->virtual;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eina_File *
|
||||
eina_file_dup(Eina_File *file)
|
||||
{
|
||||
if (file) file->refcount++;
|
||||
if (file)
|
||||
{
|
||||
eina_lock_take(&file->lock);
|
||||
file->refcount++;
|
||||
eina_lock_release(&file->lock);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ struct _Eina_File
|
|||
Eina_Bool shared : 1;
|
||||
Eina_Bool delete_me : 1;
|
||||
Eina_Bool global_faulty : 1;
|
||||
Eina_Bool virtual : 1;
|
||||
};
|
||||
|
||||
struct _Eina_File_Map
|
||||
|
@ -123,4 +124,16 @@ extern Eina_Hash *_eina_file_cache;
|
|||
extern Eina_Lock _eina_file_lock_cache;
|
||||
extern int _eina_file_log_dom;
|
||||
|
||||
// Common function to handle virtual file
|
||||
void *eina_file_virtual_map_all(Eina_File *file);
|
||||
void *eina_file_virtual_map_new(Eina_File *file,
|
||||
unsigned long int offset, unsigned long int length);
|
||||
void eina_file_virtual_map_free(Eina_File *file, void *map);
|
||||
|
||||
// Common hash function
|
||||
unsigned int eina_file_map_key_length(const void *key);
|
||||
int eina_file_map_key_cmp(const unsigned long int *key1, int key1_length,
|
||||
const unsigned long int *key2, int key2_length);
|
||||
int eina_file_map_key_hash(const unsigned long int *key, int key_length);
|
||||
|
||||
#endif /* EINA_FILE_COMMON_H_ */
|
||||
|
|
|
@ -384,27 +384,6 @@ _eina_file_map_close(Eina_File_Map *map)
|
|||
free(map);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_eina_file_map_key_length(const void *key EINA_UNUSED)
|
||||
{
|
||||
return sizeof (unsigned long int) * 2;
|
||||
}
|
||||
|
||||
static int
|
||||
_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length EINA_UNUSED,
|
||||
const unsigned long int *key2, int key2_length EINA_UNUSED)
|
||||
{
|
||||
if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
|
||||
return key1[0] - key2[0];
|
||||
}
|
||||
|
||||
static int
|
||||
_eina_file_map_key_hash(const unsigned long int *key, int key_length EINA_UNUSED)
|
||||
{
|
||||
return eina_hash_int64(&key[0], sizeof (unsigned long int))
|
||||
^ eina_hash_int64(&key[1], sizeof (unsigned long int));
|
||||
}
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
@ -804,9 +783,9 @@ eina_file_open(const char *path, Eina_Bool shared)
|
|||
memset(n, 0, sizeof(Eina_File));
|
||||
n->filename = (char*) (n + 1);
|
||||
strcpy((char*) n->filename, filename);
|
||||
n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length),
|
||||
EINA_KEY_CMP(_eina_file_map_key_cmp),
|
||||
EINA_KEY_HASH(_eina_file_map_key_hash),
|
||||
n->map = eina_hash_new(EINA_KEY_LENGTH(eina_file_map_key_length),
|
||||
EINA_KEY_CMP(eina_file_map_key_cmp),
|
||||
EINA_KEY_HASH(eina_file_map_key_hash),
|
||||
EINA_FREE_CB(_eina_file_map_close),
|
||||
3);
|
||||
n->rmap = eina_hash_pointer_new(NULL);
|
||||
|
@ -859,6 +838,8 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule EINA_UNUSED)
|
|||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
|
||||
|
||||
if (file->virtual) return eina_file_virtual_map_all(file);
|
||||
|
||||
eina_lock_take(&file->lock);
|
||||
if (file->global_map == MAP_FAILED)
|
||||
{
|
||||
|
@ -875,6 +856,7 @@ eina_file_map_all(Eina_File *file, Eina_File_Populate rule EINA_UNUSED)
|
|||
if (file->global_map != MAP_FAILED)
|
||||
{
|
||||
file->global_refcount++;
|
||||
eina_lock_release(&file->lock);
|
||||
return file->global_map;
|
||||
}
|
||||
|
||||
|
@ -899,6 +881,9 @@ eina_file_map_new(Eina_File *file, Eina_File_Populate rule,
|
|||
if (offset == 0 && length == file->length)
|
||||
return eina_file_map_all(file, rule);
|
||||
|
||||
if (file->virtual)
|
||||
return eina_file_virtual_map_new(file, offset, length);
|
||||
|
||||
key[0] = offset;
|
||||
key[1] = length;
|
||||
|
||||
|
@ -952,6 +937,9 @@ eina_file_map_free(Eina_File *file, void *map)
|
|||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(file);
|
||||
|
||||
if (file->virtual)
|
||||
return eina_file_virtual_map_free(file, map);
|
||||
|
||||
eina_lock_take(&file->lock);
|
||||
|
||||
if (file->global_map == map)
|
||||
|
@ -989,6 +977,7 @@ eina_file_map_free(Eina_File *file, void *map)
|
|||
EAPI Eina_Bool
|
||||
eina_file_map_faulted(Eina_File *file, void *map)
|
||||
{
|
||||
if (file->virtual) return EINA_FALSE;
|
||||
/*
|
||||
* FIXME:
|
||||
* vc++ : http://msdn.microsoft.com/en-us/library/windows/desktop/aa366801%28v=vs.85%29.aspx
|
||||
|
|
Loading…
Reference in New Issue