blob: d72a78c38a1f78eae717f6ff9f4bd7228e7823dc [file] [log] [blame]
/*
* 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.
*/
/*-------------------------------------------------------------------------
*
* cdbshareddoublylinked.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "miscadmin.h"
#include "cdb/cdbshareddoublylinked.h"
void
SharedListBase_Init(
SharedListBase *base,
void *data,
int size,
int offsetToDoubleLinks)
{
base->data = data;
base->size = size;
base->offsetToDoubleLinks = offsetToDoubleLinks;
}
void
SharedDoublyLinkedHead_Init(
SharedDoublyLinkedHead *head)
{
head->count = 0;
head->first = -1;
head->last = -1;
}
void
SharedDoubleLinks_Init(
SharedDoubleLinks *doubleLinks,
int index)
{
doubleLinks->index = index;
doubleLinks->prev = -1;
doubleLinks->next = -1;
}
SharedDoubleLinks*
SharedDoubleLinks_FromElement(
SharedListBase *base,
void *current)
{
uint8 *uint8Current = (uint8*)current;
return (SharedDoubleLinks*)(uint8Current + base->offsetToDoubleLinks);
}
void*
SharedListBase_ToElement(
SharedListBase *base,
int index)
{
Assert(base != NULL);
Assert(index >= 0);
return base->data + (index * base->size);
}
void*
SharedDoublyLinkedHead_First(
SharedListBase *base,
SharedDoublyLinkedHead *head)
{
Assert(base != NULL);
Assert(head != NULL);
if (head->first != -1)
{
void *firstEle;
SharedDoubleLinks *firstDoubleLinks;
Assert(head->first >= 0);
firstEle = SharedListBase_ToElement(base, head->first);
firstDoubleLinks = SharedDoubleLinks_FromElement(base, firstEle);
Assert(firstDoubleLinks->index == head->first);
return firstEle;
}
else
return NULL;
}
SharedDoubleLinks*
SharedListBase_ToDoubleLinks(
SharedListBase *base,
int index)
{
SharedDoubleLinks *sharedDoubleLinks;
Assert(base != NULL);
Assert(index >= 0);
sharedDoubleLinks =
(SharedDoubleLinks*)
(base->data + (index * base->size) + base->offsetToDoubleLinks);
Assert(sharedDoubleLinks->index == index);
return sharedDoubleLinks;
}
void*
SharedDoubleLinks_Next(
SharedListBase *base,
SharedDoublyLinkedHead *head,
void *currentEle)
{
SharedDoubleLinks *currentDoubleLinks;
Assert(base != NULL);
Assert(head != NULL);
Assert(currentEle != NULL);
currentDoubleLinks = SharedDoubleLinks_FromElement(base, currentEle);
if (currentDoubleLinks->next == -1)
{
Assert(head->last == currentDoubleLinks->index);
return NULL;
}
else
{
void *nextEle;
SharedDoubleLinks *nextDoubleLinks;
Assert(currentDoubleLinks->next >= 0);
nextEle = SharedListBase_ToElement(base, currentDoubleLinks->next);
nextDoubleLinks = SharedDoubleLinks_FromElement(base, nextEle);
Assert(nextDoubleLinks->index == currentDoubleLinks->next);
return nextEle;
}
}
void
SharedDoubleLinks_Remove(
SharedListBase *base,
SharedDoublyLinkedHead *head,
void *removeEle)
{
SharedDoubleLinks *removeDoubleLinks;
int index;
SharedDoubleLinks *prevDoubleLinks = NULL;
SharedDoubleLinks *nextDoubleLinks = NULL;
Assert(base != NULL);
Assert(head != NULL);
Assert(removeEle != NULL);
removeDoubleLinks = SharedDoubleLinks_FromElement(base, removeEle);
index = removeDoubleLinks->index;
if (removeDoubleLinks->prev == -1 &&
removeDoubleLinks->next == -1)
{
/*
* Removing the only one.
*/
Assert(head->first == index);
Assert(head->last == index);
Assert(head->count == 1);
head->first = -1;
head->last = -1;
}
else if (removeDoubleLinks->prev == -1)
{
/*
* Removing the first element.
*/
Assert(head->first == index);
nextDoubleLinks =
SharedListBase_ToDoubleLinks(base, removeDoubleLinks->next);
Assert(nextDoubleLinks->prev == index);
nextDoubleLinks->prev = -1;
head->first = nextDoubleLinks->index;
}
else if (removeDoubleLinks->next == -1)
{
Assert(head->last == index);
/*
* Removing the last element.
*/
prevDoubleLinks =
SharedListBase_ToDoubleLinks(base, removeDoubleLinks->prev);
Assert(prevDoubleLinks->next == index);
prevDoubleLinks->next = -1;
head->last = prevDoubleLinks->index;
}
else
{
/*
* Removing a middle element.
*/
nextDoubleLinks =
SharedListBase_ToDoubleLinks(base, removeDoubleLinks->next);
Assert(nextDoubleLinks->prev == index);
nextDoubleLinks->prev = removeDoubleLinks->prev;
prevDoubleLinks =
SharedListBase_ToDoubleLinks(base, removeDoubleLinks->prev);
Assert(prevDoubleLinks->next == index);
prevDoubleLinks->next = removeDoubleLinks->next;
}
Assert(head->count >= 1);
head->count--;
removeDoubleLinks->prev = -1;
removeDoubleLinks->next = -1;
}
void
SharedDoublyLinkedHead_AddFirst(
SharedListBase *base,
SharedDoublyLinkedHead *head,
void *ele)
{
SharedDoubleLinks *eleDoubleLinks;
Assert(base != NULL);
Assert(head != NULL);
Assert(ele != NULL);
eleDoubleLinks = SharedDoubleLinks_FromElement(base, ele);
Assert(eleDoubleLinks->prev == -1);
Assert(eleDoubleLinks->next == -1);
if (head->first == -1 && head->last == -1)
{
Assert(head->count == 0);
head->first = eleDoubleLinks->index;
head->last = eleDoubleLinks->index;
}
else
{
SharedDoubleLinks *firstDoubleLinks;
Assert(head->count > 0);
firstDoubleLinks =
SharedListBase_ToDoubleLinks(base, head->first);
Assert(firstDoubleLinks->prev == -1);
eleDoubleLinks->next = head->first;
head->first = eleDoubleLinks->index;
firstDoubleLinks->prev = eleDoubleLinks->index;
}
head->count++;
}
void
SharedDoublyLinkedHead_AddLast(
SharedListBase *base,
SharedDoublyLinkedHead *head,
void *ele)
{
SharedDoubleLinks *eleDoubleLinks;
Assert(base != NULL);
Assert(head != NULL);
Assert(ele != NULL);
eleDoubleLinks = SharedDoubleLinks_FromElement(base, ele);
Assert(eleDoubleLinks->prev == -1);
Assert(eleDoubleLinks->next == -1);
if (head->first == -1 && head->last == -1)
{
Assert(head->count == 0);
head->first = eleDoubleLinks->index;
head->last = eleDoubleLinks->index;
}
else
{
SharedDoubleLinks *lastDoubleLinks;
Assert(head->count > 0);
Assert(head->first >= 0);
Assert(head->last >= 0);
lastDoubleLinks =
SharedListBase_ToDoubleLinks(base, head->last);
Assert(lastDoubleLinks->next == -1);
eleDoubleLinks->prev = lastDoubleLinks->index;
head->last = eleDoubleLinks->index;
lastDoubleLinks->next = eleDoubleLinks->index;
}
head->count++;
}
void*
SharedDoublyLinkedHead_RemoveFirst(
SharedListBase *base,
SharedDoublyLinkedHead *head)
{
void* firstEle;
SharedDoubleLinks *firstDoubleLinks;
Assert(base != NULL);
Assert(head != NULL);
if (head->first == -1)
{
Assert(head->count == 0);
return NULL;
}
Assert(head->first >= 0);
firstEle = SharedListBase_ToElement(base, head->first);
firstDoubleLinks = SharedDoubleLinks_FromElement(base, firstEle);
Assert(firstDoubleLinks->index == head->first);
SharedDoubleLinks_Remove(
base,
head,
firstEle);
return firstEle;
}
void
SharedDoubleLinks_AddBefore(
SharedListBase *base,
SharedDoublyLinkedHead *head,
void *atEle,
void *newEle)
{
SharedDoubleLinks *newDoubleLinks;
SharedDoubleLinks *atDoubleLinks;
SharedDoubleLinks *prevDoubleLinks;
Assert(base != NULL);
Assert(head != NULL);
Assert(head->count > 0);
Assert(atEle != NULL);
Assert(newEle != NULL);
newDoubleLinks = SharedDoubleLinks_FromElement(base, newEle);
Assert(newDoubleLinks->prev == -1);
Assert(newDoubleLinks->next == -1);
atDoubleLinks = SharedDoubleLinks_FromElement(base, atEle);
if (head->first == atDoubleLinks->index)
{
SharedDoublyLinkedHead_AddFirst(
base,
head,
newEle);
return;
}
prevDoubleLinks =
SharedListBase_ToDoubleLinks(base, atDoubleLinks->prev);
prevDoubleLinks->next = atDoubleLinks->prev = newDoubleLinks->index;
newDoubleLinks->next = atDoubleLinks->index;
newDoubleLinks->prev = prevDoubleLinks->index;
head->count++;
}
//******************************************************************************