Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Günther Wagner
gnome-builder
Commits
0c37e2de
Commit
0c37e2de
authored
Jan 16, 2018
by
Christian Hergert
Browse files
code-index: code style cleanup for map builder
parent
f23579d3
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/plugins/code-index/ide-persistent-map-builder.c
View file @
0c37e2de
...
...
@@ -23,24 +23,28 @@
#include
"ide-persistent-map-builder.h"
struct
_IdePersistentMapBuilder
typedef
struct
{
GObject
parent
;
/* Array of keys. */
GByteArray
*
keys
;
GByteArray
*
keys
;
/* Hash table of keys to remove duplicate keys. */
GHashTable
*
keys_hash
;
GHashTable
*
keys_hash
;
/* Array of values. */
GPtrArray
*
values
;
GPtrArray
*
values
;
/*
* Array of key value pairs. This is pair of offset of
* key in keys array and index of value in values array.
*/
GArray
*
kvpairs
;
GArray
*
kvpairs
;
/* Dictionary for metadata. */
GVariantDict
*
metadata
;
};
/* Where to write the file */
GFile
*
destination
;
}
BuildState
;
typedef
struct
{
...
...
@@ -48,8 +52,40 @@ typedef struct
guint32
value
;
}
KVPair
;
struct
_IdePersistentMapBuilder
{
GObject
parent
;
/* Owning thread for assertions */
GThread
*
thread
;
/*
* The build state lets us keep all the contents together, and then
* pass it to the worker thread so the main thread can no longer access
* the existing state.
*/
BuildState
*
state
;
};
G_STATIC_ASSERT
(
sizeof
(
KVPair
)
==
8
);
G_DEFINE_TYPE
(
IdePersistentMapBuilder
,
ide_persistent_map_builder
,
G_TYPE_OBJECT
)
static
void
build_state_free
(
gpointer
data
)
{
BuildState
*
state
=
data
;
g_clear_pointer
(
&
state
->
keys
,
g_byte_array_unref
);
g_clear_pointer
(
&
state
->
keys_hash
,
g_hash_table_unref
);
g_clear_pointer
(
&
state
->
values
,
g_ptr_array_unref
);
g_clear_pointer
(
&
state
->
kvpairs
,
g_array_unref
);
g_clear_pointer
(
&
state
->
metadata
,
g_variant_dict_unref
);
g_clear_object
(
&
state
->
destination
);
g_slice_free
(
BuildState
,
state
);
}
void
ide_persistent_map_builder_insert
(
IdePersistentMapBuilder
*
self
,
const
gchar
*
key
,
...
...
@@ -62,35 +98,38 @@ ide_persistent_map_builder_insert (IdePersistentMapBuilder *self,
g_return_if_fail
(
IDE_IS_PERSISTENT_MAP_BUILDER
(
self
));
g_return_if_fail
(
key
!=
NULL
);
g_return_if_fail
(
value
!=
NULL
);
g_return_if_fail
(
self
->
state
!=
NULL
);
g_return_if_fail
(
self
->
state
->
keys_hash
!=
NULL
);
g_return_if_fail
(
self
->
state
->
values
!=
NULL
);
g_return_if_fail
(
self
->
state
->
kvpairs
!=
NULL
);
local_value
=
g_variant_ref_sink
(
value
);
if
((
value_index
=
GPOINTER_TO_UINT
(
g_hash_table_lookup
(
self
->
keys_hash
,
key
))))
if
(
0
!=
(
value_index
=
GPOINTER_TO_UINT
(
g_hash_table_lookup
(
self
->
state
->
keys_hash
,
key
))))
{
value_index
--
;
if
(
replace
)
{
g_
clear_pointer
(
&
g_ptr_array_index
(
self
->
values
,
value_index
),
g_variant_unref
);
g_ptr_array_index
(
self
->
values
,
value_index
)
=
g_steal_pointer
(
&
local_value
);
g_
variant_unref
(
g_ptr_array_index
(
self
->
state
->
values
,
value_index
-
1
)
);
g_ptr_array_index
(
self
->
state
->
values
,
value_index
-
1
)
=
g_steal_pointer
(
&
local_value
);
}
}
else
{
KVPair
kvpair
;
kvpair
.
key
=
self
->
keys
->
len
;
kvpair
.
value
=
self
->
values
->
len
;
kvpair
.
key
=
self
->
state
->
keys
->
len
;
kvpair
.
value
=
self
->
state
->
values
->
len
;
g_byte_array_append
(
self
->
keys
,
(
const
guchar
*
)
key
,
strlen
(
key
)
+
1
);
g_ptr_array_add
(
self
->
values
,
g_steal_pointer
(
&
local_value
));
g_array_append_val
(
self
->
kvpairs
,
kvpair
);
g_byte_array_append
(
self
->
state
->
keys
,
(
const
guchar
*
)
key
,
strlen
(
key
)
+
1
);
g_ptr_array_add
(
self
->
state
->
values
,
g_steal_pointer
(
&
local_value
));
g_array_append_val
(
self
->
state
->
kvpairs
,
kvpair
);
/*
* Key in hashtable is the actual key in our map.
* Value in hash table will point to element in values array
* where actual value of key in our map is there.
*/
g_hash_table_insert
(
self
->
keys_hash
,
g_hash_table_insert
(
self
->
state
->
keys_hash
,
g_strdup
(
key
),
GUINT_TO_POINTER
(
kvpair
.
value
+
1
));
}
...
...
@@ -103,17 +142,16 @@ ide_persistent_map_builder_set_metadata_int64 (IdePersistentMapBuilder *self,
{
g_return_if_fail
(
IDE_IS_PERSISTENT_MAP_BUILDER
(
self
));
g_return_if_fail
(
key
!=
NULL
);
g_return_if_fail
(
self
->
state
!=
NULL
);
g_return_if_fail
(
self
->
state
->
metadata
!=
NULL
);
g_variant_dict_insert
(
self
->
metadata
,
key
,
"x"
,
value
);
g_variant_dict_insert
(
self
->
state
->
metadata
,
key
,
"x"
,
value
);
}
gint
compare
(
KVPair
*
a
,
KVPair
*
b
,
gchar
*
keys
)
static
gint
compare
_keys
(
KVPair
*
a
,
KVPair
*
b
,
const
gchar
*
keys
)
{
return
g_strcmp0
(
keys
+
a
->
key
,
keys
+
b
->
key
);
}
...
...
@@ -125,65 +163,73 @@ ide_persistent_map_builder_write_worker (GTask *task,
GCancellable
*
cancellable
)
{
IdePersistentMapBuilder
*
self
=
source_object
;
GFile
*
destination
=
task_data
;
GVariantDict
dict
;
BuildState
*
state
=
task_data
;
g_autoptr
(
GError
)
error
=
NULL
;
g_autoptr
(
GVariant
)
data
=
NULL
;
GVariantDict
dict
;
GVariant
*
keys
;
GVariant
*
values
;
GVariant
*
kvpairs
;
GVariant
*
metadata
;
g_autoptr
(
GError
)
error
=
NULL
;
g_assert
(
G_IS_TASK
(
task
));
g_assert
(
IDE_IS_PERSISTENT_MAP_BUILDER
(
self
));
g_assert
(
G_IS_FILE
(
destination
));
g_assert
(
state
!=
NULL
);
g_assert
(
state
->
keys
!=
NULL
);
g_assert
(
state
->
keys_hash
!=
NULL
);
g_assert
(
state
->
values
!=
NULL
);
g_assert
(
state
->
kvpairs
!=
NULL
);
g_assert
(
state
->
metadata
!=
NULL
);
g_assert
(
G_IS_FILE
(
state
->
destination
));
g_assert
(
!
cancellable
||
G_IS_CANCELLABLE
(
cancellable
));
if
(
!
self
->
keys
->
len
)
g_task_return_boolean
(
task
,
TRUE
);
if
(
g_task_return_error_if_cancelled
(
task
))
return
;
if
(
state
->
keys
->
len
==
0
)
{
g_task_return_new_error
(
task
,
G_IO_ERROR
,
G_IO_ERROR_INVALID_DATA
,
"No entries to write"
);
return
;
}
g_variant_dict_init
(
&
dict
,
NULL
);
keys
=
g_variant_new_fixed_array
(
G_VARIANT_TYPE_BYTE
,
s
elf
->
keys
->
data
,
s
elf
->
keys
->
len
,
s
tate
->
keys
->
data
,
s
tate
->
keys
->
len
,
sizeof
(
guint8
));
values
=
g_variant_new_array
(
NULL
,
(
GVariant
*
const
*
)(
gpointer
)
self
->
values
->
pdata
,
self
->
values
->
len
);
(
GVariant
*
const
*
)(
gpointer
)
state
->
values
->
pdata
,
state
->
values
->
len
);
g_array_sort_with_data
(
state
->
kvpairs
,
(
GCompareDataFunc
)
compare_keys
,
state
->
keys
->
data
);
g_array_sort_with_data
(
self
->
kvpairs
,
(
GCompareDataFunc
)
compare
,
self
->
keys
->
data
);
kvpairs
=
g_variant_new_fixed_array
(
G_VARIANT_TYPE
(
"(uu)"
),
s
elf
->
kvpairs
->
data
,
s
elf
->
kvpairs
->
len
,
s
tate
->
kvpairs
->
data
,
s
tate
->
kvpairs
->
len
,
sizeof
(
KVPair
));
metadata
=
g_variant_dict_end
(
s
elf
->
metadata
);
metadata
=
g_variant_dict_end
(
s
tate
->
metadata
);
/* Insert Keys. */
g_variant_dict_insert_value
(
&
dict
,
"keys"
,
keys
);
/* Insert values. */
g_variant_dict_insert_value
(
&
dict
,
"values"
,
values
);
/* Insert key value pairs. */
g_variant_dict_insert_value
(
&
dict
,
"kvpairs"
,
kvpairs
);
/* Insert metadata. */
g_variant_dict_insert_value
(
&
dict
,
"metadata"
,
metadata
);
/* Insert verion number. */
g_variant_dict_insert
(
&
dict
,
"version"
,
"i"
,
2
);
/* Insert byte order*/
g_variant_dict_insert
(
&
dict
,
"byte-order"
,
"i"
,
G_BYTE_ORDER
);
/* Write to file. */
data
=
g_variant_ref_sink
(
g_variant_dict_end
(
&
dict
));
if
(
g_file_replace_contents
(
destination
,
g_variant_dict_insert
(
&
dict
,
"version"
,
"i"
,
2
);
g_variant_dict_insert
(
&
dict
,
"byte-order"
,
"i"
,
G_BYTE_ORDER
);
data
=
g_variant_take_ref
(
g_variant_dict_end
(
&
dict
));
if
(
g_task_return_error_if_cancelled
(
task
))
return
;
if
(
g_file_replace_contents
(
state
->
destination
,
g_variant_get_data
(
data
),
g_variant_get_size
(
data
),
NULL
,
...
...
@@ -198,74 +244,78 @@ ide_persistent_map_builder_write_worker (GTask *task,
}
gboolean
ide_persistent_map_builder_write
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
gint
io_priority
,
GCancellable
*
cancellable
,
GError
**
error
)
ide_persistent_map_builder_write
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
gint
io_priority
,
GCancellable
*
cancellable
,
GError
**
error
)
{
g_autoptr
(
GTask
)
task
=
NULL
;
g_return_val_if_fail
(
IDE_IS_PERSISTENT_MAP_BUILDER
(
self
),
FALSE
);
g_return_val_if_fail
(
self
->
thread
==
g_thread_self
(),
FALSE
);
g_return_val_if_fail
(
G_IS_FILE
(
destination
),
FALSE
);
g_return_val_if_fail
(
!
cancellable
||
G_IS_CANCELLABLE
(
cancellable
),
FALSE
);
g_return_val_if_fail
(
self
->
state
!=
NULL
,
FALSE
);
g_return_val_if_fail
(
self
->
state
->
destination
!=
NULL
,
FALSE
);
self
->
state
->
destination
=
g_object_ref
(
destination
);
task
=
g_task_new
(
self
,
cancellable
,
NULL
,
NULL
);
g_task_set_source_tag
(
task
,
ide_persistent_map_builder_write
);
g_task_set_priority
(
task
,
io_priority
);
g_task_set_task_data
(
task
,
g_object_ref
(
destination
),
g_object_unref
);
if
(
self
->
values
->
len
)
ide_persistent_map_builder_write_worker
(
task
,
self
,
destination
,
cancellable
);
else
g_task_return_new_error
(
task
,
G_IO_ERROR
,
G_IO_ERROR_INVALID_DATA
,
"No entries to write"
);
g_task_set_task_data
(
task
,
g_steal_pointer
(
&
self
->
state
),
build_state_free
);
g_task_run_in_thread_sync
(
task
,
ide_persistent_map_builder_write_worker
);
return
g_task_propagate_boolean
(
task
,
error
);
}
void
ide_persistent_map_builder_write_async
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
gint
io_priority
,
GCancellable
*
cancellable
,
GAsyncReadyCallback
callback
,
gpointer
user_data
)
ide_persistent_map_builder_write_async
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
gint
io_priority
,
GCancellable
*
cancellable
,
GAsyncReadyCallback
callback
,
gpointer
user_data
)
{
g_autoptr
(
GTask
)
task
=
NULL
;
g_return_if_fail
(
IDE_IS_PERSISTENT_MAP_BUILDER
(
self
));
g_return_if_fail
(
self
->
thread
==
g_thread_self
());
g_return_if_fail
(
G_IS_FILE
(
destination
));
g_return_if_fail
(
!
cancellable
||
G_IS_CANCELLABLE
(
cancellable
));
g_return_if_fail
(
self
->
thread
==
g_thread_self
());
g_return_if_fail
(
self
->
state
!=
NULL
);
g_return_if_fail
(
self
->
state
->
destination
!=
NULL
);
self
->
state
->
destination
=
g_object_ref
(
destination
);
task
=
g_task_new
(
self
,
cancellable
,
callback
,
user_data
);
g_task_set_priority
(
task
,
io_priority
);
g_task_set_task_data
(
task
,
g_object_ref
(
destination
),
g_object_unref
);
g_task_set_source_tag
(
task
,
ide_persistent_map_builder_write_async
);
g_task_set_task_data
(
task
,
g_steal_pointer
(
&
self
->
state
),
build_state_free
);
g_task_run_in_thread
(
task
,
ide_persistent_map_builder_write_worker
);
}
/**
* ide_persistent_map_builder_write_finish:
* @self:
A
n #IdePersistentMapBuilder
instance.
* @result:
result of writing process
* @error:
error in writing process
* @self:
a
n #IdePersistentMapBuilder
* @result:
a #GAsyncResult provided to callback
* @error:
location for a #GError, or %NULL
*
* Returns: Whether file is written or not.
* Returns: %TRUE if the while was written successfully; otherwise %FALSE
* and @error is set.
*/
gboolean
ide_persistent_map_builder_write_finish
(
IdePersistentMapBuilder
*
self
,
GAsyncResult
*
result
,
GError
**
error
)
{
GTask
*
task
=
(
GTask
*
)
result
;
g_
assert
(
G_IS_TASK
(
task
)
);
g_return_val_if_fail
(
IDE_IS_PERSISTENT_MAP_BUILDER
(
self
),
FALSE
)
;
g_return_val_if_fail
(
G_IS_TASK
(
result
),
FALSE
);
g_
return_val_if_fail
(
self
->
thread
==
g_thread_self
(),
FALSE
);
return
g_task_propagate_boolean
(
task
,
error
);
return
g_task_propagate_boolean
(
G_TASK
(
result
)
,
error
);
}
static
void
...
...
@@ -273,11 +323,8 @@ ide_persistent_map_builder_finalize (GObject *object)
{
IdePersistentMapBuilder
*
self
=
(
IdePersistentMapBuilder
*
)
object
;
g_clear_pointer
(
&
self
->
keys
,
g_byte_array_unref
);
g_clear_pointer
(
&
self
->
keys_hash
,
g_hash_table_unref
);
g_clear_pointer
(
&
self
->
values
,
g_ptr_array_unref
);
g_clear_pointer
(
&
self
->
kvpairs
,
g_array_unref
);
g_clear_pointer
(
&
self
->
metadata
,
g_variant_dict_unref
);
g_clear_pointer
(
&
self
->
state
,
build_state_free
);
self
->
thread
=
NULL
;
G_OBJECT_CLASS
(
ide_persistent_map_builder_parent_class
)
->
finalize
(
object
);
}
...
...
@@ -285,11 +332,14 @@ ide_persistent_map_builder_finalize (GObject *object)
static
void
ide_persistent_map_builder_init
(
IdePersistentMapBuilder
*
self
)
{
self
->
keys
=
g_byte_array_new
();
self
->
keys_hash
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
NULL
);
self
->
values
=
g_ptr_array_new_with_free_func
((
GDestroyNotify
)
g_variant_unref
);
self
->
kvpairs
=
g_array_new
(
FALSE
,
FALSE
,
sizeof
(
KVPair
));
self
->
metadata
=
g_variant_dict_new
(
NULL
);
self
->
thread
=
g_thread_self
();
self
->
state
=
g_slice_new0
(
BuildState
);
self
->
state
->
keys
=
g_byte_array_new
();
self
->
state
->
keys_hash
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
NULL
);
self
->
state
->
values
=
g_ptr_array_new_with_free_func
((
GDestroyNotify
)
g_variant_unref
);
self
->
state
->
kvpairs
=
g_array_new
(
FALSE
,
FALSE
,
sizeof
(
KVPair
));
self
->
state
->
metadata
=
g_variant_dict_new
(
NULL
);
}
static
void
...
...
@@ -300,7 +350,7 @@ ide_persistent_map_builder_class_init (IdePersistentMapBuilderClass *klass)
object_class
->
finalize
=
ide_persistent_map_builder_finalize
;
}
IdePersistentMapBuilder
*
IdePersistentMapBuilder
*
ide_persistent_map_builder_new
(
void
)
{
return
g_object_new
(
IDE_TYPE_PERSISTENT_MAP_BUILDER
,
NULL
);
...
...
src/plugins/code-index/ide-persistent-map-builder.h
View file @
0c37e2de
...
...
@@ -27,27 +27,27 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE
(
IdePersistentMapBuilder
,
ide_persistent_map_builder
,
IDE
,
PERSISTENT_MAP_BUILDER
,
GObject
)
IdePersistentMapBuilder
*
ide_persistent_map_builder_new
(
void
);
void
ide_persistent_map_builder_insert
(
IdePersistentMapBuilder
*
self
,
const
gchar
*
key
,
GVariant
*
value
,
gboolean
replace
);
gboolean
ide_persistent_map_builder_
write
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
gint
io_priority
,
GCancellable
*
cancellable
,
GError
*
*
error
);
void
ide_persistent_map_builder_write_async
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
gint
io_priority
,
GCancellable
*
cancellable
,
GAsyncReadyCallback
callback
,
gpo
int
er
user_data
);
gboolean
ide_persistent_map_builder_write_finish
(
IdePersistentMapBuilder
*
self
,
GAsyncRe
sult
*
result
,
GErro
r
**
error
);
void
ide_persistent_map_builder_
set_metadata_int64
(
IdePersistentMapBuilder
*
self
,
const
gchar
*
key
,
gint64
value
);
IdePersistentMapBuilder
*
ide_persistent_map_builder_new
(
void
);
void
ide_persistent_map_builder_insert
(
IdePersistentMapBuilder
*
self
,
const
gchar
*
key
,
GVariant
*
value
,
gboolean
replace
);
void
ide_persistent_map_builder_
set_metadata_int64
(
IdePersistentMapBuilder
*
self
,
const
gchar
*
key
,
gint
64
value
);
gboolean
ide_persistent_map_builder_write
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
gint
io_priority
,
GCancellable
*
cancellable
,
GError
**
error
);
void
ide_persistent_map_builder_write_async
(
IdePersistentMapBuilder
*
self
,
GFile
*
destination
,
g
int
io_priority
,
GCancellable
*
cancellable
,
GAsyncRe
adyCallback
callback
,
gpointe
r
user_data
);
gboolean
ide_persistent_map_builder_
write_finish
(
IdePersistentMapBuilder
*
self
,
GAsyncResult
*
result
,
GError
**
error
);
G_END_DECLS
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment