<commit_before>/*
 * Cache for translation server responses.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "tcache.h"
#include "transformation.h"
#include "cache.h"
#include "stock.h"
#include "uri-address.h"

#include <time.h>

struct tcache_item {
    struct cache_item item;

    pool_t pool;

    struct translate_response response;
};

struct tcache {
    pool_t pool;

    struct cache *cache;

    struct hstock *tcp_stock;

    const char *socket_path;
};

struct tcache_request {
    pool_t pool;

    struct tcache *tcache;

    const char *key;

    translate_callback_t callback;
    void *ctx;
};

#ifdef CACHE_LOG
#include <daemon/log.h>
#define cache_log(...) daemon_log(__VA_ARGS__)
#else
#define cache_log(...) do {} while (0)
#endif


/* check whether the request could produce a cacheable response */
static bool
tcache_request_evaluate(const struct translate_request *request)
{
    return (request->uri != NULL || request->widget_type != NULL) &&
        request->param == NULL;
}

/* check whether the response is cacheable */
static bool
tcache_response_evaluate(const struct translate_response *response)
{
    return response != NULL && response->status == 0;
}

static inline const char *
p_strdup_checked(pool_t pool, const char *s)
{
    return s == NULL ? NULL : p_strdup(pool, s);
}

static void
tcache_dup_response(pool_t pool, struct translate_response *dest,
                    const struct translate_response *src)
{
    dest->status = src->status;
    resource_address_copy(pool, &dest->address, &src->address);
    dest->site = p_strdup_checked(pool, src->site);
    dest->document_root = p_strdup_checked(pool, src->document_root);
    dest->redirect = p_strdup_checked(pool, src->redirect);
    dest->stateful = src->stateful;
    dest->session = NULL;
    dest->user = NULL;
    dest->language = NULL;

    dest->views = src->views != NULL
        ? transformation_dup_view_chain(pool, src->views)
        : NULL;
}


/*
 * translate callback
 *
 */

static void
tcache_callback(const struct translate_response *response, void *ctx)
{
    struct tcache_request *tcr = ctx;

    if (tcache_response_evaluate(response)) {
        pool_t pool = pool_new_linear(tcr->tcache->pool, "tcache_item", 512);
        struct tcache_item *item = p_malloc(pool, sizeof(*item));

        cache_log(4, "translate_cache: store %s\n", tcr->key);

        item->item.expires = time(NULL) + 300;
        item->item.size = 1;
        item->pool = pool;

        tcache_dup_response(pool, &item->response, response);
        cache_put(tcr->tcache->cache, p_strdup(pool, tcr->key), &item->item);
    } else {
        cache_log(4, "translate_cache: nocache %s\n", tcr->key);
    }

    tcr->callback(response, tcr->ctx);
}


/*
 * cache class
 *
 */

static bool
tcache_validate(struct cache_item *item __attr_unused)
{
    return true;
}

static void
tcache_destroy(struct cache_item *_item)
{
    struct tcache_item *item = (struct tcache_item *)_item;

    pool_unref(item->pool);
}

static const struct cache_class tcache_class = {
    .validate = tcache_validate,
    .destroy = tcache_destroy,
};


/*
 * constructor
 *
 */

struct tcache *
translate_cache_new(pool_t pool, struct hstock *tcp_stock,<commit_msg>removed implementation of optional "validate()" method<commit_after>/*
 * Cache for translation server responses.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "tcache.h"
#include "transformation.h"
#include "cache.h"
#include "stock.h"
#include "uri-address.h"

#include <time.h>

struct tcache_item {
    struct cache_item item;

    pool_t pool;

    struct translate_response response;
};

struct tcache {
    pool_t pool;

    struct cache *cache;

    struct hstock *tcp_stock;

    const char *socket_path;
};

struct tcache_request {
    pool_t pool;

    struct tcache *tcache;

    const char *key;

    translate_callback_t callback;
    void *ctx;
};

#ifdef CACHE_LOG
#include <daemon/log.h>
#define cache_log(...) daemon_log(__VA_ARGS__)
#else
#define cache_log(...) do {} while (0)
#endif


/* check whether the request could produce a cacheable response */
static bool
tcache_request_evaluate(const struct translate_request *request)
{
    return (request->uri != NULL || request->widget_type != NULL) &&
        request->param == NULL;
}

/* check whether the response is cacheable */
static bool
tcache_response_evaluate(const struct translate_response *response)
{
    return response != NULL && response->status == 0;
}

static inline const char *
p_strdup_checked(pool_t pool, const char *s)
{
    return s == NULL ? NULL : p_strdup(pool, s);
}

static void
tcache_dup_response(pool_t pool, struct translate_response *dest,
                    const struct translate_response *src)
{
    dest->status = src->status;
    resource_address_copy(pool, &dest->address, &src->address);
    dest->site = p_strdup_checked(pool, src->site);
    dest->document_root = p_strdup_checked(pool, src->document_root);
    dest->redirect = p_strdup_checked(pool, src->redirect);
    dest->stateful = src->stateful;
    dest->session = NULL;
    dest->user = NULL;
    dest->language = NULL;

    dest->views = src->views != NULL
        ? transformation_dup_view_chain(pool, src->views)
        : NULL;
}


/*
 * translate callback
 *
 */

static void
tcache_callback(const struct translate_response *response, void *ctx)
{
    struct tcache_request *tcr = ctx;

    if (tcache_response_evaluate(response)) {
        pool_t pool = pool_new_linear(tcr->tcache->pool, "tcache_item", 512);
        struct tcache_item *item = p_malloc(pool, sizeof(*item));

        cache_log(4, "translate_cache: store %s\n", tcr->key);

        item->item.expires = time(NULL) + 300;
        item->item.size = 1;
        item->pool = pool;

        tcache_dup_response(pool, &item->response, response);
        cache_put(tcr->tcache->cache, p_strdup(pool, tcr->key), &item->item);
    } else {
        cache_log(4, "translate_cache: nocache %s\n", tcr->key);
    }

    tcr->callback(response, tcr->ctx);
}


/*
 * cache class
 *
 */

static void
tcache_destroy(struct cache_item *_item)
{
    struct tcache_item *item = (struct tcache_item *)_item;

    pool_unref(item->pool);
}

static const struct cache_class tcache_class = {
    .destroy = tcache_destroy,
};


/*
 * constructor
 *
 */

struct tcache *
translate_cache_new(pool_t pool, struct hstock *tcp_stock,
{'fraction_non_alphanumeric': 0.1276829077236409, 'fraction_numerical': 0.003446655177816074, 'mean_word_length': 3.511660777385159, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2584841', 'n_tokens_mistral': 2139, 'n_tokens_neox': 2073, 'n_words': 508}