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