Пример #1
0
err_t qbuffer_pop_back(qbuffer_t* buf)
{
  qbytes_t* bytes;
  int64_t skip;
  int64_t len;
  qbuffer_iter_t chunk;

  if ( qbuffer_num_parts(buf) == 0 ) return EINVAL;
  
  chunk = qbuffer_end(buf);
  qbuffer_iter_prev_part(buf, &chunk);

  qbuffer_iter_get(chunk, qbuffer_end(buf), &bytes, &skip, &len);

  deque_pop_back(sizeof(qbuffer_part_t), &buf->deque);

  buf->offset_end -= len;

  return 0;
}
Пример #2
0
qioerr qbuffer_pop_back(qbuffer_t* buf)
{
  qbytes_t* bytes;
  int64_t skip;
  int64_t len;
  qbuffer_iter_t chunk;

  if ( qbuffer_num_parts(buf) == 0 ) QIO_RETURN_CONSTANT_ERROR(EINVAL, "cannot pop from empty buffer");
  
  chunk = qbuffer_end(buf);
  qbuffer_iter_prev_part(buf, &chunk);

  qbuffer_iter_get(chunk, qbuffer_end(buf), &bytes, &skip, &len);

  deque_pop_back(sizeof(qbuffer_part_t), &buf->deque);

  buf->offset_end -= len;

  return 0;
}
Пример #3
0
/* Advances an iterator using linear search. 
 */
void qbuffer_iter_advance(qbuffer_t* buf, qbuffer_iter_t* iter, int64_t amt)
{
  deque_iterator_t d_begin = deque_begin( & buf->deque );
  deque_iterator_t d_end = deque_end( & buf->deque );

  if( amt >= 0 ) {
    // forward search.
    iter->offset += amt;
    while( ! deque_it_equals(iter->iter, d_end) ) {
      qbuffer_part_t* qbp = (qbuffer_part_t*) deque_it_get_cur_ptr(sizeof(qbuffer_part_t), iter->iter);
      if( iter->offset < qbp->end_offset ) {
        // it's in this one.
        return;
      }
      deque_it_forward_one(sizeof(qbuffer_part_t), & iter->iter);
    }
    // If we get here, we didn't find it. Return the buffer end.
    *iter = qbuffer_end(buf);
  } else {
    // backward search.
    iter->offset += amt; // amt is negative

    if( ! deque_it_equals( iter->iter, d_end ) ) {
      // is it within the current buffer?
      qbuffer_part_t* qbp = (qbuffer_part_t*) deque_it_get_cur_ptr(sizeof(qbuffer_part_t), iter->iter);
      if( iter->offset >= qbp->end_offset - qbp->len_bytes ) {
        // it's in this one.
        return;
      }
    }

    // now we have a valid deque element.
    do {
      qbuffer_part_t* qbp;

      deque_it_back_one(sizeof(qbuffer_part_t), & iter->iter);

      qbp = (qbuffer_part_t*) deque_it_get_cur_ptr(sizeof(qbuffer_part_t), iter->iter);
      if( iter->offset >= qbp->end_offset - qbp->len_bytes ) {
        // it's in this one.
        return;
      }
    } while( ! deque_it_equals(iter->iter, d_begin) );
    // If we get here, we didn't find it. Return the buffer start.
    *iter = qbuffer_begin(buf);
  }
}
Пример #4
0
err_t qbuffer_pop_front(qbuffer_t* buf)
{
  qbytes_t* bytes;
  int64_t skip;
  int64_t len;
  qbuffer_iter_t chunk;

  if ( qbuffer_num_parts(buf) == 0 ) return EINVAL;

  chunk = qbuffer_begin(buf);

  qbuffer_iter_get(chunk, qbuffer_end(buf), &bytes, &skip, &len);

  deque_pop_front(sizeof(qbuffer_part_t), &buf->deque);

  buf->offset_start += len;

  return 0;
}
Пример #5
0
// find buffer iterator part in logarithmic time
// finds an offset in the window [offset_start,offset_end]
// (in other words, offset might not start at 0)
qbuffer_iter_t qbuffer_iter_at(qbuffer_t* buf, int64_t offset)
{
  qbuffer_iter_t ret;
  deque_iterator_t first = deque_begin(& buf->deque);
  deque_iterator_t last = deque_end(& buf->deque);
  deque_iterator_t middle;
  qbuffer_part_t* qbp;
  ssize_t num_parts = deque_it_difference(sizeof(qbuffer_part_t), last, first);
  ssize_t half;

  while( num_parts > 0 ) {
    half = num_parts >> 1;
    middle = first;

    deque_it_forward_n(sizeof(qbuffer_part_t), &middle, half);

    qbp = (qbuffer_part_t*) deque_it_get_cur_ptr(sizeof(qbuffer_part_t), middle);
    if( offset < qbp->end_offset ) {
      num_parts = half;
    } else {
      first = middle;
      deque_it_forward_one(sizeof(qbuffer_part_t), &first);
      num_parts = num_parts - half - 1;
    }
  }

  if( deque_it_equals(first, last) ) {
    ret = qbuffer_end(buf);
  } else {
    qbp = (qbuffer_part_t*) deque_it_get_cur_ptr(sizeof(qbuffer_part_t), first);
    if( offset < qbp->end_offset - qbp->len_bytes ) {
      ret = qbuffer_begin(buf);
    } else {
      ret.offset = offset;
      ret.iter = first;
    }
  }
  return ret;
}