]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/filemap.cc
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 08 Swap File Bitmap */
12 #include "debug/Stream.h"
15 /* Number of bits in a long */
17 #define LONG_BIT_SHIFT 6
18 #define BITS_IN_A_LONG 0x40
19 #define LONG_BIT_MASK 0x3F
20 #define ALL_ONES (unsigned long) 0xFFFFFFFFFFFFFFFF
21 #elif SIZEOF_LONG == 4
22 #define LONG_BIT_SHIFT 5
23 #define BITS_IN_A_LONG 0x20
24 #define LONG_BIT_MASK 0x1F
25 #define ALL_ONES (unsigned long) 0xFFFFFFFF
27 #define LONG_BIT_SHIFT 5
28 #define BITS_IN_A_LONG 0x20
29 #define LONG_BIT_MASK 0x1F
30 #define ALL_ONES (unsigned long) 0xFFFFFFFF
33 #define FM_INITIAL_NUMBER (1<<14)
36 capacity_(FM_INITIAL_NUMBER
), usedSlots_(0),
37 nwords(capacity_
>> LONG_BIT_SHIFT
)
39 debugs(8, 3, "creating space for " << capacity_
<< " files");
40 debugs(8, 5, "--> " << nwords
<< " words of " << sizeof(*bitmap
) << " bytes each");
41 bitmap
= (unsigned long *)xcalloc(nwords
, sizeof(*bitmap
));
47 int old_sz
= nwords
* sizeof(*bitmap
);
48 void *old_map
= bitmap
;
50 assert(capacity_
<= (1 << 24)); /* swap_filen is 25 bits, signed */
51 nwords
= capacity_
>> LONG_BIT_SHIFT
;
52 debugs(8, 3, " creating space for " << capacity_
<< " files");
53 debugs(8, 5, "--> " << nwords
<< " words of " << sizeof(*bitmap
) << " bytes each");
54 bitmap
= (unsigned long *)xcalloc(nwords
, sizeof(*bitmap
));
55 debugs(8, 3, "copying " << old_sz
<< " old bytes");
56 memcpy(bitmap
, old_map
, old_sz
);
58 /* XXX account fm->bitmap */
62 FileMap::setBit(sfileno file_number
)
64 unsigned long bitmask
= (1L << (file_number
& LONG_BIT_MASK
));
66 while (file_number
>= capacity_
)
69 bitmap
[file_number
>> LONG_BIT_SHIFT
] |= bitmask
;
77 * WARNING: clearBit does not perform array bounds
78 * checking! It assumes that 'file_number' is valid, and that the
79 * bit is already set. The caller must verify both of those
80 * conditions by calling testBit
84 FileMap::clearBit(sfileno file_number
)
86 unsigned long bitmask
= (1L << (file_number
& LONG_BIT_MASK
));
87 bitmap
[file_number
>> LONG_BIT_SHIFT
] &= ~bitmask
;
92 FileMap::testBit(sfileno file_number
) const
94 unsigned long bitmask
= (1L << (file_number
& LONG_BIT_MASK
));
96 if (file_number
>= capacity_
)
99 /* be sure the return value is an int, not a u_long */
100 return (bitmap
[file_number
>> LONG_BIT_SHIFT
] & bitmask
? 1 : 0);
104 FileMap::allocate(sfileno suggestion
)
108 if (suggestion
>= capacity_
)
111 if (!testBit(suggestion
))
114 word
= suggestion
>> LONG_BIT_SHIFT
;
116 for (unsigned int count
= 0; count
< nwords
; ++count
) {
117 if (bitmap
[word
] != ALL_ONES
)
120 word
= (word
+ 1) % nwords
;
123 for (unsigned char bit
= 0; bit
< BITS_IN_A_LONG
; ++bit
) {
124 suggestion
= ((unsigned long) word
<< LONG_BIT_SHIFT
) | bit
;
126 if (!testBit(suggestion
)) {
132 return allocate(capacity_
>> 1);