comparison src/rangetab.c @ 5168:cf900a2f1fa3

extract gap array from extents.c, use in range tables -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-03-22 Ben Wing <ben@xemacs.org> * Makefile.in.in (objs): * array.c: * array.c (gap_array_adjust_markers): * array.c (gap_array_move_gap): * array.c (gap_array_make_gap): * array.c (gap_array_insert_els): * array.c (gap_array_delete_els): * array.c (gap_array_make_marker): * array.c (gap_array_delete_marker): * array.c (gap_array_delete_all_markers): * array.c (gap_array_clone): * array.h: * depend: * emacs.c (main_1): * extents.c: * extents.c (EXTENT_GAP_ARRAY_AT): * extents.c (extent_list_num_els): * extents.c (extent_list_locate): * extents.c (extent_list_at): * extents.c (extent_list_delete_all): * extents.c (allocate_extent_list): * extents.c (syms_of_extents): * extents.h: * extents.h (XEXTENT_LIST_MARKER): * lisp.h: * rangetab.c: * rangetab.c (mark_range_table): * rangetab.c (print_range_table): * rangetab.c (range_table_equal): * rangetab.c (range_table_hash): * rangetab.c (verify_range_table): * rangetab.c (get_range_table_pos): * rangetab.c (Fmake_range_table): * rangetab.c (Fcopy_range_table): * rangetab.c (Fget_range_table): * rangetab.c (put_range_table): * rangetab.c (Fclear_range_table): * rangetab.c (Fmap_range_table): * rangetab.c (unified_range_table_bytes_needed): * rangetab.c (unified_range_table_copy_data): * rangetab.c (unified_range_table_lookup): * rangetab.h: * rangetab.h (struct range_table_entry): * rangetab.h (struct Lisp_Range_Table): * rangetab.h (rangetab_gap_array_at): * symsinit.h: Rename dynarr.c to array.c. Move gap array from extents.c to array.c. Extract dynarr, gap array and stack-like malloc into new file array.h. Rename GAP_ARRAY_NUM_ELS -> gap_array_length(). Add gap_array_at(), gap_array_atp(). Rewrite range table code to use gap arrays. Make put_range_table() smarter so that its operation is O(log n) for adding a localized range. * gc.c (lispdesc_block_size_1): Don't ABORT() when two elements are located at the same place. This will happen with a size-0 gap array -- both parts of the array (before and after gap) are in the same place.
author Ben Wing <ben@xemacs.org>
date Mon, 22 Mar 2010 19:12:15 -0500
parents 88bd4f3ef8e4
children 6c6d78781d59
comparison
equal deleted inserted replaced
5167:e374ea766cc1 5168:cf900a2f1fa3
88 mark_range_table (Lisp_Object obj) 88 mark_range_table (Lisp_Object obj)
89 { 89 {
90 Lisp_Range_Table *rt = XRANGE_TABLE (obj); 90 Lisp_Range_Table *rt = XRANGE_TABLE (obj);
91 int i; 91 int i;
92 92
93 for (i = 0; i < Dynarr_length (rt->entries); i++) 93 for (i = 0; i < gap_array_length (rt->entries); i++)
94 mark_object (Dynarr_at (rt->entries, i).val); 94 mark_object (rangetab_gap_array_at (rt->entries, i).val);
95 95
96 return Qnil; 96 return Qnil;
97 } 97 }
98 98
99 static void 99 static void
106 if (print_readably) 106 if (print_readably)
107 write_fmt_string_lisp (printcharfun, "#s(range-table type %s data (", 107 write_fmt_string_lisp (printcharfun, "#s(range-table type %s data (",
108 1, range_table_type_to_symbol (rt->type)); 108 1, range_table_type_to_symbol (rt->type));
109 else 109 else
110 write_ascstring (printcharfun, "#<range-table "); 110 write_ascstring (printcharfun, "#<range-table ");
111 for (i = 0; i < Dynarr_length (rt->entries); i++) 111 for (i = 0; i < gap_array_length (rt->entries); i++)
112 { 112 {
113 struct range_table_entry *rte = Dynarr_atp (rt->entries, i); 113 struct range_table_entry rte = rangetab_gap_array_at (rt->entries, i);
114 int so, ec; 114 int so, ec;
115 if (i > 0) 115 if (i > 0)
116 write_ascstring (printcharfun, " "); 116 write_ascstring (printcharfun, " ");
117 switch (rt->type) 117 switch (rt->type)
118 { 118 {
122 case RANGE_START_OPEN_END_CLOSED: so = 1; ec = 1; break; 122 case RANGE_START_OPEN_END_CLOSED: so = 1; ec = 1; break;
123 default: ABORT (); so = 0, ec = 0; break; 123 default: ABORT (); so = 0, ec = 0; break;
124 } 124 }
125 write_fmt_string (printcharfun, "%c%ld %ld%c ", 125 write_fmt_string (printcharfun, "%c%ld %ld%c ",
126 print_readably ? '(' : so ? '(' : '[', 126 print_readably ? '(' : so ? '(' : '[',
127 (long) (rte->first - so), 127 (long) (rte.first - so),
128 (long) (rte->last - ec), 128 (long) (rte.last - ec),
129 print_readably ? ')' : ec ? ']' : ')' 129 print_readably ? ')' : ec ? ']' : ')'
130 ); 130 );
131 print_internal (rte->val, printcharfun, 1); 131 print_internal (rte.val, printcharfun, 1);
132 } 132 }
133 if (print_readably) 133 if (print_readably)
134 write_ascstring (printcharfun, "))"); 134 write_ascstring (printcharfun, "))");
135 else 135 else
136 write_fmt_string (printcharfun, " 0x%x>", LISP_OBJECT_UID (obj)); 136 write_fmt_string (printcharfun, " 0x%x>", LISP_OBJECT_UID (obj));
141 { 141 {
142 Lisp_Range_Table *rt1 = XRANGE_TABLE (obj1); 142 Lisp_Range_Table *rt1 = XRANGE_TABLE (obj1);
143 Lisp_Range_Table *rt2 = XRANGE_TABLE (obj2); 143 Lisp_Range_Table *rt2 = XRANGE_TABLE (obj2);
144 int i; 144 int i;
145 145
146 if (Dynarr_length (rt1->entries) != Dynarr_length (rt2->entries)) 146 if (gap_array_length (rt1->entries) != gap_array_length (rt2->entries))
147 return 0; 147 return 0;
148 148
149 for (i = 0; i < Dynarr_length (rt1->entries); i++) 149 for (i = 0; i < gap_array_length (rt1->entries); i++)
150 { 150 {
151 struct range_table_entry *rte1 = Dynarr_atp (rt1->entries, i); 151 struct range_table_entry *rte1 =
152 struct range_table_entry *rte2 = Dynarr_atp (rt2->entries, i); 152 rangetab_gap_array_atp (rt1->entries, i);
153 struct range_table_entry *rte2 =
154 rangetab_gap_array_atp (rt2->entries, i);
153 155
154 if (rte1->first != rte2->first 156 if (rte1->first != rte2->first
155 || rte1->last != rte2->last 157 || rte1->last != rte2->last
156 || !internal_equal_0 (rte1->val, rte2->val, depth + 1, foldcase)) 158 || !internal_equal_0 (rte1->val, rte2->val, depth + 1, foldcase))
157 return 0; 159 return 0;
169 static Hashcode 171 static Hashcode
170 range_table_hash (Lisp_Object obj, int depth) 172 range_table_hash (Lisp_Object obj, int depth)
171 { 173 {
172 Lisp_Range_Table *rt = XRANGE_TABLE (obj); 174 Lisp_Range_Table *rt = XRANGE_TABLE (obj);
173 int i; 175 int i;
174 int size = Dynarr_length (rt->entries); 176 int size = gap_array_length (rt->entries);
175 Hashcode hash = size; 177 Hashcode hash = size;
176 178
177 /* approach based on internal_array_hash(). */ 179 /* approach based on internal_array_hash(). */
178 if (size <= 5) 180 if (size <= 5)
179 { 181 {
180 for (i = 0; i < size; i++) 182 for (i = 0; i < size; i++)
181 hash = HASH2 (hash, 183 hash = HASH2 (hash,
182 range_table_entry_hash (Dynarr_atp (rt->entries, i), 184 range_table_entry_hash
183 depth)); 185 (rangetab_gap_array_atp (rt->entries, i), depth));
184 return hash; 186 return hash;
185 } 187 }
186 188
187 /* just pick five elements scattered throughout the array. 189 /* just pick five elements scattered throughout the array.
188 A slightly better approach would be to offset by some 190 A slightly better approach would be to offset by some
189 noise factor from the points chosen below. */ 191 noise factor from the points chosen below. */
190 for (i = 0; i < 5; i++) 192 for (i = 0; i < 5; i++)
191 hash = HASH2 (hash, range_table_entry_hash (Dynarr_atp (rt->entries, 193 hash = HASH2 (hash,
192 i*size/5), 194 range_table_entry_hash
193 depth)); 195 (rangetab_gap_array_atp (rt->entries, i*size/5), depth));
194 return hash; 196 return hash;
195 } 197 }
196 198
197 static const struct memory_description rte_description_1[] = { 199 static const struct memory_description rte_description_1[] = {
198 { XD_LISP_OBJECT, offsetof (range_table_entry, val) }, 200 { XD_LISP_OBJECT, offsetof (range_table_entry, val) },
202 static const struct sized_memory_description rte_description = { 204 static const struct sized_memory_description rte_description = {
203 sizeof (range_table_entry), 205 sizeof (range_table_entry),
204 rte_description_1 206 rte_description_1
205 }; 207 };
206 208
207 static const struct memory_description rted_description_1[] = { 209 static const struct memory_description rtega_description_1[] = {
208 XD_DYNARR_DESC (range_table_entry_dynarr, &rte_description), 210 XD_GAP_ARRAY_DESC (&rte_description),
209 { XD_END } 211 { XD_END }
210 }; 212 };
211 213
212 static const struct sized_memory_description rted_description = { 214 static const struct sized_memory_description rtega_description = {
213 sizeof (range_table_entry_dynarr), 215 0, rtega_description_1
214 rted_description_1
215 }; 216 };
216 217
217 static const struct memory_description range_table_description[] = { 218 static const struct memory_description range_table_description[] = {
218 { XD_BLOCK_PTR, offsetof (Lisp_Range_Table, entries), 1, 219 { XD_BLOCK_PTR, offsetof (Lisp_Range_Table, entries), 1,
219 { &rted_description } }, 220 { &rtega_description } },
220 { XD_END } 221 { XD_END }
221 }; 222 };
222 223
223 DEFINE_DUMPABLE_LISP_OBJECT ("range-table", range_table, 224 DEFINE_DUMPABLE_LISP_OBJECT ("range-table", range_table,
224 mark_range_table, print_range_table, 0, 225 mark_range_table, print_range_table, 0,
235 static void 236 static void
236 verify_range_table (Lisp_Range_Table *rt) 237 verify_range_table (Lisp_Range_Table *rt)
237 { 238 {
238 int i; 239 int i;
239 240
240 for (i = 0; i < Dynarr_length (rt->entries); i++) 241 for (i = 0; i < gap_array_length (rt->entries); i++)
241 { 242 {
242 struct range_table_entry *rte = Dynarr_atp (rt->entries, i); 243 struct range_table_entry *rte = rangetab_gap_array_atp (rt->entries, i);
243 assert (rte->last >= rte->first); 244 assert (rte->last >= rte->first);
244 if (i > 0) 245 if (i > 0)
245 assert (Dynarr_at (rt->entries, i - 1).last <= rte->first); 246 assert (rangetab_gap_array_at (rt->entries, i - 1).last <= rte->first);
246 } 247 }
247 } 248 }
248 249
249 #else 250 #else
250 251
251 #define verify_range_table(rt) 252 #define verify_range_table(rt)
252 253
253 #endif 254 #endif
254 255
255 /* Look up in a range table without the Dynarr wrapper. 256 /* Locate the range table entry corresponding to the value POS, and return
256 Used also by the unified range table format. */ 257 it. If found, FOUNDP is set to 1 and the return value specifies an entry
257 258 that encloses POS. Otherwise, FOUNDP is set to 0 and the return value
258 static Lisp_Object 259 specifies where an entry that encloses POS would be inserted. */
259 get_range_table (EMACS_INT pos, int nentries, struct range_table_entry *tab, 260
260 Lisp_Object default_) 261 static Elemcount
261 { 262 get_range_table_pos (Elemcount pos, Elemcount nentries,
262 int left = 0, right = nentries; 263 struct range_table_entry *tab,
264 Elemcount gappos, Elemcount gapsize,
265 int *foundp)
266 {
267 Elemcount left = 0, right = nentries;
263 268
264 /* binary search for the entry. Based on similar code in 269 /* binary search for the entry. Based on similar code in
265 extent_list_locate(). */ 270 extent_list_locate(). */
266 while (left != right) 271 while (left != right)
267 { 272 {
268 /* RIGHT might not point to a valid entry (i.e. it's at the end 273 /* RIGHT might not point to a valid entry (i.e. it's at the end
269 of the list), so NEWPOS must round down. */ 274 of the list), so NEWPOS must round down. */
270 int newpos = (left + right) >> 1; 275 Elemcount newpos = (left + right) >> 1;
271 struct range_table_entry *entry = tab + newpos; 276 struct range_table_entry *entry =
277 tab + GAP_ARRAY_ARRAY_TO_MEMORY_POS_1 (newpos, gappos, gapsize);
272 if (pos >= entry->last) 278 if (pos >= entry->last)
273 left = newpos + 1; 279 left = newpos + 1;
274 else if (pos < entry->first) 280 else if (pos < entry->first)
275 right = newpos; 281 right = newpos;
276 else 282 else
277 return entry->val; 283 {
284 *foundp = 1;
285 return newpos;
286 }
287 }
288
289 *foundp = 0;
290 return left;
291 }
292
293 /* Look up in a range table without the gap array wrapper.
294 Used also by the unified range table format. */
295
296 static Lisp_Object
297 get_range_table (Elemcount pos, Elemcount nentries,
298 struct range_table_entry *tab,
299 Elemcount gappos, Elemcount gapsize,
300 Lisp_Object default_)
301 {
302 int foundp;
303 Elemcount entrypos = get_range_table_pos (pos, nentries, tab, gappos,
304 gapsize, &foundp);
305 if (foundp)
306 {
307 struct range_table_entry *entry =
308 tab + GAP_ARRAY_ARRAY_TO_MEMORY_POS_1 (entrypos, gappos, gapsize);
309 return entry->val;
278 } 310 }
279 311
280 return default_; 312 return default_;
281 } 313 }
282 314
331 */ 363 */
332 (type)) 364 (type))
333 { 365 {
334 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (range_table); 366 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (range_table);
335 Lisp_Range_Table *rt = XRANGE_TABLE (obj); 367 Lisp_Range_Table *rt = XRANGE_TABLE (obj);
336 rt->entries = Dynarr_new (range_table_entry); 368 rt->entries = make_gap_array (sizeof (struct range_table_entry), 0);
337 rt->type = range_table_symbol_to_type (type); 369 rt->type = range_table_symbol_to_type (type);
338 return obj; 370 return obj;
339 } 371 }
340 372
341 DEFUN ("copy-range-table", Fcopy_range_table, 1, 1, 0, /* 373 DEFUN ("copy-range-table", Fcopy_range_table, 1, 1, 0, /*
345 */ 377 */
346 (range_table)) 378 (range_table))
347 { 379 {
348 Lisp_Range_Table *rt, *rtnew; 380 Lisp_Range_Table *rt, *rtnew;
349 Lisp_Object obj; 381 Lisp_Object obj;
382 Elemcount i;
350 383
351 CHECK_RANGE_TABLE (range_table); 384 CHECK_RANGE_TABLE (range_table);
352 rt = XRANGE_TABLE (range_table); 385 rt = XRANGE_TABLE (range_table);
353 386
354 obj = ALLOC_NORMAL_LISP_OBJECT (range_table); 387 obj = ALLOC_NORMAL_LISP_OBJECT (range_table);
355 rtnew = XRANGE_TABLE (obj); 388 rtnew = XRANGE_TABLE (obj);
356 rtnew->entries = Dynarr_new (range_table_entry); 389 rtnew->entries = make_gap_array (sizeof (struct range_table_entry), 0);
357 rtnew->type = rt->type; 390 rtnew->type = rt->type;
358 391
359 Dynarr_add_many (rtnew->entries, Dynarr_begin (rt->entries), 392 for (i = 0; i < gap_array_length (rt->entries); i++)
360 Dynarr_length (rt->entries)); 393 rtnew->entries =
394 gap_array_insert_els (rtnew->entries, i,
395 rangetab_gap_array_atp (rt->entries, i), 1);
361 return obj; 396 return obj;
362 } 397 }
363 398
364 DEFUN ("get-range-table", Fget_range_table, 2, 3, 0, /* 399 DEFUN ("get-range-table", Fget_range_table, 2, 3, 0, /*
365 Find value for position POS in RANGE-TABLE. 400 Find value for position POS in RANGE-TABLE.
372 CHECK_RANGE_TABLE (range_table); 407 CHECK_RANGE_TABLE (range_table);
373 rt = XRANGE_TABLE (range_table); 408 rt = XRANGE_TABLE (range_table);
374 409
375 CHECK_INT_COERCE_CHAR (pos); 410 CHECK_INT_COERCE_CHAR (pos);
376 411
377 return get_range_table (XINT (pos), Dynarr_length (rt->entries), 412 return get_range_table (XINT (pos), gap_array_length (rt->entries),
378 Dynarr_begin (rt->entries), default_); 413 gap_array_begin (rt->entries,
414 struct range_table_entry),
415 gap_array_gappos (rt->entries),
416 gap_array_gapsize (rt->entries),
417 default_);
379 } 418 }
380 419
381 static void 420 static void
382 external_to_internal_adjust_ends (enum range_table_type type, 421 external_to_internal_adjust_ends (enum range_table_type type,
383 EMACS_INT *first, EMACS_INT *last) 422 EMACS_INT *first, EMACS_INT *last)
413 EMACS_INT last, Lisp_Object val) 452 EMACS_INT last, Lisp_Object val)
414 { 453 {
415 int i; 454 int i;
416 int insert_me_here = -1; 455 int insert_me_here = -1;
417 Lisp_Range_Table *rt = XRANGE_TABLE (table); 456 Lisp_Range_Table *rt = XRANGE_TABLE (table);
457 int foundp;
418 458
419 external_to_internal_adjust_ends (rt->type, &first, &last); 459 external_to_internal_adjust_ends (rt->type, &first, &last);
420 if (first == last) 460 if (first == last)
421 return; 461 return;
422 if (first > last) 462 if (first > last)
423 /* This will happen if originally first == last and both ends are 463 /* This will happen if originally first == last and both ends are
424 open. #### Should we signal an error? */ 464 open. #### Should we signal an error? */
425 return; 465 return;
426 466
467 if (DUMPEDP (rt->entries))
468 rt->entries = gap_array_clone (rt->entries);
469
470 i = get_range_table_pos (first, gap_array_length (rt->entries),
471 gap_array_begin (rt->entries,
472 struct range_table_entry),
473 gap_array_gappos (rt->entries),
474 gap_array_gapsize (rt->entries), &foundp);
475
476 #ifdef ERROR_CHECK_TYPES
477 if (foundp)
478 {
479 if (i < gap_array_length (rt->entries))
480 {
481 struct range_table_entry *entry =
482 rangetab_gap_array_atp (rt->entries, i);
483 assert (first >= entry->first && first < entry->last);
484 }
485 }
486 else
487 {
488 if (i < gap_array_length (rt->entries))
489 {
490 struct range_table_entry *entry =
491 rangetab_gap_array_atp (rt->entries, i);
492 assert (first < entry->first);
493 }
494 if (i > 0)
495 {
496 struct range_table_entry *entry =
497 rangetab_gap_array_atp (rt->entries, i - 1);
498 assert (first >= entry->last);
499 }
500 }
501 #endif /* ERROR_CHECK_TYPES */
502
503 /* If the beginning of the new range isn't within any existing range,
504 it might still be just grazing the end of an end-open range (remember,
505 internally all ranges are start-close end-open); so back up one
506 so we consider this range. */
507 if (!foundp && i > 0)
508 i--;
509
427 /* Now insert in the proper place. This gets tricky because 510 /* Now insert in the proper place. This gets tricky because
428 we may be overlapping one or more existing ranges and need 511 we may be overlapping one or more existing ranges and need
429 to fix them up. */ 512 to fix them up. */
430 513
431 /* First delete all sections of any existing ranges that overlap 514 /* First delete all sections of any existing ranges that overlap
432 the new range. */ 515 the new range. */
433 for (i = 0; i < Dynarr_length (rt->entries); i++) 516 for (; i < gap_array_length (rt->entries); i++)
434 { 517 {
435 struct range_table_entry *entry = Dynarr_atp (rt->entries, i); 518 struct range_table_entry *entry =
519 rangetab_gap_array_atp (rt->entries, i);
436 /* We insert before the first range that begins at or after the 520 /* We insert before the first range that begins at or after the
437 new range. */ 521 new range. */
438 if (entry->first >= first && insert_me_here < 0) 522 if (entry->first >= first && insert_me_here < 0)
439 insert_me_here = i; 523 insert_me_here = i;
440 if (entry->last < first) 524 if (entry->last < first)
474 558
475 insert_me_too.first = last; 559 insert_me_too.first = last;
476 insert_me_too.last = entry->last; 560 insert_me_too.last = entry->last;
477 insert_me_too.val = entry->val; 561 insert_me_too.val = entry->val;
478 entry->last = first; 562 entry->last = first;
479 Dynarr_insert_many (rt->entries, &insert_me_too, 1, i + 1); 563 rt->entries =
564 gap_array_insert_els (rt->entries, i + 1, &insert_me_too, 1);
480 } 565 }
481 else if (entry->last >= last) 566 else if (entry->last >= last)
482 { 567 {
483 /* looks like: 568 /* looks like:
484 569
495 entry->first = last; 580 entry->first = last;
496 } 581 }
497 else 582 else
498 { 583 {
499 /* existing is entirely within new. */ 584 /* existing is entirely within new. */
500 Dynarr_delete_many (rt->entries, i, 1); 585 gap_array_delete_els (rt->entries, i, 1);
501 i--; /* back up since everything shifted one to the left. */ 586 i--; /* back up since everything shifted one to the left. */
502 } 587 }
503 } 588 }
504 589
505 /* Someone asked us to delete the range, not insert it. */ 590 /* Someone asked us to delete the range, not insert it. */
516 601
517 insert_me.first = first; 602 insert_me.first = first;
518 insert_me.last = last; 603 insert_me.last = last;
519 insert_me.val = val; 604 insert_me.val = val;
520 605
521 Dynarr_insert_many (rt->entries, &insert_me, 1, insert_me_here); 606 rt->entries =
607 gap_array_insert_els (rt->entries, insert_me_here, &insert_me, 1);
522 } 608 }
523 609
524 /* Now see if we can combine this entry with adjacent ones just 610 /* Now see if we can combine this entry with adjacent ones just
525 before or after. */ 611 before or after. */
526 612
527 if (insert_me_here > 0) 613 if (insert_me_here > 0)
528 { 614 {
529 struct range_table_entry *entry = Dynarr_atp (rt->entries, 615 struct range_table_entry *entry =
530 insert_me_here - 1); 616 rangetab_gap_array_atp (rt->entries, insert_me_here - 1);
531 if (EQ (val, entry->val) && entry->last == first) 617 if (EQ (val, entry->val) && entry->last == first)
532 { 618 {
533 entry->last = last; 619 entry->last = last;
534 Dynarr_delete_many (rt->entries, insert_me_here, 1); 620 gap_array_delete_els (rt->entries, insert_me_here, 1);
535 insert_me_here--; 621 insert_me_here--;
536 /* We have morphed into a larger range. Update our records 622 /* We have morphed into a larger range. Update our records
537 in case we also combine with the one after. */ 623 in case we also combine with the one after. */
538 first = entry->first; 624 first = entry->first;
539 } 625 }
540 } 626 }
541 627
542 if (insert_me_here < Dynarr_length (rt->entries) - 1) 628 if (insert_me_here < gap_array_length (rt->entries) - 1)
543 { 629 {
544 struct range_table_entry *entry = Dynarr_atp (rt->entries, 630 struct range_table_entry *entry =
545 insert_me_here + 1); 631 rangetab_gap_array_atp (rt->entries, insert_me_here + 1);
546 if (EQ (val, entry->val) && entry->first == last) 632 if (EQ (val, entry->val) && entry->first == last)
547 { 633 {
548 entry->first = first; 634 entry->first = first;
549 Dynarr_delete_many (rt->entries, insert_me_here, 1); 635 gap_array_delete_els (rt->entries, insert_me_here, 1);
550 } 636 }
551 } 637 }
552 } 638 }
553 639
554 DEFUN ("put-range-table", Fput_range_table, 4, 4, 0, /* 640 DEFUN ("put-range-table", Fput_range_table, 4, 4, 0, /*
583 Flush RANGE-TABLE. 669 Flush RANGE-TABLE.
584 */ 670 */
585 (range_table)) 671 (range_table))
586 { 672 {
587 CHECK_RANGE_TABLE (range_table); 673 CHECK_RANGE_TABLE (range_table);
588 Dynarr_reset (XRANGE_TABLE (range_table)->entries); 674 gap_array_delete_all_els (XRANGE_TABLE (range_table)->entries);
589 return Qnil; 675 return Qnil;
590 } 676 }
591 677
592 DEFUN ("map-range-table", Fmap_range_table, 2, 2, 0, /* 678 DEFUN ("map-range-table", Fmap_range_table, 2, 2, 0, /*
593 Map FUNCTION over entries in RANGE-TABLE, calling it with three args, 679 Map FUNCTION over entries in RANGE-TABLE, calling it with three args,
609 695
610 rt = XRANGE_TABLE (range_table); 696 rt = XRANGE_TABLE (range_table);
611 697
612 /* Do not "optimize" by pulling out the length computation below! 698 /* Do not "optimize" by pulling out the length computation below!
613 FUNCTION may have changed the table. */ 699 FUNCTION may have changed the table. */
614 for (i = 0; i < Dynarr_length (rt->entries); i++) 700 for (i = 0; i < gap_array_length (rt->entries); i++)
615 { 701 {
616 struct range_table_entry *entry = Dynarr_atp (rt->entries, i); 702 struct range_table_entry entry =
703 rangetab_gap_array_at (rt->entries, i);
617 EMACS_INT first, last; 704 EMACS_INT first, last;
618 Lisp_Object args[4]; 705 Lisp_Object args[4];
619 int oldlen; 706 int oldlen;
620 707
621 again: 708 again:
622 first = entry->first; 709 first = entry.first;
623 last = entry->last; 710 last = entry.last;
624 oldlen = Dynarr_length (rt->entries); 711 oldlen = gap_array_length (rt->entries);
625 args[0] = function; 712 args[0] = function;
626 /* Fix up the numbers in accordance with the open/closedness of the 713 /* Fix up the numbers in accordance with the open/closedness of the
627 table. */ 714 table. */
628 { 715 {
629 EMACS_INT premier = first, dernier = last; 716 EMACS_INT premier = first, dernier = last;
630 internal_to_external_adjust_ends (rt->type, &premier, &dernier); 717 internal_to_external_adjust_ends (rt->type, &premier, &dernier);
631 args[1] = make_int (premier); 718 args[1] = make_int (premier);
632 args[2] = make_int (dernier); 719 args[2] = make_int (dernier);
633 } 720 }
634 args[3] = entry->val; 721 args[3] = entry.val;
635 Ffuncall (countof (args), args); 722 Ffuncall (countof (args), args);
636 /* Has FUNCTION removed the entry? */ 723 /* Has FUNCTION removed the entry? */
637 if (oldlen > Dynarr_length (rt->entries) 724 if (oldlen > gap_array_length (rt->entries)
638 && i < Dynarr_length (rt->entries) 725 && i < gap_array_length (rt->entries)
639 && (first != entry->first || last != entry->last)) 726 && (first != entry.first || last != entry.last))
640 goto again; 727 goto again;
641 } 728 }
642 729
643 return Qnil; 730 return Qnil;
644 } 731 }
776 863
777 int 864 int
778 unified_range_table_bytes_needed (Lisp_Object rangetab) 865 unified_range_table_bytes_needed (Lisp_Object rangetab)
779 { 866 {
780 return (sizeof (struct range_table_entry) * 867 return (sizeof (struct range_table_entry) *
781 (Dynarr_length (XRANGE_TABLE (rangetab)->entries) - 1) + 868 (gap_array_length (XRANGE_TABLE (rangetab)->entries) - 1) +
782 sizeof (struct unified_range_table) + 869 sizeof (struct unified_range_table) +
783 /* ALIGNOF a struct may be too big. */ 870 /* ALIGNOF a struct may be too big. */
784 /* We have four bytes for the size numbers, and an extra 871 /* We have four bytes for the size numbers, and an extra
785 four or eight bytes for making sure we get the alignment 872 four or eight bytes for making sure we get the alignment
786 OK. */ 873 OK. */
796 { 883 {
797 /* We cast to the above structure rather than just casting to 884 /* We cast to the above structure rather than just casting to
798 char * and adding sizeof(int), because that will lead to 885 char * and adding sizeof(int), because that will lead to
799 mis-aligned data on the Alpha machines. */ 886 mis-aligned data on the Alpha machines. */
800 struct unified_range_table *un; 887 struct unified_range_table *un;
801 range_table_entry_dynarr *rted = XRANGE_TABLE (rangetab)->entries; 888 Gap_Array *rtega = XRANGE_TABLE (rangetab)->entries;
802 int total_needed = unified_range_table_bytes_needed (rangetab); 889 int total_needed = unified_range_table_bytes_needed (rangetab);
803 void *new_dest = ALIGN_PTR ((char *) dest + 4, EMACS_INT); 890 void *new_dest = ALIGN_PTR ((char *) dest + 4, EMACS_INT);
891 Elemcount i;
804 892
805 * (char *) dest = (char) ((char *) new_dest - (char *) dest); 893 * (char *) dest = (char) ((char *) new_dest - (char *) dest);
806 * ((unsigned char *) dest + 1) = total_needed & 0xFF; 894 * ((unsigned char *) dest + 1) = total_needed & 0xFF;
807 total_needed >>= 8; 895 total_needed >>= 8;
808 * ((unsigned char *) dest + 2) = total_needed & 0xFF; 896 * ((unsigned char *) dest + 2) = total_needed & 0xFF;
809 total_needed >>= 8; 897 total_needed >>= 8;
810 * ((unsigned char *) dest + 3) = total_needed & 0xFF; 898 * ((unsigned char *) dest + 3) = total_needed & 0xFF;
811 un = (struct unified_range_table *) new_dest; 899 un = (struct unified_range_table *) new_dest;
812 un->nentries = Dynarr_length (rted); 900 un->nentries = gap_array_length (rtega);
813 un->type = XRANGE_TABLE (rangetab)->type; 901 un->type = XRANGE_TABLE (rangetab)->type;
814 memcpy (&un->first, Dynarr_begin (rted), 902 for (i = 0; i < gap_array_length (rtega); i++)
815 sizeof (struct range_table_entry) * Dynarr_length (rted)); 903 (&un->first)[i] = rangetab_gap_array_at (rtega, i);
816 } 904 }
817 905
818 /* Return number of bytes actually used by a unified range table. */ 906 /* Return number of bytes actually used by a unified range table. */
819 907
820 int 908 int
853 941
854 align_the_damn_table (unrangetab); 942 align_the_damn_table (unrangetab);
855 new_dest = (char *) unrangetab + * (char *) unrangetab; 943 new_dest = (char *) unrangetab + * (char *) unrangetab;
856 un = (struct unified_range_table *) new_dest; 944 un = (struct unified_range_table *) new_dest;
857 945
858 return get_range_table (pos, un->nentries, &un->first, default_); 946 return get_range_table (pos, un->nentries, &un->first, 0, 0, default_);
859 } 947 }
860 948
861 /* Return number of entries in a unified range table. */ 949 /* Return number of entries in a unified range table. */
862 950
863 int 951 int