#ifdef __CSCAN_TEST__ #include struct buf { int id; int b_pblkno; int b_flags; TAILQ_ENTRY(buf) b_act; }; #endif struct cscan_queue { TAILQ_HEAD(cscanq, buf) queue; daddr_t lastpos; }; static __inline void cscan_init(struct cscan_queue *head) { TAILQ_INIT(&head->queue); head->lastpos = 0; } /* not required to remove the cscan_select()ed buffer */ static __inline void cscan_dequeue(struct cscan_queue *head, struct buf *bp) { if (bp == NULL) return; TAILQ_REMOVE(&head->queue, bp, b_act); head->lastpos = bp->b_pblkno; } static __inline struct buf * cscan_select(struct cscan_queue *head) { struct buf *bp = 0, *bp1 = 0, *bp2 = 0; daddr_t d1 = INT_MAX, d2 = 0; TAILQ_FOREACH(bp, &head->queue, b_act) { daddr_t d = bp->b_pblkno - head->lastpos; if (d >= 0) { if (d <= d1) d1 = d, bp1 = bp; } else { d = -d; if (d >= d2) d2 = d, bp2 = bp; } } return bp1 ? bp1 : bp2; } static __inline void cscan_enqueue(head, bp) struct cscan_queue *head; struct buf *bp; { TAILQ_INSERT_TAIL(&head->queue, bp, b_act); } #ifdef __CSCAN_TEST__ int main(int argc, char *argv[]) { #define N 10 struct buf buf[N], *b; int i; struct cscan_queue q; cscan_init(&q); for (i = 0; i < N; i++) { bzero(&buf[i], sizeof(struct buf)); buf[i].b_pblkno = i; buf[i].id = i; } for (i = N-1; i >= 1; i--) cscan_enqueue(&q, &buf[i]); #define P b = cscan_select(&q); printf("xx %d\n", b ? b->id : -1); P /* cscan_dequeue(&q, &buf[0]); */ cscan_dequeue(&q, &buf[1]); cscan_dequeue(&q, &buf[2]); cscan_dequeue(&q, &buf[4]); /* cscan_enqueue(&q, &buf[2]); */ /* cscan_enqueue(&q, &buf[0]); */ cscan_enqueue(&q, &buf[1]); P cscan_dequeue(&q, &buf[1]); P for (i = 0; i < N; i++) { b = cscan_select(&q); printf("%d\n", b ? b->id : -1); if (b) cscan_dequeue(&q, b); } return 0; } #endif #define cscan_foreach(q,bp) TAILQ_FOREACH(bp, &(q)->queue, b_act)