Logo Search packages:      
Sourcecode: kaya version File versions  Download package

Array.cc

/**
    Kaya run-time system
    Copyright (C) 2004, 2005 Edwin Brady

    This file is distributed under the terms of the GNU Lesser General
    Public Licence. See COPYING for licence.
*/

#include "Array.h"
#include <gc/gc_allocator.h>

#include <iostream>
#include "Heap.h"
#include "ValueFuns.h"
#include "stdfuns.h"

#define ALLOC 50

Array::Array(int size):m_alloc(ALLOC),m_size(0),m_first(NULL)
{
    if (size!=0) {
      m_size=0;
      m_alloc = size;
    }
//    m_data = (Value**)GC_MALLOC_UNCOLLECTABLE(sizeof(Value*)*m_alloc);
//    m_data = new Value*[m_alloc];

    m_first = new chunk();
    m_first -> data = (Value**)GC_MALLOC_UNCOLLECTABLE(sizeof(Value*)*m_alloc);

    m_first -> size = m_alloc;
    m_first -> next = NULL;
}

Array::~Array() {
    chunk* c = m_first;
    
    // Delete all the chunks data blocks.
    while (c!=NULL) {
      GC_FREE(c->data);
      c = c->next;
    }
//    cout << "Array destructor called" << endl;
}

void Array::expectedSize(int size)
{
    if (size<=m_size) return; // Already big enough

    chunk* c = m_first;
    chunk* last = NULL;
    
    // Find the last chunk, then make a chunk big enough for <size>.

    while (c!=NULL) {
      last = c;
      c = c->next;
    }
    
    c = new chunk();
    last->next = c;
    int alloc = size;
//    cout << " New chunk, size " << alloc << " at " << c << endl;
    c -> data = (Value**)GC_MALLOC_UNCOLLECTABLE(sizeof(Value*)*alloc);
    c -> size = alloc;
    c -> next = NULL;
}

void Array::resize(int i)
{
//     int oldsize=m_size;
    if (i<m_size) {
      m_size=i;
    }
    else {
      // This is slow. Better to just set the size, and remember how
      // much is allocated. But this'll do for now.
      while(m_size<i) {
          push_back(new Value(NULL,NULL));
      }
    }
// Perhaps delete chunks we no longer need here?

//     if (m_size<=m_alloc) {
//    m_alloc=m_size+1;
//    Value** newdata = (Value**)GC_MALLOC_UNCOLLECTABLE(sizeof(Value*)*m_alloc);
//    for(int i=0;i<oldsize;i++)
//        newdata[i]=m_data[i];
//    for(int i=oldsize;i<m_size;i++)
//        newdata[i]=new Value(NULL,NULL);
//    m_data=newdata;
//     }
}

Value* Array::shift()
{
    chunk* c = m_first;
    Value* shiftval = *(c->data);

    // Move all the values down one.
    while (c!=NULL) {
      memmove(c->data,(c->data)+1,(c->size-1)*sizeof(Value*));
      if (c->next!=NULL) {
          c->data[(c->size)-1] = c->next->data[0];
      }
      c = c->next;
    }
    m_size--;
    return shiftval;
}

void Array::push_back(Value *v)
{
    chunk* c = m_first;
    chunk* last = NULL;
    int i = m_size;
    while (c!=NULL) {
      if (i<c->size) {
          break;
      } else {
          i=i-c->size;
          last = c;
          c = c->next;
      }
    }
    // If c is NULL make a new chunk.
    if (c==NULL) {
      c = new chunk();
      last->next = c;
      // Always double the size of the last chunk. Not sure how often
      // this is a good strategy...
      int alloc = last->size*2;
//    cout << " New chunk, size " << alloc << " at " << c << endl;
      c -> data = (Value**)GC_MALLOC_UNCOLLECTABLE(sizeof(Value*)*alloc);
      c -> size = alloc;
//    cout << c->size << endl;
      c -> next = NULL;
      i=0;
    }
    c->data[i] = v;
    m_size++;

/*    if (m_size==m_alloc) {
      m_alloc*=2;
      /// CAN'T DO THIS!!!!1!!!
      Value** newdata = (Value**)GC_MALLOC_UNCOLLECTABLE(sizeof(Value*)*m_alloc);
//    Value** newdata = new Value*[m_alloc];
      for(int i=0;i<m_size;i++)
          newdata[i]=m_data[i];
      m_data=newdata;
    }
    m_data[m_size]=v;
    m_size++;*/
}

Value* Array::lookup(int i)
{
    chunk* c = m_first;
    while (c!=NULL) {
      if (i<c->size) {
          return c->data[i];
      } else {
          i=i-c->size;
          c = c->next;
      }
    }
    return NULL; // Out of bounds.
}

bool Array::eq(Array* x)
{
    if (x->size()!=size()) return false;
    for(int i=0;i<m_size;i++) {
      Value* idx = lookup(i);
      Value* xidx = x->lookup(i);
      if (!funtable_eq(idx,xidx)) return false;
    }
    return true;
}

int Array::cmp(Array* x)
{
    if (x->size()<size()) return -1;
    if (x->size()>size()) return 1;
    for(int i=0;i<m_size;i++) {
      Value* idx = lookup(i);
      Value* xidx = x->lookup(i);
      int cmp = funtable_compare(idx,xidx);
      if (cmp!=0) return cmp;
    }
    return 0;
}

Array* Array::copy()
{
    Array* a = new Array(m_size);
    for(int i=0;i<m_size;i++) {
      Value* ai = funtable_copy(lookup(i));
      a->push_back(ai);
    }
    return a;
}


Generated by  Doxygen 1.6.0   Back to index