annotate src/dynarr.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents fdefd0186b75
children e38acbeb1cae
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Simple 'n' stupid dynamic-array module.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Copyright (C) 1993 Sun Microsystems, Inc.
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
3 Copyright (C) 2002 Ben Wing.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 under the terms of the GNU General Public License as published by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 Free Software Foundation; either version 2, or (at your option) any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 along with XEmacs; see the file COPYING. If not, write to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 Boston, MA 02111-1307, USA. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 /* Synched up with: Not in FSF. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 /* Written by Ben Wing, December 1993. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 A "dynamic array" is a contiguous array of fixed-size elements where there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 is no upper limit (except available memory) on the number of elements in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 array. Because the elements are maintained contiguously, space is used
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 efficiently (no per-element pointers necessary) and random access to a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 particular element is in constant time. At any one point, the block of memory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 that holds the array has an upper limit; if this limit is exceeded, the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 memory is realloc()ed into a new array that is twice as big. Assuming that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 the time to grow the array is on the order of the new size of the array
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 block, this scheme has a provably constant amortized time (i.e. average
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 time over all additions).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 When you add elements or retrieve elements, pointers are used. Note that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 the element itself (of whatever size it is), and not the pointer to it,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 is stored in the array; thus you do not have to allocate any heap memory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 on your own. Also, returned pointers are only guaranteed to be valid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 until the next operation that changes the length of the array.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 This is a container object. Declare a dynamic array of a specific type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 as follows:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 typedef struct
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 Dynarr_declare (mytype);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 } mytype_dynarr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53 Use the following functions/macros:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 void *Dynarr_new(type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 [MACRO] Create a new dynamic-array object, with each element of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 specified type. The return value is cast to (type##_dynarr).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 This requires following the convention that types are declared in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 such a way that this type concatenation works. In particular, TYPE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 must be a symbol, not an arbitrary C type.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 Dynarr_add(d, el)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 [MACRO] Add an element to the end of a dynamic array. EL is a pointer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 to the element; the element itself is stored in the array, however.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 No function call is performed unless the array needs to be resized.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 Dynarr_add_many(d, base, len)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 [MACRO] Add LEN elements to the end of the dynamic array. The elements
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
69 should be contiguous in memory, starting at BASE. If BASE if NULL,
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
70 just make space for the elements; don't actually add them.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 Dynarr_insert_many_at_start(d, base, len)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 [MACRO] Append LEN elements to the beginning of the dynamic array.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 The elements should be contiguous in memory, starting at BASE.
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
75 If BASE if NULL, just make space for the elements; don't actually
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
76 add them.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 Dynarr_insert_many(d, base, len, start)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79 Insert LEN elements to the dynamic array starting at position
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 START. The elements should be contiguous in memory, starting at BASE.
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
81 If BASE if NULL, just make space for the elements; don't actually
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
82 add them.
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
83
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
84 Dynarr_delete(d, i)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
85 [MACRO] Delete an element from the dynamic array at position I.
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
86
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
87 Dynarr_delete_many(d, start, len)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
88 Delete LEN elements from the dynamic array starting at position
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
89 START.
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
90
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
91 Dynarr_delete_by_pointer(d, p)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
92 [MACRO] Delete an element from the dynamic array at pointer P,
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
93 which must point within the block of memory that stores the data.
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
94 P should be obtained using Dynarr_atp().
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 int Dynarr_length(d)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 [MACRO] Return the number of elements currently in a dynamic array.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 int Dynarr_largest(d)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 [MACRO] Return the maximum value that Dynarr_length(d) would
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 ever have returned.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 type Dynarr_at(d, i)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 [MACRO] Return the element at the specified index (no bounds checking
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 done on the index). The element itself is returned, not a pointer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 to it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 type *Dynarr_atp(d, i)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 [MACRO] Return a pointer to the element at the specified index (no
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 bounds checking done on the index). The pointer may not be valid
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 after an element is added to or removed from the array.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 Dynarr_reset(d)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 [MACRO] Reset the length of a dynamic array to 0.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 Dynarr_free(d)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 Destroy a dynamic array and the memory allocated to it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 Use the following global variable:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 Dynarr_min_size
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 428
diff changeset
122 Minimum allowable size for a dynamic array when it is resized.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 #include "lisp.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 428
diff changeset
129 static int Dynarr_min_size = 8;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 Dynarr_realloc (Dynarr *dy, int new_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 if (DUMPEDP (dy->base))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 void *new_base = malloc (new_size);
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
137 memcpy (new_base, dy->base, dy->max > new_size ? dy->max : new_size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 dy->base = new_base;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 dy->base = xrealloc (dy->base, new_size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 void *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 Dynarr_newf (int elsize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 Dynarr *d = xnew_and_zero (Dynarr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 d->elsize = elsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 return d;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 Dynarr_resize (void *d, int size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 int newsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 double multiplier;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 Dynarr *dy = (Dynarr *) d;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 if (dy->max <= 8)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 multiplier = 2;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 multiplier = 1.5;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 for (newsize = dy->max; newsize < size;)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 newsize = max (Dynarr_min_size, (int) (multiplier * newsize));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 /* Don't do anything if the array is already big enough. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 if (newsize > dy->max)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 Dynarr_realloc (dy, newsize*dy->elsize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 dy->max = newsize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 /* Add a number of contiguous elements to the array starting at START. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 void
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
178 Dynarr_insert_many (void *d, const void *el, int len, int start)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 Dynarr *dy = (Dynarr *) d;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 Dynarr_resize (dy, dy->cur+len);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 /* Silently adjust start to be valid. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 if (start > dy->cur)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 start = dy->cur;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 else if (start < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 start = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 if (start != dy->cur)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 memmove ((char *) dy->base + (start + len)*dy->elsize,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (char *) dy->base + start*dy->elsize,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 (dy->cur - start)*dy->elsize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 }
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
195 if (el)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
196 memcpy ((char *) dy->base + start*dy->elsize, el, len*dy->elsize);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 dy->cur += len;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 if (dy->cur > dy->largest)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 dy->largest = dy->cur;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 Dynarr_delete_many (void *d, int start, int len)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 Dynarr *dy = (Dynarr *) d;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 assert (start >= 0 && len >= 0 && start + len <= dy->cur);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 memmove ((char *) dy->base + start*dy->elsize,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 (char *) dy->base + (start + len)*dy->elsize,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 (dy->cur - start - len)*dy->elsize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 dy->cur -= len;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 Dynarr_free (void *d)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 Dynarr *dy = (Dynarr *) d;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 if (dy->base && !DUMPEDP (dy->base))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 xfree (dy->base);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 if(!DUMPEDP (dy))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 xfree (dy);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 #ifdef MEMORY_USAGE_STATS
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 /* Return memory usage for Dynarr D. The returned value is the total
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 amount of bytes actually being used for the Dynarr, including all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 overhead. The extra amount of space in the Dynarr that is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 allocated beyond what was requested is returned in DYNARR_OVERHEAD
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 in STATS. The extra amount of space that malloc() allocates beyond
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 what was requested of it is returned in MALLOC_OVERHEAD in STATS.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 See the comment above the definition of this structure. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
236 Bytecount
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 Dynarr_memory_usage (void *d, struct overhead_stats *stats)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
239 Bytecount total = 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 Dynarr *dy = (Dynarr *) d;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 /* We have to be a bit tricky here because not all of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 memory that malloc() will claim as "requested" was actually
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 requested. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 if (dy->base)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
248 Bytecount malloc_used = malloced_storage_size (dy->base,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 dy->elsize * dy->max, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 /* #### This may or may not be correct. Some Dynarrs would
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 prefer that we use dy->cur instead of dy->largest here. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 int was_requested = dy->elsize * dy->largest;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 int dynarr_overhead = dy->elsize * (dy->max - dy->largest);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 total += malloc_used;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 stats->was_requested += was_requested;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 stats->dynarr_overhead += dynarr_overhead;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 /* And the remainder must be malloc overhead. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 stats->malloc_overhead +=
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 malloc_used - was_requested - dynarr_overhead;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 total += malloced_storage_size (d, sizeof (*dy), stats);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 return total;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 #endif /* MEMORY_USAGE_STATS */