Skip to content

Commit

Permalink
Merge pull request #134 from alltilla/filterx-cache-json-file-deep-fr…
Browse files Browse the repository at this point in the history
…eeze

filterx: `cache_json_file()` deep freeze
  • Loading branch information
bazsi authored Jun 1, 2024
2 parents fc096ff + 1f04874 commit 422dbfb
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 12 deletions.
4 changes: 4 additions & 0 deletions lib/filterx/filterx-eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ filterx_format_last_error(void)
void
filterx_eval_store_weak_ref(FilterXObject *object)
{
/* Frozen objects do not need weak refs. */
if (object && filterx_object_is_frozen(object))
return;

FilterXEvalContext *context = filterx_eval_get_context();

if (object && !object->weak_referenced)
Expand Down
3 changes: 3 additions & 0 deletions lib/filterx/filterx-weakrefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,8 @@ filterx_weakref_get(FilterXWeakRef *self)
* validate if it's valid, we just assume it is until our Scope has not
* been terminated yet */

if (!self)
return NULL;

return filterx_object_ref(self->object);
}
11 changes: 11 additions & 0 deletions lib/filterx/object-json-array.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,17 @@ filterx_json_array_to_json_literal(FilterXObject *s)
return json_object_to_json_string_ext(self->jso, JSON_C_TO_STRING_PLAIN);
}

struct json_object *
filterx_json_array_get_value(FilterXObject *s)
{
if (!filterx_object_is_type(s, &FILTERX_TYPE_NAME(json_array)))
return NULL;

FilterXJsonArray *self = (FilterXJsonArray *) s;

return self->jso;
}

FILTERX_DEFINE_TYPE(json_array, FILTERX_TYPE_NAME(list),
.is_mutable = TRUE,
.truthy = _truthy,
Expand Down
11 changes: 11 additions & 0 deletions lib/filterx/object-json-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,17 @@ filterx_json_object_to_json_literal(FilterXObject *s)
return json_object_to_json_string_ext(self->jso, JSON_C_TO_STRING_PLAIN);
}

struct json_object *
filterx_json_object_get_value(FilterXObject *s)
{
if (!filterx_object_is_type(s, &FILTERX_TYPE_NAME(json_object)))
return NULL;

FilterXJsonObject *self = (FilterXJsonObject *) s;

return self->jso;
}

FILTERX_DEFINE_TYPE(json_object, FILTERX_TYPE_NAME(dict),
.is_mutable = TRUE,
.truthy = _truthy,
Expand Down
16 changes: 7 additions & 9 deletions lib/filterx/object-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "filterx/object-dict-interface.h"
#include "filterx/object-list-interface.h"
#include "filterx/object-message-value.h"
#include "filterx/filterx-weakrefs.h"
#include "filterx/filterx-eval.h"

#include "scanner/list-scanner/list-scanner.h"
Expand Down Expand Up @@ -73,8 +72,8 @@ filterx_json_deep_copy(struct json_object *jso)
return clone;
}

static FilterXObject *
_convert_json_to_object(FilterXObject *self, FilterXWeakRef *root_container, struct json_object *jso)
FilterXObject *
filterx_json_convert_json_to_object(FilterXObject *root_obj, FilterXWeakRef *root_container, struct json_object *jso)
{
switch (json_object_get_type(jso))
{
Expand All @@ -90,10 +89,10 @@ _convert_json_to_object(FilterXObject *self, FilterXWeakRef *root_container, str
return filterx_string_new(json_object_get_string(jso), -1);
case json_type_array:
return filterx_json_array_new_sub(json_object_get(jso),
filterx_weakref_get(root_container) ? : filterx_object_ref(self));
filterx_weakref_get(root_container) ? : filterx_object_ref(root_obj));
case json_type_object:
return filterx_json_object_new_sub(json_object_get(jso),
filterx_weakref_get(root_container) ? : filterx_object_ref(self));
filterx_weakref_get(root_container) ? : filterx_object_ref(root_obj));
default:
g_assert_not_reached();
}
Expand Down Expand Up @@ -124,7 +123,7 @@ filterx_json_convert_json_to_object_cached(FilterXObject *self, FilterXWeakRef *
*/

if (JSON_C_MAJOR_VERSION == 0 && JSON_C_MINOR_VERSION < 14)
return _convert_json_to_object(self, root_container, jso);
return filterx_json_convert_json_to_object(self, root_container, jso);

json_object_set_double(jso, json_object_get_double(jso));
}
Expand All @@ -134,9 +133,8 @@ filterx_json_convert_json_to_object_cached(FilterXObject *self, FilterXWeakRef *
if (filterx_obj)
return filterx_object_ref(filterx_obj);

filterx_obj = _convert_json_to_object(self, root_container, jso);
if (!filterx_object_is_frozen(self))
filterx_json_associate_cached_object(jso, filterx_obj);
filterx_obj = filterx_json_convert_json_to_object(self, root_container, jso);
filterx_json_associate_cached_object(jso, filterx_obj);
return filterx_obj;
}

Expand Down
6 changes: 6 additions & 0 deletions lib/filterx/object-json.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define OBJECT_JSON_H_INCLUDED

#include "filterx/filterx-object.h"
#include "filterx/filterx-weakrefs.h"
#include "compat/json.h"

typedef struct FilterXJsonObject_ FilterXJsonObject;
Expand All @@ -49,6 +50,11 @@ const gchar *filterx_json_to_json_literal(FilterXObject *s);
const gchar *filterx_json_object_to_json_literal(FilterXObject *s);
const gchar *filterx_json_array_to_json_literal(FilterXObject *s);

FilterXObject *filterx_json_convert_json_to_object(FilterXObject *root_obj, FilterXWeakRef *root_container,
struct json_object *jso);
void filterx_json_associate_cached_object(struct json_object *jso, FilterXObject *filterx_object);

struct json_object *filterx_json_object_get_value(FilterXObject *s);
struct json_object *filterx_json_array_get_value(FilterXObject *s);

#endif
57 changes: 54 additions & 3 deletions modules/json/filterx-cache-json-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "filterx-cache-json-file.h"
#include "filterx/object-json.h"
#include "filterx/object-string.h"
#include "filterx/object-list-interface.h"
#include "filterx/object-dict-interface.h"
#include "filterx/expr-literal.h"
#include "filterx/filterx-eval.h"
#include "scratch-buffers.h"
Expand Down Expand Up @@ -54,6 +56,7 @@ typedef struct FilterXFunctionCacheJsonFile_
FilterXFunction super;
gchar *filepath;
FilterXObject *cached_json;
GPtrArray *frozen_objects;
} FilterXFuntionCacheJsonFile;

static gchar *
Expand Down Expand Up @@ -143,11 +146,56 @@ _free(FilterXExpr *s)
FilterXFuntionCacheJsonFile *self = (FilterXFuntionCacheJsonFile *) s;

g_free(self->filepath);
if (self->cached_json)
filterx_object_unfreeze_and_free(self->cached_json);
g_ptr_array_unref(self->frozen_objects);
filterx_function_free_method(&self->super);
}

static void _deep_freeze(FilterXFuntionCacheJsonFile *self, FilterXObject *object);

static void
_deep_freeze_dict(FilterXFuntionCacheJsonFile *self, FilterXObject *object)
{
struct json_object_iter itr;
json_object_object_foreachC(filterx_json_object_get_value(object), itr)
{
struct json_object *elem_jso = itr.val;
FilterXObject *elem_object = filterx_json_convert_json_to_object(self->cached_json, NULL, elem_jso);
_deep_freeze(self, elem_object);
filterx_json_associate_cached_object(elem_jso, elem_object);
}
}

static void
_deep_freeze_list(FilterXFuntionCacheJsonFile *self, FilterXObject *object)
{
struct json_object *jso = filterx_json_object_get_value(object);
guint64 len = json_object_array_length(jso);

for (guint64 i = 0; i < len; i++)
{
struct json_object *elem_jso = json_object_array_get_idx(jso, i);
FilterXObject *elem_object = filterx_json_convert_json_to_object(self->cached_json, NULL, elem_jso);
_deep_freeze(self, elem_object);
filterx_json_associate_cached_object(elem_jso, elem_object);
}
}

static void
_deep_freeze(FilterXFuntionCacheJsonFile *self, FilterXObject *object)
{
if (!object)
return;

if (filterx_object_freeze(object))
g_ptr_array_add(self->frozen_objects, object);

if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(json_object)))
_deep_freeze_dict(self, object);

if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(json_array)))
_deep_freeze_list(self, object);
}

FilterXFunction *
filterx_function_cache_json_file_new(const gchar *function_name, FilterXFunctionArgs *args, GError **error)
{
Expand All @@ -157,6 +205,8 @@ filterx_function_cache_json_file_new(const gchar *function_name, FilterXFunction
self->super.super.eval = _eval;
self->super.super.free_fn = _free;

self->frozen_objects = g_ptr_array_new_with_free_func((GDestroyNotify) filterx_object_unfreeze_and_free);

self->filepath = _extract_filepath(args, error);
if (!self->filepath)
goto error;
Expand All @@ -165,7 +215,8 @@ filterx_function_cache_json_file_new(const gchar *function_name, FilterXFunction
if (!self->cached_json)
goto error;

filterx_object_freeze(self->cached_json);
_deep_freeze(self, self->cached_json);

filterx_function_args_free(args);
return &self->super;

Expand Down

0 comments on commit 422dbfb

Please sign in to comment.