class LevelCache extends AbstractCache<Id, Object> {

    // For multi-layer caches
    private final AbstractCache<Id, Object>[] caches;

    @SuppressWarnings("unchecked")
    public LevelCache(AbstractCache<Id, Object> lavel1,
                      AbstractCache<Id, Object> lavel2) {
        super(lavel2.capacity());
        super.expire(lavel2.expire());
        this.caches = new AbstractCache[]{lavel1, lavel2};
    }

    @Override
    public void traverse(Consumer<Object> consumer) {
        this.last().traverse(consumer);
    }

    @Override
    public long size() {
        return this.last().size();
    }

    @Override
    public void clear() {
        for (AbstractCache<Id, Object> cache : this.caches) {
            cache.clear();
        }
    }

    @Override
    public void expire(long ms) {
        super.expire(ms);
        for (AbstractCache<Id, Object> cache : this.caches) {
            cache.expire(ms);
        }
    }

    @Override
    public boolean containsKey(Id id) {
        for (AbstractCache<Id, Object> cache : this.caches) {
            if (cache.containsKey(id)) {
                return true;
            }
        }
        return false;
    }

    @Override
    protected Object access(Id id) {<FILL_FUNCTION_BODY>}

    @Override
    protected boolean write(Id id, Object value, long timeOffset) {
        boolean success = false;
        for (AbstractCache<Id, Object> cache : this.caches) {
            success |= cache.write(id, value, timeOffset);
        }
        return success;
    }

    @Override
    protected void remove(Id id) {
        for (AbstractCache<Id, Object> cache : this.caches) {
            cache.remove(id);
        }
    }

    @Override
    protected Iterator<CacheNode<Id, Object>> nodes() {
        ExtendableIterator<CacheNode<Id, Object>> iters;
        iters = new ExtendableIterator<>();
        for (AbstractCache<Id, Object> cache : this.caches) {
            iters.extend(cache.nodes());
        }
        return iters;
    }

    protected AbstractCache<Id, Object> last() {
        final int length = this.caches.length;
        E.checkState(length > 0,
                     "Expect at least one cache in LevelCache, but got %s",
                     length);
        return this.caches[length - 1];
    }
}

        for (AbstractCache<Id, Object> cache : this.caches) {
            // Priority access to the previous level
            Object value = cache.access(id);
            if (value != null) {
                return value;
            }
        }
        return null;
    
<methods>public void <init>() ,public void <init>(long) ,public T attachment(T) ,public T attachment() ,public final long capacity() ,public boolean enableMetrics(boolean) ,public void expire(long) ,public final long expire() ,public java.lang.Object get(org.apache.hugegraph.backend.id.Id) ,public java.lang.Object getOrFetch(org.apache.hugegraph.backend.id.Id, Function<org.apache.hugegraph.backend.id.Id,java.lang.Object>) ,public final long hits() ,public void invalidate(org.apache.hugegraph.backend.id.Id) ,public final long miss() ,public long tick() ,public boolean update(org.apache.hugegraph.backend.id.Id, java.lang.Object) ,public boolean update(org.apache.hugegraph.backend.id.Id, java.lang.Object, long) ,public boolean updateIfAbsent(org.apache.hugegraph.backend.id.Id, java.lang.Object) ,public boolean updateIfPresent(org.apache.hugegraph.backend.id.Id, java.lang.Object) <variables>public static final int DEFAULT_SIZE,protected static final Logger LOG,public static final int MAX_INIT_CAP,public static final int MB,private final non-sealed AtomicReference<java.lang.Object> attachment,private final non-sealed long capacity,private volatile boolean enabledMetrics,private volatile long expire,private final non-sealed java.util.concurrent.atomic.LongAdder hits,private final non-sealed java.util.concurrent.atomic.LongAdder miss