/* libs/graphics/sgl/SkDeque.cpp
**
** Copyright 2006, The Android Open Source Project
**
** 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 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.
*/

#include "SkDeque.h"

#define INIT_ELEM_COUNT 1  // should we let the caller set this?

struct SkDeque::Head {
    Head*   fNext;
    Head*   fPrev;
    char*   fBegin; // start of used section in this chunk
    char*   fEnd;   // end of used section in this chunk
    char*   fStop;  // end of the allocated chunk

    char*       start() { return (char*)(this + 1); }
    const char* start() const { return (const char*)(this + 1); }

    void init(size_t size) {
        fNext   = fPrev = NULL;
        fBegin  = fEnd = NULL;
        fStop   = (char*)this + size;
    }
};

SkDeque::SkDeque(size_t elemSize)
        : fElemSize(elemSize), fInitialStorage(NULL), fCount(0) {
    fFront = fBack = NULL;
}

SkDeque::SkDeque(size_t elemSize, void* storage, size_t storageSize)
        : fElemSize(elemSize), fInitialStorage(storage), fCount(0) {
    SkASSERT(storageSize == 0 || storage != NULL);

    if (storageSize >= sizeof(Head) + elemSize) {
        fFront = (Head*)storage;
        fFront->init(storageSize);
    } else {
        fFront = NULL;
    }
    fBack = fFront;
}

SkDeque::~SkDeque() {
    Head* head = fFront;
    Head* initialHead = (Head*)fInitialStorage;

    while (head) {
        Head* next = head->fNext;
        if (head != initialHead) {
            sk_free(head);
        }
        head = next;
    }
}

const void* SkDeque::front() const {
    Head* front = fFront;

    if (NULL == front) {
        return NULL;
    }
    if (NULL == front->fBegin) {
        front = front->fNext;
        if (NULL == front) {
            return NULL;
        }
    }
    SkASSERT(front->fBegin);
    return front->fBegin;
}

const void* SkDeque::back() const {
    Head* back = fBack;

    if (NULL == back) {
        return NULL;
    }
    if (NULL == back->fEnd) {  // marked as deleted
        back = back->fPrev;
        if (NULL == back) {
            return NULL;
        }
    }
    SkASSERT(back->fEnd);
    return back->fEnd - fElemSize;
}

void* SkDeque::push_front() {
    fCount += 1;

    if (NULL == fFront) {
        fFront = (Head*)sk_malloc_throw(sizeof(Head) +
                                        INIT_ELEM_COUNT * fElemSize);
        fFront->init(sizeof(Head) + INIT_ELEM_COUNT * fElemSize);
        fBack = fFront;     // update our linklist
    }

    Head*   first = fFront;
    char*   begin;

    if (NULL == first->fBegin) {
    INIT_CHUNK:
        first->fEnd = first->fStop;
        begin = first->fStop - fElemSize;
    } else {
        begin = first->fBegin - fElemSize;
        if (begin < first->start()) {    // no more room in this chunk
            // should we alloc more as we accumulate more elements?
            size_t  size = sizeof(Head) + INIT_ELEM_COUNT * fElemSize;

            first = (Head*)sk_malloc_throw(size);
            first->init(size);
            first->fNext = fFront;
            fFront->fPrev = first;
            fFront = first;
            goto INIT_CHUNK;
        }
    }

    first->fBegin = begin;
    return begin;
}

void* SkDeque::push_back() {
    fCount += 1;

    if (NULL == fBack) {
        fBack = (Head*)sk_malloc_throw(sizeof(Head) +
                                       INIT_ELEM_COUNT * fElemSize);
        fBack->init(sizeof(Head) + INIT_ELEM_COUNT * fElemSize);
        fFront = fBack; // update our linklist
    }

    Head*   last = fBack;
    char*   end;

    if (NULL == last->fBegin) {
    INIT_CHUNK:
        last->fBegin = last->start();
        end = last->fBegin + fElemSize;
    } else {
        end = last->fEnd + fElemSize;
        if (end > last->fStop) {  // no more room in this chunk
            // should we alloc more as we accumulate more elements?
            size_t  size = sizeof(Head) + INIT_ELEM_COUNT * fElemSize;

            last = (Head*)sk_malloc_throw(size);
            last->init(size);
            last->fPrev = fBack;
            fBack->fNext = last;
            fBack = last;
            goto INIT_CHUNK;
        }
    }

    last->fEnd = end;
    return end - fElemSize;
}

void SkDeque::pop_front() {
    SkASSERT(fCount > 0);
    fCount -= 1;

    Head*   first = fFront;

    SkASSERT(first != NULL);

    if (first->fBegin == NULL) {  // we were marked empty from before
        first = first->fNext;
        first->fPrev = NULL;
        sk_free(fFront);
        fFront = first;
        SkASSERT(first != NULL);    // else we popped too far
    }

    char* begin = first->fBegin + fElemSize;
    SkASSERT(begin <= first->fEnd);

    if (begin < fFront->fEnd) {
        first->fBegin = begin;
    } else {
        first->fBegin = first->fEnd = NULL;  // mark as empty
    }
}

void SkDeque::pop_back() {
    SkASSERT(fCount > 0);
    fCount -= 1;

    Head* last = fBack;

    SkASSERT(last != NULL);

    if (last->fEnd == NULL) {  // we were marked empty from before
        last = last->fPrev;
        last->fNext = NULL;
        sk_free(fBack);
        fBack = last;
        SkASSERT(last != NULL);  // else we popped too far
    }

    char* end = last->fEnd - fElemSize;
    SkASSERT(end >= last->fBegin);

    if (end > last->fBegin) {
        last->fEnd = end;
    } else {
        last->fBegin = last->fEnd = NULL;    // mark as empty
    }
}

///////////////////////////////////////////////////////////////////////////////

SkDeque::F2BIter::F2BIter(const SkDeque& d) : fElemSize(d.fElemSize) {
    fHead = d.fFront;
    while (fHead != NULL && fHead->fBegin == NULL) {
        fHead = fHead->fNext;
    }
    fPos = fHead ? fHead->fBegin : NULL;
}

void* SkDeque::F2BIter::next() {
    char* pos = fPos;

    if (pos) {   // if we were valid, try to move to the next setting
        char* next = pos + fElemSize;
        SkASSERT(next <= fHead->fEnd);
        if (next == fHead->fEnd) { // exhausted this chunk, move to next
            do {
                fHead = fHead->fNext;
            } while (fHead != NULL && fHead->fBegin == NULL);
            next = fHead ? fHead->fBegin : NULL;
        }
        fPos = next;
    }
    return pos;
}

