aboutsummaryrefslogtreecommitdiffstats
path: root/array.c
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2014-02-26 09:36:43 -0500
committerChet Ramey <chet.ramey@case.edu>2014-02-26 09:36:43 -0500
commitac50fbac377e32b98d2de396f016ea81e8ee9961 (patch)
treef71882366b98fedf1a88a063103219a4935de926 /array.c
parent4539d736f1aff232857a854fd2a68df0c98d9f34 (diff)
downloadandroid_external_bash-ac50fbac377e32b98d2de396f016ea81e8ee9961.tar.gz
android_external_bash-ac50fbac377e32b98d2de396f016ea81e8ee9961.tar.bz2
android_external_bash-ac50fbac377e32b98d2de396f016ea81e8ee9961.zip
Bash-4.3 distribution sources and documentation
Diffstat (limited to 'array.c')
-rw-r--r--array.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/array.c b/array.c
index 27fe170..4359a52 100644
--- a/array.c
+++ b/array.c
@@ -58,7 +58,11 @@ static char *array_to_string_internal __P((ARRAY_ELEMENT *, ARRAY_ELEMENT *, cha
static ARRAY *lastarray = 0;
static ARRAY_ELEMENT *lastref = 0;
-#define IS_LASTREF(a) ((a) == lastarray)
+#define IS_LASTREF(a) (lastarray && (a) == lastarray)
+
+#define LASTREF_START(a, i) \
+ (IS_LASTREF(a) && i >= element_index(lastref)) ? lastref \
+ : element_forw(a->head)
#define INVALIDATE_LASTREF(a) \
do { \
@@ -610,7 +614,7 @@ ARRAY *a;
arrayind_t i;
char *v;
{
- register ARRAY_ELEMENT *new, *ae;
+ register ARRAY_ELEMENT *new, *ae, *start;
if (a == 0)
return(-1);
@@ -627,10 +631,17 @@ char *v;
SET_LASTREF(a, new);
return(0);
}
+#if OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT
/*
- * Otherwise we search for the spot to insert it.
+ * Otherwise we search for the spot to insert it. The lastref
+ * handle optimizes the case of sequential or almost-sequential
+ * assignments that are not at the end of the array.
*/
- for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
+ start = LASTREF_START(a, i);
+#else
+ start = element_forw(ae->head);
+#endif
+ for (ae = start; ae != a->head; ae = element_forw(ae)) {
if (element_index(ae) == i) {
/*
* Replacing an existing element.
@@ -647,6 +658,7 @@ char *v;
return(0);
}
}
+ array_dispose_element(new);
INVALIDATE_LASTREF(a);
return (-1); /* problem */
}
@@ -660,18 +672,28 @@ array_remove(a, i)
ARRAY *a;
arrayind_t i;
{
- register ARRAY_ELEMENT *ae;
+ register ARRAY_ELEMENT *ae, *start;
if (a == 0 || array_empty(a))
return((ARRAY_ELEMENT *) NULL);
- for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
+ start = LASTREF_START(a, i);
+ for (ae = start; ae != a->head; ae = element_forw(ae))
if (element_index(ae) == i) {
ae->next->prev = ae->prev;
ae->prev->next = ae->next;
a->num_elements--;
if (i == array_max_index(a))
a->max_index = element_index(ae->prev);
+#if 0
INVALIDATE_LASTREF(a);
+#else
+ if (ae->next != a->head)
+ SET_LASTREF(a, ae->next);
+ else if (ae->prev != a->head)
+ SET_LASTREF(a, ae->prev);
+ else
+ INVALIDATE_LASTREF(a);
+#endif
return(ae);
}
return((ARRAY_ELEMENT *) NULL);
@@ -685,18 +707,14 @@ array_reference(a, i)
ARRAY *a;
arrayind_t i;
{
- register ARRAY_ELEMENT *ae;
+ register ARRAY_ELEMENT *ae, *start;
if (a == 0 || array_empty(a))
return((char *) NULL);
if (i > array_max_index(a))
- return((char *)NULL);
- /* Keep roving pointer into array to optimize sequential access */
- if (lastref && IS_LASTREF(a))
- ae = (i >= element_index(lastref)) ? lastref : element_forw(a->head);
- else
- ae = element_forw(a->head);
- for ( ; ae != a->head; ae = element_forw(ae))
+ return((char *)NULL); /* Keep roving pointer into array to optimize sequential access */
+ start = LASTREF_START(a, i);
+ for (ae = start; ae != a->head; ae = element_forw(ae))
if (element_index(ae) == i) {
SET_LASTREF(a, ae);
return(element_value(ae));