Statistics
| Branch: | Revision:

streamers / output.c @ a6ac9440

History | View | Annotate | Download (2.19 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7
#include <unistd.h>
8
#include <stdlib.h>
9
#include <string.h>
10
#include <stdint.h>
11
#include <stdio.h>
12

    
13
#include <chunk.h>
14

    
15
#include "out-stream.h"
16
#include "dbg.h"
17

    
18
#define SIZE 8
19

    
20
static int next_chunk;
21
static int buff_size = SIZE;
22

    
23
static struct {
24
  void *data;
25
  int size;
26
  int id;
27
} buff[SIZE];
28

    
29
void buffer_free(int i)
30
{
31
  dprintf("\t\tFlush Buf %d: %s\n", i, buff[i].data);
32
  chunk_write(buff[i].id, buff[i].data, buff[i].size);
33
  free(buff[i].data);
34
  buff[i].data = NULL;
35
  dprintf("Next Chunk: %d -> %d\n", next_chunk, buff[i].id + 1);
36
  next_chunk = buff[i].id + 1;
37
}
38

    
39
void buffer_flush(int id)
40
{
41
  int i = id % buff_size;
42

    
43
  while(buff[i].data) {
44
    buffer_free(i);
45
    i = (i + 1) % buff_size;
46
    if (i == id % buff_size) {
47
      break;
48
    }
49
  }
50
}
51

    
52
void output_deliver(const struct chunk *c)
53
{
54
  dprintf("Chunk %d delivered\n", c->id);
55
  if (c->id < next_chunk) {
56
    return;
57
  }
58

    
59
  if (c->id >= next_chunk + buff_size) {
60
    int i;
61

    
62
    /* We might need some space for storing this chunk,
63
     * or the stored chunks are too old
64
     */
65
    for (i = next_chunk; i <= c->id - buff_size; i++) {
66
      if (buff[i % buff_size].data) {
67
        buffer_free(i % buff_size);
68
      } else {
69
        next_chunk++;
70
      }
71
    }
72
    buffer_flush(next_chunk);
73
    dprintf("Next is now %d, chunk is %d\n", next_chunk, c->id);
74
  }
75

    
76
  dprintf("%d == %d?\n", c->id, next_chunk);
77
  if (c->id == next_chunk) {
78
    dprintf("\tOut Chunk[%d] - %d: %s\n", c->id, c->id % buff_size, c->data);
79
    chunk_write(c->id, c->data, c->size);
80
    next_chunk++;
81
    buffer_flush(next_chunk);
82
  } else {
83
    dprintf("Storing %d (in %d)\n", c->id, c->id % buff_size);
84
    if (buff[c->id % buff_size].data) {
85
      if (buff[c->id % buff_size].id == c->id) {
86
        /* Duplicate of a stored chunk */
87
        return;
88
      }
89
      fprintf(stderr, "Crap!\n");
90
      exit(-1);
91
    }
92
    /* We previously flushed, so we know that c->id is free */
93
    buff[c->id % buff_size].data = malloc(c->size);
94
    memcpy(buff[c->id % buff_size].data, c->data, c->size);
95
    buff[c->id % buff_size].size = c->size;
96
    buff[c->id % buff_size].id = c->id;
97
  }
98
}