comparison src/rangetab.c @ 185:3d6bfa290dbd r20-3b19

Import from CVS: tag r20-3b19
author cvs
date Mon, 13 Aug 2007 09:55:28 +0200
parents 8eaf7971accc
children c5d627a313b1
comparison
equal deleted inserted replaced
184:bcd2674570bf 185:3d6bfa290dbd
24 /* Written by Ben Wing, August 1995. */ 24 /* Written by Ben Wing, August 1995. */
25 25
26 #include <config.h> 26 #include <config.h>
27 #include "lisp.h" 27 #include "lisp.h"
28 28
29 typedef struct range_table_entry range_table_entry;
29 struct range_table_entry 30 struct range_table_entry
30 { 31 {
31 EMACS_INT first; 32 EMACS_INT first;
32 EMACS_INT last; 33 EMACS_INT last;
33 Lisp_Object val; 34 Lisp_Object val;
34 }; 35 };
35 36
36 typedef struct range_table_entry_dynarr_type 37 typedef struct
37 { 38 {
38 Dynarr_declare (struct range_table_entry); 39 Dynarr_declare (range_table_entry);
39 } range_table_entry_dynarr; 40 } range_table_entry_dynarr;
40 41
41 struct Lisp_Range_Table 42 struct Lisp_Range_Table
42 { 43 {
43 struct lcrecord_header header; 44 struct lcrecord_header header;
115 struct Lisp_Range_Table *rt2 = XRANGE_TABLE (obj2); 116 struct Lisp_Range_Table *rt2 = XRANGE_TABLE (obj2);
116 int i; 117 int i;
117 118
118 if (Dynarr_length (rt1->entries) != Dynarr_length (rt2->entries)) 119 if (Dynarr_length (rt1->entries) != Dynarr_length (rt2->entries))
119 return 0; 120 return 0;
120 121
121 for (i = 0; i < Dynarr_length (rt1->entries); i++) 122 for (i = 0; i < Dynarr_length (rt1->entries); i++)
122 { 123 {
123 struct range_table_entry *rte1 = Dynarr_atp (rt1->entries, i); 124 struct range_table_entry *rte1 = Dynarr_atp (rt1->entries, i);
124 struct range_table_entry *rte2 = Dynarr_atp (rt2->entries, i); 125 struct range_table_entry *rte2 = Dynarr_atp (rt2->entries, i);
125 126
153 hash = HASH2 (hash, 154 hash = HASH2 (hash,
154 range_table_entry_hash (Dynarr_atp (rt->entries, i), 155 range_table_entry_hash (Dynarr_atp (rt->entries, i),
155 depth)); 156 depth));
156 return hash; 157 return hash;
157 } 158 }
158 159
159 /* just pick five elements scattered throughout the array. 160 /* just pick five elements scattered throughout the array.
160 A slightly better approach would be to offset by some 161 A slightly better approach would be to offset by some
161 noise factor from the points chosen below. */ 162 noise factor from the points chosen below. */
162 for (i = 0; i < 5; i++) 163 for (i = 0; i < 5; i++)
163 hash = HASH2 (hash, range_table_entry_hash (Dynarr_atp (rt->entries, 164 hash = HASH2 (hash, range_table_entry_hash (Dynarr_atp (rt->entries,
200 static Lisp_Object 201 static Lisp_Object
201 get_range_table (EMACS_INT pos, int nentries, struct range_table_entry *tab, 202 get_range_table (EMACS_INT pos, int nentries, struct range_table_entry *tab,
202 Lisp_Object default_) 203 Lisp_Object default_)
203 { 204 {
204 int left = 0, right = nentries; 205 int left = 0, right = nentries;
205 206
206 /* binary search for the entry. Based on similar code in 207 /* binary search for the entry. Based on similar code in
207 extent_list_locate(). */ 208 extent_list_locate(). */
208 while (left != right) 209 while (left != right)
209 { 210 {
210 /* RIGHT might not point to a valid entry (i.e. it's at the end 211 /* RIGHT might not point to a valid entry (i.e. it's at the end
235 You can manipulate it using `put-range-table', `get-range-table', 236 You can manipulate it using `put-range-table', `get-range-table',
236 `remove-range-table', and `clear-range-table'. 237 `remove-range-table', and `clear-range-table'.
237 */ 238 */
238 ()) 239 ())
239 { 240 {
240 struct Lisp_Range_Table *rt;
241 Lisp_Object obj; 241 Lisp_Object obj;
242 242 struct Lisp_Range_Table *rt = alloc_lcrecord_type (struct Lisp_Range_Table,
243 rt = (struct Lisp_Range_Table *) 243 lrecord_range_table);
244 alloc_lcrecord (sizeof (struct Lisp_Range_Table), lrecord_range_table); 244 rt->entries = Dynarr_new (range_table_entry);
245 rt->entries = Dynarr_new (struct range_table_entry);
246 XSETRANGE_TABLE (obj, rt); 245 XSETRANGE_TABLE (obj, rt);
247 return obj; 246 return obj;
248 } 247 }
249 248
250 DEFUN ("copy-range-table", Fcopy_range_table, 1, 1, 0, /* 249 DEFUN ("copy-range-table", Fcopy_range_table, 1, 1, 0, /*
256 struct Lisp_Range_Table *rt, *rtnew; 255 struct Lisp_Range_Table *rt, *rtnew;
257 Lisp_Object obj = Qnil; 256 Lisp_Object obj = Qnil;
258 257
259 CHECK_RANGE_TABLE (old_table); 258 CHECK_RANGE_TABLE (old_table);
260 rt = XRANGE_TABLE (old_table); 259 rt = XRANGE_TABLE (old_table);
261 rtnew = (struct Lisp_Range_Table *) 260
262 alloc_lcrecord (sizeof (struct Lisp_Range_Table), lrecord_range_table); 261 rtnew = alloc_lcrecord_type (struct Lisp_Range_Table, lrecord_range_table);
263 rtnew->entries = Dynarr_new (struct range_table_entry); 262 rtnew->entries = Dynarr_new (range_table_entry);
264 263
265 Dynarr_add_many (rtnew->entries, Dynarr_atp (rt->entries, 0), 264 Dynarr_add_many (rtnew->entries, Dynarr_atp (rt->entries, 0),
266 Dynarr_length (rt->entries)); 265 Dynarr_length (rt->entries));
267 XSETRANGE_TABLE (obj, rtnew); 266 XSETRANGE_TABLE (obj, rtnew);
268 return obj; 267 return obj;
329 else if (entry->first < first && entry->last > last) 328 else if (entry->first < first && entry->last > last)
330 /* looks like: 329 /* looks like:
331 330
332 [ NEW ] 331 [ NEW ]
333 [ EXISTING ] 332 [ EXISTING ]
334 333
335 */ 334 */
336 /* need to split this one in two. */ 335 /* need to split this one in two. */
337 { 336 {
338 struct range_table_entry insert_me_too; 337 struct range_table_entry insert_me_too;
339 338
340 insert_me_too.first = last + 1; 339 insert_me_too.first = last + 1;
341 insert_me_too.last = entry->last; 340 insert_me_too.last = entry->last;
342 insert_me_too.val = entry->val; 341 insert_me_too.val = entry->val;
343 entry->last = first - 1; 342 entry->last = first - 1;
344 Dynarr_insert_many (rt->entries, &insert_me_too, 1, i + 1); 343 Dynarr_insert_many (rt->entries, &insert_me_too, 1, i + 1);
345 } 344 }
346 else if (entry->last > last) 345 else if (entry->last > last)
347 { 346 {
348 /* looks like: 347 /* looks like:
349 348
350 [ NEW ] 349 [ NEW ]
351 [ EXISTING ] 350 [ EXISTING ]
352 351
353 */ 352 */
354 /* truncate the start off of it. */ 353 /* truncate the start off of it. */
363 } 362 }
364 363
365 /* Someone asked us to delete the range, not insert it. */ 364 /* Someone asked us to delete the range, not insert it. */
366 if (UNBOUNDP (val)) 365 if (UNBOUNDP (val))
367 return; 366 return;
368 367
369 /* Now insert the new entry, maybe at the end. */ 368 /* Now insert the new entry, maybe at the end. */
370 369
371 if (insert_me_here < 0) 370 if (insert_me_here < 0)
372 insert_me_here = i; 371 insert_me_here = i;
373 372
374 { 373 {
375 struct range_table_entry insert_me; 374 struct range_table_entry insert_me;
376 375
377 insert_me.first = first; 376 insert_me.first = first;
378 insert_me.last = last; 377 insert_me.last = last;
379 insert_me.val = val; 378 insert_me.val = val;
380 379
381 Dynarr_insert_many (rt->entries, &insert_me, 1, insert_me_here); 380 Dynarr_insert_many (rt->entries, &insert_me, 1, insert_me_here);
382 } 381 }
383 382
384 /* Now see if we can combine this entry with adjacent ones just 383 /* Now see if we can combine this entry with adjacent ones just
385 before or after. */ 384 before or after. */
386 385
387 if (insert_me_here > 0) 386 if (insert_me_here > 0)
388 { 387 {
389 struct range_table_entry *entry = Dynarr_atp (rt->entries, 388 struct range_table_entry *entry = Dynarr_atp (rt->entries,
390 insert_me_here - 1); 389 insert_me_here - 1);
391 if (EQ (val, entry->val) && entry->last == first - 1) 390 if (EQ (val, entry->val) && entry->last == first - 1)
498 data = Fcar (Fcdr (data)); /* skip over 'data keyword */ 497 data = Fcar (Fcdr (data)); /* skip over 'data keyword */
499 while (!NILP (data)) 498 while (!NILP (data))
500 { 499 {
501 Lisp_Object range = Fcar (data); 500 Lisp_Object range = Fcar (data);
502 Lisp_Object val = Fcar (Fcdr (data)); 501 Lisp_Object val = Fcar (Fcdr (data));
503 502
504 data = Fcdr (Fcdr (data)); 503 data = Fcdr (Fcdr (data));
505 if (CONSP (range)) 504 if (CONSP (range))
506 Fput_range_table (Fcar (range), Fcar (Fcdr (range)), val, 505 Fput_range_table (Fcar (range), Fcar (Fcdr (range)), val,
507 rangetab); 506 rangetab);
508 else 507 else
554 for modifying a unified range table. The only operations 553 for modifying a unified range table. The only operations
555 you can do to unified range tables are 554 you can do to unified range tables are
556 555
557 -- look up a value 556 -- look up a value
558 -- retrieve all the ranges in an iterative fashion 557 -- retrieve all the ranges in an iterative fashion
559 558
560 */ 559 */
561 560
562 /* The format of a unified range table is as follows: 561 /* The format of a unified range table is as follows:
563 562
564 -- The first byte contains the number of bytes to skip to find the 563 -- The first byte contains the number of bytes to skip to find the
577 struct unified_range_table 576 struct unified_range_table
578 { 577 {
579 int nentries; 578 int nentries;
580 struct range_table_entry first; 579 struct range_table_entry first;
581 }; 580 };
582 581
583 /* Return size in bytes needed to store the data in a range table. */ 582 /* Return size in bytes needed to store the data in a range table. */
584 583
585 int 584 int
586 unified_range_table_bytes_needed (Lisp_Object rangetab) 585 unified_range_table_bytes_needed (Lisp_Object rangetab)
587 { 586 {
630 return ((* ((unsigned char *) unrangetab + 1)) 629 return ((* ((unsigned char *) unrangetab + 1))
631 + ((* ((unsigned char *) unrangetab + 2)) << 8) 630 + ((* ((unsigned char *) unrangetab + 2)) << 8)
632 + ((* ((unsigned char *) unrangetab + 3)) << 16)); 631 + ((* ((unsigned char *) unrangetab + 3)) << 16));
633 } 632 }
634 633
635 /* Make sure the table is aligned, and move it around if it's not. */ 634 /* Make sure the table is aligned, and move it around if it's not. */
636 static void 635 static void
637 align_the_damn_table (void *unrangetab) 636 align_the_damn_table (void *unrangetab)
638 { 637 {
639 void *cur_dest = (char *) unrangetab + * (char *) unrangetab; 638 void *cur_dest = (char *) unrangetab + * (char *) unrangetab;
640 #if LONGBITS == 64 639 #if LONGBITS == 64
651 /* memmove() works in the presence of overlapping data. */ 650 /* memmove() works in the presence of overlapping data. */
652 memmove (new_dest, cur_dest, count); 651 memmove (new_dest, cur_dest, count);
653 * (char *) unrangetab = (char) ((char *) new_dest - (char *) unrangetab); 652 * (char *) unrangetab = (char) ((char *) new_dest - (char *) unrangetab);
654 } 653 }
655 } 654 }
656 655
657 /* Look up a value in a unified range table. */ 656 /* Look up a value in a unified range table. */
658 657
659 Lisp_Object 658 Lisp_Object
660 unified_range_table_lookup (void *unrangetab, EMACS_INT pos, 659 unified_range_table_lookup (void *unrangetab, EMACS_INT pos,
661 Lisp_Object default_) 660 Lisp_Object default_)