]>
Commit | Line | Data |
---|---|---|
877ce944 | 1 | /* |
b510f3a1 | 2 | * DEBUG: section 05 Comm |
877ce944 | 3 | */ |
f7f3304a | 4 | #include "squid.h" |
877ce944 | 5 | #include "DescriptorSet.h" |
602d9612 | 6 | #include "globals.h" /* for Squid_MaxFD */ |
877ce944 AR |
7 | |
8 | // pre-allocates descriptor store and index for Squid_MaxFD descriptors | |
9 | DescriptorSet::DescriptorSet(): descriptors_(NULL), index_(NULL), | |
26ac0430 | 10 | capacity_(0), size_(0) |
877ce944 AR |
11 | { |
12 | // we allocate once and never realloc, at least for now | |
13 | capacity_ = Squid_MaxFD; | |
14 | descriptors_ = new int[capacity_]; | |
15 | index_ = new int[capacity_]; | |
16 | ||
17 | // fill index with -1s to be able to say whether a descriptor is present | |
18 | // it is not essential to fill the descriptors, but it enables more checks | |
19 | for (int i = 0; i < capacity_; ++i) | |
20 | index_[i] = descriptors_[i] = -1; | |
21 | } | |
22 | ||
23 | DescriptorSet::~DescriptorSet() | |
24 | { | |
25 | delete[] descriptors_; | |
26 | delete[] index_; | |
27 | } | |
28 | ||
29 | /// adds if unique; returns true if added | |
30 | bool | |
31 | DescriptorSet::add(int fd) | |
32 | { | |
33 | assert(0 <= fd && fd < capacity_); // \todo: replace with Must() | |
34 | ||
35 | if (has(fd)) | |
36 | return false; // already have it | |
37 | ||
38 | assert(size_ < capacity_); // \todo: replace with Must() | |
aec55359 FC |
39 | const int pos = size_; |
40 | ++size_; | |
877ce944 AR |
41 | index_[fd] = pos; |
42 | descriptors_[pos] = fd; | |
43 | return true; // really added | |
44 | } | |
45 | ||
46 | /// deletes if there; returns true if deleted | |
47 | bool | |
48 | DescriptorSet::del(int fd) | |
49 | { | |
50 | assert(0 <= fd && fd < capacity_); // \todo: here and below, use Must() | |
51 | ||
52 | if (!has(fd)) | |
53 | return false; // we do not have it | |
54 | ||
55 | assert(!empty()); | |
56 | const int delPos = index_[fd]; | |
57 | assert(0 <= delPos && delPos < capacity_); | |
58 | ||
59 | // move the last descriptor to the deleted fd position | |
60 | // to avoid skipping deleted descriptors in pop() | |
61 | const int lastPos = size_-1; | |
62 | const int lastFd = descriptors_[lastPos]; | |
63 | assert(delPos <= lastPos); // may be the same | |
64 | descriptors_[delPos] = lastFd; | |
65 | index_[lastFd] = delPos; | |
66 | ||
67 | descriptors_[lastPos] = -1; | |
68 | index_[fd] = -1; | |
69 | --size_; | |
70 | ||
71 | return true; // really added | |
72 | } | |
73 | ||
74 | /// ejects one descriptor in unspecified order | |
75 | int | |
76 | DescriptorSet::pop() | |
77 | { | |
78 | assert(!empty()); | |
79 | const int lastPos =--size_; | |
80 | const int lastFd = descriptors_[lastPos]; | |
81 | assert(0 <= lastFd && lastFd < capacity_); | |
82 | ||
83 | // cleanup | |
84 | descriptors_[lastPos] = -1; | |
85 | index_[lastFd] = -1; | |
86 | ||
87 | return lastFd; | |
88 | } | |
89 | ||
90 | void | |
91 | DescriptorSet::print(std::ostream &os) const | |
92 | { | |
93 | // \todo add "name" if the set is used for more than just half-closed FDs | |
94 | os << size_ << " FDs"; | |
95 | } |