00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdlib.h>
00026 #include <errno.h>
00027
00028 #include "segcol.h"
00029 #include "segcol_internal.h"
00030 #include "segcol_list.h"
00031 #include "type_limits.h"
00032 #include "list.h"
00033 #include "debug.h"
00034
00035 struct segment_entry {
00036 struct list_node ln;
00037 segment_t *segment;
00038 };
00039
00040 struct segcol_list_iter_impl {
00041 struct list_node *node;
00042 off_t mapping;
00043 };
00044
00045 struct segcol_list_impl {
00046 list_t *list;
00047 struct list_node *cached_node;
00048 off_t cached_mapping;
00049 };
00050
00051
00052
00053
00054 static int find_seg_entry(segcol_t *segcol,
00055 struct segment_entry **snode, off_t *mapping, off_t offset);
00056 static int segcol_list_clear_cache(struct segcol_list_impl *impl);
00057 static int segcol_list_set_cache(struct segcol_list_impl *impl,
00058 struct list_node *node, off_t mapping);
00059
00060
00061 int segcol_list_new(segcol_t **segcol);
00062 static int segcol_list_free(segcol_t *segcol);
00063 static int segcol_list_append(segcol_t *segcol, segment_t *seg);
00064 static int segcol_list_insert(segcol_t *segcol, off_t offset, segment_t *seg);
00065 static int segcol_list_delete(segcol_t *segcol, segcol_t **deleted, off_t offset, off_t length);
00066 static int segcol_list_find(segcol_t *segcol, segcol_iter_t **iter, off_t offset);
00067 static int segcol_list_iter_new(segcol_t *segcol, void **iter);
00068 static int segcol_list_iter_next(segcol_iter_t *iter);
00069 static int segcol_list_iter_is_valid(segcol_iter_t *iter, int *valid);
00070 static int segcol_list_iter_get_segment(segcol_iter_t *iter, segment_t **seg);
00071 static int segcol_list_iter_get_mapping(segcol_iter_t *iter, off_t *mapping);
00072 static int segcol_list_iter_free(segcol_iter_t *iter);
00073
00074
00075 static struct segcol_funcs segcol_list_funcs = {
00076 .free = segcol_list_free,
00077 .append = segcol_list_append,
00078 .insert = segcol_list_insert,
00079 .delete = segcol_list_delete,
00080 .find = segcol_list_find,
00081 .iter_new = segcol_list_iter_new,
00082 .iter_next = segcol_list_iter_next,
00083 .iter_is_valid = segcol_list_iter_is_valid,
00084 .iter_get_segment = segcol_list_iter_get_segment,
00085 .iter_get_mapping = segcol_list_iter_get_mapping,
00086 .iter_free = segcol_list_iter_free
00087 };
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 static int find_seg_entry(segcol_t *segcol,
00100 struct segment_entry **entry, off_t *mapping, off_t offset)
00101 {
00102 segcol_iter_t *iter = NULL;
00103 int err = segcol_find(segcol, &iter, offset);
00104
00105 if (err)
00106 return_error(err);
00107
00108 int valid = 0;
00109 if (segcol_iter_is_valid(iter, &valid) || !valid) {
00110 *entry = NULL;
00111 } else {
00112 struct segcol_list_iter_impl *iter_impl = segcol_iter_get_impl(iter);
00113 *entry = list_entry(iter_impl->node, struct segment_entry, ln);
00114 *mapping = iter_impl->mapping;
00115 }
00116
00117 segcol_iter_free(iter);
00118
00119 return 0;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129 static int segcol_list_clear_cache(struct segcol_list_impl *impl)
00130 {
00131 if (impl == NULL)
00132 return_error(EINVAL);
00133
00134 impl->cached_node = NULL;
00135 impl->cached_mapping = 0;
00136
00137 return 0;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 static int segcol_list_set_cache(struct segcol_list_impl *impl,
00150 struct list_node *node, off_t mapping)
00151 {
00152 if (impl == NULL || node == NULL)
00153 return_error(EINVAL);
00154
00155 impl->cached_node = node;
00156 impl->cached_mapping = mapping;
00157
00158 return 0;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 static int segcol_list_get_closest_node(segcol_t *segcol,
00172 struct list_node **node, off_t *mapping, off_t offset)
00173 {
00174 off_t segcol_size;
00175 segcol_get_size(segcol, &segcol_size);
00176
00177 struct segcol_list_impl *impl =
00178 (struct segcol_list_impl *) segcol_get_impl(segcol);
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 off_t dist_from_cache = __MAX(off_t);
00192 if (impl->cached_node != NULL) {
00193 *node = impl->cached_node;
00194 *mapping = impl->cached_mapping;
00195 if (offset > *mapping)
00196 dist_from_cache = offset - *mapping;
00197 else
00198 dist_from_cache = *mapping - offset;
00199 }
00200
00201 off_t dist_from_head = offset;
00202 off_t dist_from_tail = segcol_size - offset;
00203
00204
00205
00206
00207
00208 off_t cur_min = dist_from_cache;
00209
00210 if (dist_from_head < cur_min) {
00211 *node = list_head(impl->list)->next;
00212 *mapping = 0;
00213 cur_min = dist_from_head;
00214 }
00215
00216 if (dist_from_tail < cur_min) {
00217 *node = list_tail(impl->list)->prev;
00218
00219 struct segment_entry *snode =
00220 list_entry(*node, struct segment_entry, ln);
00221 off_t seg_size;
00222 segment_get_size(snode->segment, &seg_size);
00223
00224 *mapping = segcol_size - seg_size;
00225 }
00226
00227 return 0;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 int segcol_list_new(segcol_t **segcol)
00242 {
00243 if (segcol == NULL)
00244 return_error(EINVAL);
00245
00246
00247 struct segcol_list_impl *impl = malloc(sizeof(struct segcol_list_impl));
00248
00249 if (impl == NULL)
00250 return_error(EINVAL);
00251
00252
00253 int err = list_new(&impl->list, struct segment_entry, ln);
00254 if (err)
00255 return_error(err);
00256
00257 segcol_list_clear_cache(impl);
00258
00259
00260 err = segcol_create_impl(segcol, impl, &segcol_list_funcs);
00261
00262 if (err) {
00263 list_free(impl->list);
00264 free(impl);
00265 return_error(err);
00266 }
00267
00268 return 0;
00269 }
00270
00271 static int segcol_list_free(segcol_t *segcol)
00272 {
00273 if (segcol == NULL)
00274 return_error(EINVAL);
00275
00276 struct segcol_list_impl *impl =
00277 (struct segcol_list_impl *) segcol_get_impl(segcol);
00278
00279 struct list_node *node;
00280 struct list_node *tmp;
00281
00282
00283 list_for_each_safe(list_head(impl->list)->next, node, tmp) {
00284 struct segment_entry *snode = list_entry(node, struct segment_entry, ln);
00285 if (snode->segment != NULL)
00286 segment_free(snode->segment);
00287 free(snode);
00288 }
00289
00290 list_free(impl->list);
00291
00292 free(impl);
00293
00294 return 0;
00295 }
00296
00297 static int segcol_list_append(segcol_t *segcol, segment_t *seg)
00298 {
00299 if (segcol == NULL || seg == NULL)
00300 return_error(EINVAL);
00301
00302
00303
00304
00305
00306 off_t seg_size;
00307 segment_get_size(seg, &seg_size);
00308 if (seg_size == 0) {
00309 segment_free(seg);
00310 return 0;
00311 }
00312
00313 struct segcol_list_impl *impl =
00314 (struct segcol_list_impl *) segcol_get_impl(segcol);
00315
00316 struct segment_entry *new_entry;
00317 new_entry = malloc(sizeof(struct segment_entry));
00318 if (new_entry == NULL)
00319 return_error(ENOMEM);
00320
00321 new_entry->segment = seg;
00322
00323
00324 list_insert_before(list_tail(impl->list), &new_entry->ln);
00325
00326
00327 off_t segcol_size;
00328 segcol_get_size(segcol, &segcol_size);
00329 segcol_list_set_cache(impl, &new_entry->ln, segcol_size);
00330
00331 return 0;
00332 }
00333
00334 static int segcol_list_insert(segcol_t *segcol, off_t offset, segment_t *seg)
00335 {
00336 if (segcol == NULL || seg == NULL || offset < 0)
00337 return_error(EINVAL);
00338
00339 struct segcol_list_impl *impl =
00340 (struct segcol_list_impl *) segcol_get_impl(segcol);
00341
00342
00343 segcol_iter_t *iter;
00344 int err = segcol_list_find(segcol, &iter, offset);
00345 if (err)
00346 return_error(err);
00347
00348
00349
00350
00351
00352
00353
00354 off_t seg_size;
00355 segment_get_size(seg, &seg_size);
00356 if (seg_size == 0) {
00357 segment_free(seg);
00358 segcol_iter_free(iter);
00359 return 0;
00360 }
00361
00362 segcol_list_clear_cache(impl);
00363
00364 segment_t *pseg;
00365 segcol_list_iter_get_segment(iter, &pseg);
00366
00367 off_t mapping;
00368 segcol_list_iter_get_mapping(iter, &mapping);
00369
00370 struct segcol_list_iter_impl *iter_impl =
00371 (struct segcol_list_iter_impl *) segcol_iter_get_impl(iter);
00372
00373 struct segment_entry *pentry =
00374 list_entry(iter_impl->node, struct segment_entry, ln);
00375
00376 segcol_iter_free(iter);
00377
00378
00379 struct segment_entry *qentry;
00380 qentry = malloc(sizeof(struct segment_entry));
00381 if (qentry == NULL)
00382 return_error(ENOMEM);
00383
00384 qentry->segment = seg;
00385
00386
00387
00388
00389
00390
00391 off_t split_index = offset - mapping;
00392
00393
00394
00395 if (split_index == 0) {
00396 list_insert_before(&pentry->ln, &qentry->ln);
00397 } else {
00398 segment_t *rseg;
00399 err = segment_split(pseg, &rseg, split_index);
00400 if (err)
00401 return_error(err);
00402
00403 struct segment_entry *rentry;
00404 rentry = malloc(sizeof(struct segment_entry));
00405 if (rentry == NULL) {
00406 segment_merge(pseg, rseg);
00407 segment_free(rseg);
00408 return_error(ENOMEM);
00409 }
00410 rentry->segment = rseg;
00411
00412 list_insert_after(&pentry->ln, &qentry->ln);
00413 list_insert_after(&qentry->ln, &rentry->ln);
00414 }
00415
00416
00417 segcol_list_set_cache(impl, &qentry->ln, offset);
00418
00419 return 0;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 static int segcol_list_delete(segcol_t *segcol, segcol_t **deleted, off_t
00438 offset, off_t length)
00439 {
00440 if (segcol == NULL || offset < 0 || length < 0)
00441 return_error(EINVAL);
00442
00443
00444 if (__MAX(off_t) - offset < length - 1 * (length != 0))
00445 return_error(EOVERFLOW);
00446
00447 struct segcol_list_impl *impl =
00448 (struct segcol_list_impl *) segcol_get_impl(segcol);
00449
00450 struct segment_entry *first_entry = NULL;
00451 struct segment_entry *last_entry = NULL;
00452 off_t first_mapping = -1;
00453 off_t last_mapping = -1;
00454
00455
00456 int err = find_seg_entry(segcol, &first_entry, &first_mapping, offset);
00457 if (err)
00458 return_error(err);
00459
00460
00461
00462
00463
00464
00465 if (length == 0) {
00466
00467 if (deleted != NULL) {
00468 err = segcol_list_new(deleted);
00469 if (err)
00470 return_error(err);
00471 }
00472 return 0;
00473 }
00474
00475 err = find_seg_entry(segcol, &last_entry, &last_mapping,
00476 offset + length - 1 * (length != 0));
00477
00478 if (err)
00479 return_error(err);
00480
00481 if (first_entry == NULL || last_entry == NULL
00482 || first_entry->segment == NULL || last_entry->segment == NULL)
00483 return_error(EINVAL);
00484
00485 segcol_list_clear_cache(impl);
00486
00487
00488
00489
00490
00491
00492
00493 struct segment_entry *entry_a;
00494 struct segment_entry *entry_b;
00495
00496 entry_a = malloc(sizeof(struct segment_entry));
00497 if (entry_a == NULL)
00498 return_error(ENOMEM);
00499 entry_b = malloc(sizeof(struct segment_entry));
00500 if (entry_b == NULL) {
00501 free(entry_a);
00502 return_error(ENOMEM);
00503 }
00504
00505
00506
00507
00508
00509 struct segment_entry *entry_a_prev =
00510 list_entry(first_entry->ln.prev, struct segment_entry, ln);
00511
00512 struct segment_entry *entry_b_next =
00513 list_entry(last_entry->ln.next, struct segment_entry, ln);
00514
00515
00516 list_delete_chain(&first_entry->ln, &last_entry->ln);
00517
00518
00519 off_t new_size;
00520 segcol_get_size(segcol, &new_size);
00521
00522 off_t last_seg_size;
00523 segment_get_size(last_entry->segment, &last_seg_size);
00524
00525 new_size -= last_mapping + last_seg_size - first_mapping;
00526
00527
00528
00529
00530
00531
00532
00533
00534 if (first_mapping < offset) {
00535 segment_t *tmp_seg;
00536 err = segment_split(first_entry->segment, &tmp_seg, offset - first_mapping);
00537 if (err)
00538 goto fail_first_entry;
00539
00540 entry_a->segment = first_entry->segment;
00541 first_entry->segment = tmp_seg;
00542 } else {
00543 free(entry_a);
00544 entry_a = NULL;
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554 if (last_mapping + last_seg_size > offset + length) {
00555
00556
00557
00558
00559
00560
00561 int last_seg_dec = 0;
00562
00563 if (first_entry == last_entry)
00564 last_seg_dec = offset - first_mapping;
00565
00566 segment_t *tmp_seg;
00567 err = segment_split(last_entry->segment, &tmp_seg,
00568 offset + length - last_mapping - last_seg_dec);
00569 if (err)
00570 goto fail_last_entry;
00571
00572 entry_b->segment = tmp_seg;
00573 } else {
00574 free(entry_b);
00575 entry_b = NULL;
00576 }
00577
00578
00579
00580
00581
00582 if (entry_a != NULL)
00583 list_insert_after(&entry_a_prev->ln, &entry_a->ln);
00584
00585 if (entry_b != NULL)
00586 list_insert_before(&entry_b_next->ln, &entry_b->ln);
00587
00588
00589 segcol_t *deleted_tmp;
00590 err = segcol_list_new(&deleted_tmp);
00591 if (err)
00592 goto fail_segcol_new_deleted;
00593
00594 struct segcol_list_impl *deleted_impl =
00595 (struct segcol_list_impl *) segcol_get_impl(deleted_tmp);
00596
00597 list_insert_chain_after(list_head(deleted_impl->list), &first_entry->ln,
00598 &last_entry->ln);
00599
00600
00601 if (deleted != NULL)
00602 *deleted = deleted_tmp;
00603 else
00604 segcol_free(deleted_tmp);
00605
00606
00607 if (entry_b != NULL)
00608 segcol_list_set_cache(impl, &entry_b->ln, offset);
00609 else if (entry_b_next->ln.next != &entry_b_next->ln)
00610 segcol_list_set_cache(impl, &entry_b_next->ln, offset);
00611
00612 return 0;
00613
00614
00615
00616
00617 fail_segcol_new_deleted:
00618 if (entry_b != NULL)
00619 list_delete_chain(&entry_b->ln, &entry_b->ln);
00620
00621 if (entry_a != NULL)
00622 list_delete_chain(&entry_a->ln, &entry_a->ln);
00623
00624 if (entry_b != NULL) {
00625 segment_merge(last_entry->segment, entry_b->segment);
00626 free(entry_b->segment);
00627 }
00628 fail_last_entry:
00629 if (entry_a != NULL) {
00630 segment_merge(entry_a->segment, first_entry->segment);
00631 free(first_entry->segment);
00632 first_entry->segment = entry_a->segment;
00633 }
00634 fail_first_entry:
00635 list_insert_before(&entry_b_next->ln, &last_entry->ln);
00636 list_insert_after(&entry_a_prev->ln, &first_entry->ln);
00637
00638 free(entry_a);
00639 free(entry_b);
00640
00641 return_error(err);
00642 }
00643
00644 static int segcol_list_find(segcol_t *segcol, segcol_iter_t **iter, off_t offset)
00645 {
00646 if (segcol == NULL || iter == NULL || offset < 0)
00647 return_error(EINVAL);
00648
00649 int err;
00650
00651
00652 off_t segcol_size;
00653 segcol_get_size(segcol, &segcol_size);
00654
00655 if (offset >= segcol_size)
00656 return_error(EINVAL);
00657
00658 struct segcol_list_impl *impl =
00659 (struct segcol_list_impl *) segcol_get_impl(segcol);
00660
00661
00662
00663
00664
00665 struct list_node *cur_node = NULL;
00666 off_t cur_mapping = -1;
00667
00668 segcol_list_get_closest_node(segcol, &cur_node, &cur_mapping, offset);
00669
00670 int fix_mapping = 0;
00671
00672
00673 while (cur_node != cur_node->next && cur_node != cur_node->prev) {
00674 struct segment_entry *snode =
00675 list_entry(cur_node, struct segment_entry, ln);
00676
00677 segment_t *seg = snode->segment;
00678 off_t seg_size;
00679 err = segment_get_size(seg, &seg_size);
00680
00681
00682
00683
00684
00685
00686
00687 if (fix_mapping)
00688 cur_mapping -= seg_size;
00689
00690
00691 if (offset >= cur_mapping && offset < cur_mapping + seg_size) {
00692 segcol_list_set_cache(impl, cur_node, cur_mapping);
00693 break;
00694 }
00695
00696
00697
00698
00699
00700 if (offset < cur_mapping) {
00701 cur_node = cur_node->prev;
00702
00703
00704
00705
00706
00707 fix_mapping = 1;
00708 }
00709 else if (offset >= cur_mapping + seg_size) {
00710 cur_node = cur_node->next;
00711 fix_mapping = 0;
00712 cur_mapping += seg_size;
00713 }
00714 }
00715
00716
00717 err = segcol_iter_new(segcol, iter);
00718 if (err)
00719 return_error(err);
00720
00721 struct segcol_list_iter_impl *iter_impl =
00722 (struct segcol_list_iter_impl *) segcol_iter_get_impl(*iter);
00723
00724 iter_impl->node = cur_node;
00725 iter_impl->mapping = cur_mapping;
00726
00727 return 0;
00728 }
00729
00730 static int segcol_list_iter_new(segcol_t *segcol, void **iter_impl)
00731 {
00732 if (segcol == NULL || iter_impl == NULL)
00733 return_error(EINVAL);
00734
00735 struct segcol_list_impl *impl =
00736 (struct segcol_list_impl *) segcol_get_impl(segcol);
00737 struct segcol_list_iter_impl **iter_impl1 =
00738 (struct segcol_list_iter_impl **)iter_impl;
00739
00740 *iter_impl1 = malloc(sizeof(struct segcol_list_iter_impl));
00741
00742 (*iter_impl1)->node = list_head(impl->list)->next;
00743 (*iter_impl1)->mapping = 0;
00744
00745 return 0;
00746 }
00747
00748
00749 static int segcol_list_iter_next(segcol_iter_t *iter)
00750 {
00751 if (iter == NULL)
00752 return_error(EINVAL);
00753
00754 struct segcol_list_iter_impl *iter_impl = segcol_iter_get_impl(iter);
00755
00756 if (iter_impl->node != iter_impl->node->next) {
00757 off_t node_size;
00758
00759 struct segment_entry *snode =
00760 list_entry(iter_impl->node, struct segment_entry, ln);
00761
00762 segment_get_size(snode->segment, &node_size);
00763 iter_impl->node = iter_impl->node->next;
00764 iter_impl->mapping = iter_impl->mapping + node_size;
00765 }
00766
00767 return 0;
00768 }
00769
00770 static int segcol_list_iter_get_segment(segcol_iter_t *iter, segment_t **seg)
00771 {
00772 if (iter == NULL || seg == NULL)
00773 return_error(EINVAL);
00774
00775 struct segcol_list_iter_impl *iter_impl = segcol_iter_get_impl(iter);
00776
00777 *seg = list_entry(iter_impl->node, struct segment_entry, ln)->segment;
00778
00779 return 0;
00780 }
00781
00782 static int segcol_list_iter_get_mapping(segcol_iter_t *iter, off_t *mapping)
00783 {
00784 if (iter == NULL || mapping == NULL)
00785 return_error(EINVAL);
00786
00787 struct segcol_list_iter_impl *iter_impl = segcol_iter_get_impl(iter);
00788
00789 *mapping = iter_impl->mapping;
00790
00791 return 0;
00792 }
00793
00794 static int segcol_list_iter_is_valid(segcol_iter_t *iter, int *valid)
00795 {
00796 if (iter == NULL || valid == NULL)
00797 return_error(EINVAL);
00798
00799 struct segcol_list_iter_impl *iter_impl = segcol_iter_get_impl(iter);
00800
00801
00802
00803 *valid = (iter_impl != NULL) && (iter_impl->node != iter_impl->node->next)
00804 && (iter_impl->node != iter_impl->node->prev);
00805
00806 return 0;
00807 }
00808
00809 static int segcol_list_iter_free(segcol_iter_t *iter)
00810 {
00811 if (iter == NULL)
00812 return_error(EINVAL);
00813
00814 free(segcol_iter_get_impl(iter));
00815
00816 return 0;
00817 }