⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitset.c

📁 libbt-1.04
💻 C
字号:
#include "config.h"#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#include <stdio.h>#include "bitset.h"#include "random.h"#include "util.h"kBitSet* kBitSet_create( kBitSet *set, int nbits) {    int bytes = (nbits+7)/8;    if (nbits %8) bytes++;    if (!set) {	set = btcalloc( 1, sizeof(kBitSet));    }     set->nbits = nbits;    set->bits = btcalloc( bytes, 1);    return set;}kBitSet* kBitSet_createCopy( kBitSet *copy, kBitSet *orig) {    int bytes;    int i;    kBitSet_create( copy, orig->nbits);    bytes = (orig->nbits+7)/8;    for (i = 0; i<bytes; i++) {	copy->bits[i] = orig->bits[i];    }    return copy;}void kBitSet_finit( kBitSet *set) {    if (set && set->bits) {	btfree(set->bits);	set->bits = NULL;    }}void kBitSet_readBytes( kBitSet *set, char* bits, int len) {    int i;    int bytes = (set->nbits+7)/8;    DIE_UNLESS(len <= bytes);    for (i=0; i<len; i++) {	set->bits[i] = bits[i];    }}void bs_set( kBitSet *set, int bit) {    int byte = bit/8;    int mask = 0x80 >> (bit %8);    set->bits[byte] |= mask;}void bs_clr( kBitSet *set, int bit) {    int byte = bit/8;    int mask = 0x80 >> (bit %8);    set->bits[byte] &= ~mask;}int bs_isSet( kBitSet *set, int bit) {    int byte = bit/8;    int mask = 0x80 >> (bit %8);    return (set->bits[byte] & mask) != 0;}void bs_and( kBitSet *res, kBitSet *a, kBitSet *b) {    int n;    int bytes = (a->nbits+7)/8;    DIE_UNLESS(a->nbits == b->nbits);    DIE_UNLESS(res->nbits == b->nbits);    for (n=0; n<bytes; n++) {	res->bits[n] = a->bits[n] & b->bits[n];    }}void bs_not( kBitSet *res, kBitSet *a) {    int n;    int bytes = (a->nbits+7)/8;    DIE_UNLESS(res->nbits == a->nbits);    for (n=0; n<bytes; n++) {	res->bits[n] = ~a->bits[n];    }}#if WIN32char bstest_mask[] = {		'\xff', '\x80', '\xc0', '\xe0', '\xf0', '\xf8', '\xfc', '\xfe'	};#elsechar bstest_mask[] = {	0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe    };#endifint bs_isEmpty( kBitSet *a) {    int n;    int bytes = (a->nbits+7)/8;    for (n=0; n<bytes-1; n++) {	if (a->bits[n]) return 0;    }    if (a->bits[bytes-1] & bstest_mask[a->nbits %8]) return 0;    return 1;}int bs_isFull( kBitSet *a) {    int res;    kBitSet c;    kBitSet_create( &c, a->nbits);    bs_not( &c, a);    res = bs_isEmpty( &c);     kBitSet_finit( &c);    return res;}int bs_firstClr( kBitSet *a) {    int i;    for (i=0; i<a->nbits; i++) {	if (!bs_isSet( a, i)) return i;    }    return 0;}void bs_setRange( kBitSet *set, int start, int endplus1) {    int bit;    for (bit = start; bit<endplus1; bit++) {	if ((bit & 7) == 0 && (bit + 8)<endplus1) {	    int byte = bit/8;            set->bits[byte] = 0xff;	    bit += 7;	} else {	    bs_set( set, bit);	}    }}void bs_getSparseSet( kBitSet *a, int **data, int *len) {    int l=0, m=0;    int *d = NULL;    int n;    for (n=0; n<a->nbits; n++) {	if (bs_isSet( a, n)) {	    if (l >= m) { m += 10; d = btrealloc( d, m * sizeof(int)); }	    d[l] = n;	    l++;	}    }    *data = d;    *len = l;}int bs_countBits( kBitSet *a) {    int n;    int count = 0;    for (n=0; n<a->nbits; n++) {	if (bs_isSet( a, n)) {	    count++;	}    }    return count;}int bs_hasInteresting( kBitSet *reqs, kBitSet *peer, kBitSet *intr) {    /*     * reqs is the list of blocks already requested from other peers     * peer is the list of blocks available at this peer     * intr in the list of block that I'm interested in downloading     *     * returns the true iff there is at least one block that the peer     * has, but isn't already requested.     */    kBitSet r;     int interesting = 1;    kBitSet_create( &r, peer->nbits);    bs_not( &r, reqs);    bs_and( &r, &r, peer);    bs_and( &r, &r, intr);    if (bs_isEmpty( &r)) interesting=0;    kBitSet_finit( &r);    return interesting;}int bs_pickblock( kBitSet *reqs, kBitSet *peer, kBitSet *intr) {    /*     * reqs is the list of blocks already requested from other peers     * peer is the list of blocks available at this peer     * intr in the list of block that I'm interested in downloading     *     * returns the block number of a block to request from this peer,     * or -1 if there are no blocks to request.     */    kBitSet r;     int *picks;    int npicks;    int block;    kBitSet_create( &r, peer->nbits);    bs_not( &r, reqs);    bs_and( &r, &r, peer);    bs_and( &r, &r, intr);    if (bs_isEmpty( &r)) return -1;#if 0    bs_dump( "reqs", reqs);    bs_dump( "peer", peer);    bs_dump( "intr", intr);    bs_dump("r", &r);#endif    bs_getSparseSet( &r, &picks, &npicks);    DIE_UNLESS(npicks != 0);    block = picks[ rnd(npicks)];    btfree(picks);    kBitSet_finit( &r);    return block;}void bs_dump( char *label, kBitSet *bs) {#define BPL 24    int n,m;    int bytes = (bs->nbits+7)/8;    for (n=0; n<bytes; n+=BPL) {	printf("%s+%05d:", label, n);	for (m=0; m<BPL && m+n<bytes; m++) {	    if (m>0 && (m%4)==0) printf(" ");	    printf ("%02x", (unsigned char)bs->bits[n+m]);	}	printf("\n");    }    printf("\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -