/*
 * Copyright 2009-2012 by The Regents of the University of California
 * Licensed 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 from
 * 
 *     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.
 */

package edu.uci.ics.hyracks.storage.am.lsm.common.freepage;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.io.FileReference;
import edu.uci.ics.hyracks.storage.am.lsm.common.api.IInMemoryBufferCache;
import edu.uci.ics.hyracks.storage.common.buffercache.ICacheMemoryAllocator;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPageInternal;
import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
import edu.uci.ics.hyracks.storage.common.file.IFileMapManager;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;

public class InMemoryBufferCache implements IInMemoryBufferCache {
    protected final ICacheMemoryAllocator allocator;
    protected final IFileMapManager fileMapManager;
    protected final int pageSize;
    protected final int numPages;
    protected final List<CachedPage> overflowPages = new ArrayList<CachedPage>();
    protected CachedPage[] pages;

    public InMemoryBufferCache(ICacheMemoryAllocator allocator, int pageSize, int numPages,
            IFileMapManager fileMapManager) {
        this.allocator = allocator;
        this.fileMapManager = fileMapManager;
        this.pageSize = pageSize;
        this.numPages = numPages;
    }

    public void open() {
        pages = new CachedPage[numPages];
        ByteBuffer[] buffers = allocator.allocate(pageSize, numPages);
        for (int i = 0; i < buffers.length; ++i) {
            pages[i] = new CachedPage(i, buffers[i]);
        }
    }

    @Override
    public ICachedPage pin(long dpid, boolean newPage) {
        int pageId = BufferedFileHandle.getPageId(dpid);
        if (pageId < pages.length) {
            // Common case: Return regular page.
            return pages[pageId];
        } else {
            // Rare case: Return overflow page, possibly expanding overflow array.
            synchronized (overflowPages) {
                int numNewPages = pageId - pages.length - overflowPages.size() + 1;
                if (numNewPages > 0) {
                    ByteBuffer[] buffers = allocator.allocate(pageSize, numNewPages);
                    for (int i = 0; i < numNewPages; i++) {
                        CachedPage overflowPage = new CachedPage(pages.length + overflowPages.size(), buffers[i]);
                        overflowPages.add(overflowPage);
                    }
                }
                return overflowPages.get(pageId - pages.length);
            }
        }
    }

    @Override
    public ICachedPage tryPin(long dpid) throws HyracksDataException {
        return pin(dpid, false);
    }

    @Override
    public int getPageSize() {
        return pageSize;
    }

    @Override
    public int getNumPages() {
        return numPages;
    }

    @Override
    public ICachedPageInternal getPage(int cpid) {
        return pages[cpid];
    }

    public int getNumOverflowPages() {
        return overflowPages.size();
    }

    @Override
    public void createFile(FileReference fileRef) throws HyracksDataException {
        synchronized (fileMapManager) {
            fileMapManager.registerFile(fileRef);
        }
    }

    @Override
    public void openFile(int fileId) throws HyracksDataException {
        // Do nothing.
    }

    @Override
    public void closeFile(int fileId) throws HyracksDataException {
        // Do nothing.
    }

    @Override
    public void deleteFile(int fileId, boolean flushDirtyPages) throws HyracksDataException {
        synchronized (fileMapManager) {
            fileMapManager.unregisterFile(fileId);
        }
    }

    @Override
    public void unpin(ICachedPage page) throws HyracksDataException {
        // Do Nothing.
    }

    @Override
    public void close() {
        for (int i = 0; i < numPages; ++i) {
            pages[i] = null;
        }
        overflowPages.clear();
    }

    public class CachedPage implements ICachedPageInternal {
        private final int cpid;
        private final ByteBuffer buffer;
        private final ReadWriteLock latch;

        public CachedPage(int cpid, ByteBuffer buffer) {
            this.cpid = cpid;
            this.buffer = buffer;
            latch = new ReentrantReadWriteLock(true);
        }

        @Override
        public ByteBuffer getBuffer() {
            return buffer;
        }

        @Override
        public Object getReplacementStrategyObject() {
            // Do nothing.
            return null;
        }

        @Override
        public boolean pinIfGoodVictim() {
            // Do nothing.
            return false;
        }

        @Override
        public int getCachedPageId() {
            return cpid;
        }

        @Override
        public void acquireReadLatch() {
            latch.readLock().lock();
        }

        @Override
        public void acquireWriteLatch() {
            latch.writeLock().lock();
        }

        @Override
        public void releaseReadLatch() {
            latch.readLock().unlock();
        }

        @Override
        public void releaseWriteLatch() {
            latch.writeLock().unlock();
        }
    }

    @Override
    public void force(int fileId, boolean metadata) throws HyracksDataException {
    }

    @Override
    public void flushDirtyPage(ICachedPage page) throws HyracksDataException {
    }

    public IFileMapProvider getFileMapProvider() {
        return fileMapManager;
    }
}
