| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| #pragma once |
| |
| #include <cstddef> |
| #include <memory> |
| |
| #include "kudu/gutil/macros.h" |
| #include "kudu/gutil/ref_counted.h" |
| |
| namespace kudu { |
| |
| class Cache; |
| class Slice; |
| class Status; |
| |
| namespace codegen { |
| |
| class JITWrapper; |
| |
| // A code cache is a specialized LRU cache with the following services: |
| // 1. It supports only one writer at a time, but multiple concurrent |
| // readers. |
| // 2. If its items are taking too much space, it evicts the least- |
| // recently-used member of the cache. |
| // |
| // The cache takes shared ownership of its entry values, the JITWrappers, |
| // by incrementing their reference count. |
| // |
| // LRU eviction does not guarantee that a JITWrapper is deleted, only that |
| // the cache releases its shared ownership (by decrementing the reference |
| // count) of the jit code. |
| class CodeCache { |
| public: |
| // TODO: currently CodeCache is implemented using the Cache in |
| // kudu/util/cache.h, which requires some transformation to nongeneric |
| // Slice-type keys and values. Furthermore, the Cache implementation |
| // provides concurrent write guarantees (thus relies on locks heavily), which |
| // is unnecessary for the CodeCache. A potential improvement would be to |
| // implement a single-writer multi-reader LRU cache with proper generics. |
| |
| // TODO: a potential improvment would be for the cache to monitor its memory |
| // consumption explicity and keep its usage under a size limit specified at |
| // construction time. In order to do this, the cache would have to inject |
| // a custom memory manager into the CodeGenerator's execution engine which |
| // intercepts allocation calls and tracks code size. |
| |
| // Generates an empty code cache which stores at most 'capacity' JITWrappers. |
| // A JIT payload is defined to be the combination of objects which rely on jitted |
| // code and the classes which own the jitted code. |
| explicit CodeCache(size_t capacity); |
| ~CodeCache(); |
| |
| // This function is NOT thread safe (only one writer may call this at |
| // a time). Attempts to add a new entry 'wrapper' to the cache, using |
| // wrapper->EncodeOwnKey() as the key. Overwrites the previous value |
| // if one exists. If insertion results in excess capacity, LRU eviction |
| // occurs. Returns Status::OK() upon success. |
| Status AddEntry(const scoped_refptr<JITWrapper>& wrapper); |
| |
| // This function may be called from any thread concurrently with other |
| // writes and reads to the cache. Looks in the cache for the specified key. |
| // Returns a reference to the associated payload, or NULL if no such entry |
| // exists in the cache. |
| scoped_refptr<JITWrapper> Lookup(const Slice& key); |
| |
| private: |
| class EvictionCallback; |
| |
| std::unique_ptr<EvictionCallback> eviction_callback_; |
| std::unique_ptr<Cache> cache_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CodeCache); |
| }; |
| |
| } // namespace codegen |
| } // namespace kudu |