Fixing array pop (#458)

This commit is contained in:
Richard Knoll 2017-07-21 13:42:48 -05:00 committed by GitHub
parent 07f86be501
commit 204ec41823

View File

@ -146,16 +146,16 @@ namespace pxt {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("In Segment::get index:%u\n", i); printf("In Segment::get index:%u\n", i);
this->print(); this->print();
#endif #endif
if (i < length) if (i < length)
{ {
return data[i]; return data[i];
} }
return Segment::DefaultValue; return Segment::DefaultValue;
} }
void Segment::set(uint32_t i, uint32_t value) void Segment::set(uint32_t i, uint32_t value)
{ {
if (i < size) if (i < size)
{ {
@ -168,16 +168,16 @@ namespace pxt {
} }
if (length <= i) if (length <= i)
{ {
length = i + 1; length = i + 1;
} }
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("In Segment::set\n"); printf("In Segment::set\n");
this->print(); this->print();
#endif #endif
return; return;
} }
uint16_t Segment::growthFactor(uint16_t size) uint16_t Segment::growthFactor(uint16_t size)
{ {
@ -201,12 +201,12 @@ namespace pxt {
growBy(max(minSize, growthFactor(size))); growBy(max(minSize, growthFactor(size)));
} }
void Segment::growBy(uint16_t newSize) void Segment::growBy(uint16_t newSize)
{ {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("growBy: %d\n", newSize); printf("growBy: %d\n", newSize);
this->print(); this->print();
#endif #endif
if (size < newSize) if (size < newSize)
{ {
//this will throw if unable to allocate //this will throw if unable to allocate
@ -221,16 +221,16 @@ namespace pxt {
memset(tmp + size, Segment::DefaultValue, (newSize - size) * sizeof(uint32_t)); memset(tmp + size, Segment::DefaultValue, (newSize - size) * sizeof(uint32_t));
//free older segment; //free older segment;
::operator delete(data); ::operator delete(data);
data = tmp; data = tmp;
size = newSize; size = newSize;
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("growBy - after reallocation\n"); printf("growBy - after reallocation\n");
this->print(); this->print();
#endif #endif
} }
//else { no shrinking yet; } //else { no shrinking yet; }
return; return;
@ -249,42 +249,42 @@ namespace pxt {
{ {
if (newLength > size) if (newLength > size)
{ {
ensure(length); ensure(length);
} }
length = newLength; length = newLength;
return; return;
} }
void Segment::push(uint32_t value) void Segment::push(uint32_t value)
{ {
this->set(length, value); this->set(length, value);
} }
uint32_t Segment::pop() uint32_t Segment::pop()
{ {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("In Segment::pop\n"); printf("In Segment::pop\n");
this->print(); this->print();
#endif #endif
if (length > 0) if (length > 0)
{ {
--length;
uint32_t value = data[length]; uint32_t value = data[length];
data[length] = Segment::DefaultValue; data[length] = Segment::DefaultValue;
--length;
return value; return value;
} }
return Segment::DefaultValue; return Segment::DefaultValue;
} }
//this function removes an element at index i and shifts the rest of the elements to //this function removes an element at index i and shifts the rest of the elements to
//left to fill the gap //left to fill the gap
uint32_t Segment::remove(uint32_t i) uint32_t Segment::remove(uint32_t i)
{ {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("In Segment::remove index:%u\n", i); printf("In Segment::remove index:%u\n", i);
this->print(); this->print();
#endif #endif
if (i < length) if (i < length)
{ {
//value to return //value to return
@ -294,24 +294,24 @@ namespace pxt {
//Move the rest of the elements to fill in the gap. //Move the rest of the elements to fill in the gap.
memmove(data + i, data + i + 1, (length - i - 1) * sizeof(uint32_t)); memmove(data + i, data + i + 1, (length - i - 1) * sizeof(uint32_t));
} }
length--; length--;
data[length] = Segment::DefaultValue; data[length] = Segment::DefaultValue;
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("After Segment::remove index:%u\n", i); printf("After Segment::remove index:%u\n", i);
this->print(); this->print();
#endif #endif
return ret; return ret;
} }
return Segment::DefaultValue; return Segment::DefaultValue;
} }
//this function inserts element value at index i by shifting the rest of the elements right. //this function inserts element value at index i by shifting the rest of the elements right.
void Segment::insert(uint32_t i, uint32_t value) void Segment::insert(uint32_t i, uint32_t value)
{ {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("In Segment::insert index:%u value:%u\n", i, value); printf("In Segment::insert index:%u value:%u\n", i, value);
this->print(); this->print();
#endif #endif
if (i < length) if (i < length)
{ {
@ -322,7 +322,7 @@ namespace pxt {
memmove(data + i + 1, data + i, (length - i) * sizeof(uint32_t)); memmove(data + i + 1, data + i, (length - i) * sizeof(uint32_t));
} }
data[i] = value; data[i] = value;
length++; length++;
} }
else else
@ -333,7 +333,7 @@ namespace pxt {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("After Segment::insert index:%u\n", i); printf("After Segment::insert index:%u\n", i);
this->print(); this->print();
#endif #endif
} }
void Segment::print() void Segment::print()
@ -360,29 +360,29 @@ namespace pxt {
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
printf("In Segment::destroy\n"); printf("In Segment::destroy\n");
this->print(); this->print();
#endif #endif
length = size = 0; length = size = 0;
::operator delete(data); ::operator delete(data);
data = nullptr; data = nullptr;
} }
void RefCollection::push(uint32_t x) void RefCollection::push(uint32_t x)
{ {
if (isRef()) incr(x); if (isRef()) incr(x);
head.push(x); head.push(x);
} }
uint32_t RefCollection::pop() uint32_t RefCollection::pop()
{ {
uint32_t ret = head.pop(); uint32_t ret = head.pop();
if (isRef()) if (isRef())
{ {
incr(ret); incr(ret);
} }
return ret; return ret;
} }
uint32_t RefCollection::getAt(int i) uint32_t RefCollection::getAt(int i)
{ {
uint32_t tmp = head.get(i); uint32_t tmp = head.get(i);
if (isRef()) if (isRef())
@ -392,27 +392,27 @@ namespace pxt {
return tmp; return tmp;
} }
uint32_t RefCollection::removeAt(int i) uint32_t RefCollection::removeAt(int i)
{ {
if (isRef()) if (isRef())
{ {
decr(head.get(i)); decr(head.get(i));
} }
return head.remove(i); return head.remove(i);
} }
void RefCollection::insertAt(int i, uint32_t value) void RefCollection::insertAt(int i, uint32_t value)
{ {
head.insert(i, value); head.insert(i, value);
if (isRef()) if (isRef())
{ {
incr(value); incr(value);
} }
} }
void RefCollection::setAt(int i, uint32_t value) void RefCollection::setAt(int i, uint32_t value)
{ {
if (isRef()) if (isRef())
{ {
if (head.isValidIndex((uint32_t)i)) if (head.isValidIndex((uint32_t)i))
{ {
@ -423,9 +423,9 @@ namespace pxt {
head.set(i, value); head.set(i, value);
} }
int RefCollection::indexOf(uint32_t x, int start) int RefCollection::indexOf(uint32_t x, int start)
{ {
if (isString()) if (isString())
{ {
StringData *xx = (StringData*)x; StringData *xx = (StringData*)x;
uint32_t i = start; uint32_t i = start;
@ -443,8 +443,8 @@ namespace pxt {
} }
i++; i++;
} }
} }
else else
{ {
uint32_t i = start; uint32_t i = start;
while(head.isValidIndex(i)) while(head.isValidIndex(i))
@ -460,7 +460,7 @@ namespace pxt {
return -1; return -1;
} }
int RefCollection::removeElement(uint32_t x) int RefCollection::removeElement(uint32_t x)
{ {
int idx = indexOf(x, 0); int idx = indexOf(x, 0);
if (idx >= 0) { if (idx >= 0) {