/* Determine whether a value belongs to this set * * 检查给定值 value 是否集合中的元素。 * * 是返回 1 ,不是返回 0 。 * * T = O(log N) */ uint8_tintsetFind(intset *is, int64_t value) {
// 计算 value 的编码 uint8_t valenc = _intsetValueEncoding(value);
// 如果 value 的编码大于集合的当前编码,那么 value 一定不存在于集合 // 当 value 的编码小于等于集合的当前编码时, // 才再使用 intsetSearch 进行查找 return valenc <= intrev32ifbe(is->encoding) && intsetSearch(is,value,NULL); }
/* Search for the position of "value". * * 在集合 is 的底层数组中查找值 value 所在的索引。 * * Return 1 when the value was found and * sets "pos" to the position of the value within the intset. * * 成功找到 value 时,函数返回 1 ,并将 *pos 的值设为 value 所在的索引。 * * Return 0 when the value is not present in the intset * and sets "pos" to the position where "value" can be inserted. * * 当在数组中没找到 value 时,返回 0 。 * 并将 *pos 的值设为 value 可以插入到数组中的位置。 * * T = O(log N) */ staticuint8_tintsetSearch(intset *is, int64_t value, uint32_t *pos) { int min = 0, max = intrev32ifbe(is->length)-1, mid = -1; int64_t cur = -1;
/* The value can never be found when the set is empty */ // 处理 is 为空时的情况 if (intrev32ifbe(is->length) == 0) { if (pos) *pos = 0; return0; } else { /* Check for the case where we know we cannot find the value, * but do know the insert position. */ // 因为底层数组是有序的,如果 value 比数组中最后一个值都要大 // 那么 value 肯定不存在于集合中, // 并且应该将 value 添加到底层数组的最末端 if (value > _intsetGet(is,intrev32ifbe(is->length)-1)) { if (pos) *pos = intrev32ifbe(is->length); return0; // 因为底层数组是有序的,如果 value 比数组中最前一个值都要小 // 那么 value 肯定不存在于集合中, // 并且应该将它添加到底层数组的最前端 } elseif (value < _intsetGet(is,0)) { if (pos) *pos = 0; return0; } }
// 在有序数组中进行二分查找 // T = O(log N) while(max >= min) { mid = (min+max)/2; cur = _intsetGet(is,mid); if (value > cur) { min = mid+1; } elseif (value < cur) { max = mid-1; } else { break; } }
// 检查是否已经找到了 value if (value == cur) { if (pos) *pos = mid; return1; } else { if (pos) *pos = min; return0; } }