1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "util/u_memory.h"
29bf215546Sopenharmony_ci#include "pipe/p_state.h"
30bf215546Sopenharmony_ci#include "translate.h"
31bf215546Sopenharmony_ci#include "translate_cache.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "cso_cache/cso_cache.h"
34bf215546Sopenharmony_ci#include "cso_cache/cso_hash.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_cistruct translate_cache {
37bf215546Sopenharmony_ci   struct cso_hash hash;
38bf215546Sopenharmony_ci};
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_cistruct translate_cache * translate_cache_create( void )
41bf215546Sopenharmony_ci{
42bf215546Sopenharmony_ci   struct translate_cache *cache = MALLOC_STRUCT(translate_cache);
43bf215546Sopenharmony_ci   if (!cache) {
44bf215546Sopenharmony_ci      return NULL;
45bf215546Sopenharmony_ci   }
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ci   cso_hash_init(&cache->hash);
48bf215546Sopenharmony_ci   return cache;
49bf215546Sopenharmony_ci}
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_cistatic inline void delete_translates(struct translate_cache *cache)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   struct cso_hash *hash = &cache->hash;
55bf215546Sopenharmony_ci   struct cso_hash_iter iter = cso_hash_first_node(hash);
56bf215546Sopenharmony_ci   while (!cso_hash_iter_is_null(iter)) {
57bf215546Sopenharmony_ci      struct translate *state = (struct translate*)cso_hash_iter_data(iter);
58bf215546Sopenharmony_ci      iter = cso_hash_iter_next(iter);
59bf215546Sopenharmony_ci      if (state) {
60bf215546Sopenharmony_ci         state->release(state);
61bf215546Sopenharmony_ci      }
62bf215546Sopenharmony_ci   }
63bf215546Sopenharmony_ci}
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_civoid translate_cache_destroy(struct translate_cache *cache)
66bf215546Sopenharmony_ci{
67bf215546Sopenharmony_ci   delete_translates(cache);
68bf215546Sopenharmony_ci   cso_hash_deinit(&cache->hash);
69bf215546Sopenharmony_ci   FREE(cache);
70bf215546Sopenharmony_ci}
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_cistatic inline unsigned translate_hash_key_size(struct translate_key *key)
74bf215546Sopenharmony_ci{
75bf215546Sopenharmony_ci   unsigned size = sizeof(struct translate_key) -
76bf215546Sopenharmony_ci                   sizeof(struct translate_element) * (TRANSLATE_MAX_ATTRIBS - key->nr_elements);
77bf215546Sopenharmony_ci   return size;
78bf215546Sopenharmony_ci}
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_cistatic inline unsigned create_key(struct translate_key *key)
81bf215546Sopenharmony_ci{
82bf215546Sopenharmony_ci   unsigned hash_key;
83bf215546Sopenharmony_ci   unsigned size = translate_hash_key_size(key);
84bf215546Sopenharmony_ci   /*debug_printf("key size = %d, (els = %d)\n",
85bf215546Sopenharmony_ci     size, key->nr_elements);*/
86bf215546Sopenharmony_ci   hash_key = cso_construct_key(key, size);
87bf215546Sopenharmony_ci   return hash_key;
88bf215546Sopenharmony_ci}
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_cistruct translate * translate_cache_find(struct translate_cache *cache,
91bf215546Sopenharmony_ci                                        struct translate_key *key)
92bf215546Sopenharmony_ci{
93bf215546Sopenharmony_ci   unsigned hash_key = create_key(key);
94bf215546Sopenharmony_ci   struct translate *translate = (struct translate*)
95bf215546Sopenharmony_ci      cso_hash_find_data_from_template(&cache->hash,
96bf215546Sopenharmony_ci                                       hash_key,
97bf215546Sopenharmony_ci                                       key, sizeof(*key));
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   if (!translate) {
100bf215546Sopenharmony_ci      /* create/insert */
101bf215546Sopenharmony_ci      translate = translate_create(key);
102bf215546Sopenharmony_ci      cso_hash_insert(&cache->hash, hash_key, translate);
103bf215546Sopenharmony_ci   }
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci   return translate;
106bf215546Sopenharmony_ci}
107