~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to iocore/eventsystem/IOBuffer.cc

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
  A brief file description
 
4
 
 
5
  @section license License
 
6
 
 
7
  Licensed to the Apache Software Foundation (ASF) under one
 
8
  or more contributor license agreements.  See the NOTICE file
 
9
  distributed with this work for additional information
 
10
  regarding copyright ownership.  The ASF licenses this file
 
11
  to you under the Apache License, Version 2.0 (the
 
12
  "License"); you may not use this file except in compliance
 
13
  with the License.  You may obtain a copy of the License at
 
14
 
 
15
      http://www.apache.org/licenses/LICENSE-2.0
 
16
 
 
17
  Unless required by applicable law or agreed to in writing, software
 
18
  distributed under the License is distributed on an "AS IS" BASIS,
 
19
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
20
  See the License for the specific language governing permissions and
 
21
  limitations under the License.
 
22
 */
 
23
 
 
24
#include "ink_unused.h"      /* MAGIC_EDITING_TAG */
 
25
/**************************************************************************
 
26
  UIOBuffer.cc
 
27
 
 
28
**************************************************************************/
 
29
 
 
30
#include "P_EventSystem.h"
 
31
 
 
32
//
 
33
// General Buffer Allocator
 
34
//
 
35
inkcoreapi Allocator ioBufAllocator[DEFAULT_BUFFER_SIZES];
 
36
inkcoreapi ClassAllocator<MIOBuffer> ioAllocator("ioAllocator", DEFAULT_BUFFER_NUMBER);
 
37
inkcoreapi ClassAllocator<IOBufferData> ioDataAllocator("ioDataAllocator", DEFAULT_BUFFER_NUMBER);
 
38
inkcoreapi ClassAllocator<IOBufferBlock> ioBlockAllocator("ioBlockAllocator", DEFAULT_BUFFER_NUMBER);
 
39
int64_t default_large_iobuffer_size = DEFAULT_LARGE_BUFFER_SIZE;
 
40
int64_t default_small_iobuffer_size = DEFAULT_SMALL_BUFFER_SIZE;
 
41
int64_t max_iobuffer_size = DEFAULT_BUFFER_SIZES - 1;
 
42
 
 
43
//
 
44
// Initialization
 
45
//
 
46
void
 
47
init_buffer_allocators()
 
48
{
 
49
  char *name;
 
50
 
 
51
  for (int i = 0; i < DEFAULT_BUFFER_SIZES; i++) {
 
52
    int64_t s = DEFAULT_BUFFER_BASE_SIZE * (((int64_t)1) << i);
 
53
    int64_t a = DEFAULT_BUFFER_ALIGNMENT;
 
54
    int n = i <= default_large_iobuffer_size ? DEFAULT_BUFFER_NUMBER : DEFAULT_HUGE_BUFFER_NUMBER;
 
55
    if (s < a)
 
56
      a = s;
 
57
 
 
58
    name = NEW(new char[64]);
 
59
    snprintf(name, 64, "ioBufAllocator[%d]", i);
 
60
    ioBufAllocator[i].re_init(name, s, n, a);
 
61
  }
 
62
}
 
63
 
 
64
int64_t
 
65
MIOBuffer::remove_append(IOBufferReader * r)
 
66
{
 
67
  int64_t l = 0;
 
68
  while (r->block) {
 
69
    Ptr<IOBufferBlock> b = r->block;
 
70
    r->block = r->block->next;
 
71
    b->_start += r->start_offset;
 
72
    if (b->start() >= b->end()) {
 
73
      r->start_offset = -r->start_offset;
 
74
      continue;
 
75
    }
 
76
    r->start_offset = 0;
 
77
    l += b->read_avail();
 
78
    append_block(b);
 
79
  }
 
80
  r->mbuf->_writer = NULL;
 
81
  return l;
 
82
}
 
83
 
 
84
int64_t
 
85
MIOBuffer::write(const void *abuf, int64_t alen)
 
86
{
 
87
  const char *buf = (const char*)abuf;
 
88
  int64_t len = alen;
 
89
  while (len) {
 
90
    if (!_writer)
 
91
      add_block();
 
92
    int64_t f = _writer->write_avail();
 
93
    f = f < len ? f : len;
 
94
    if (f > 0) {
 
95
      ::memcpy(_writer->end(), buf, f);
 
96
      _writer->fill(f);
 
97
      buf += f;
 
98
      len -= f;
 
99
    }
 
100
    if (len) {
 
101
      if (!_writer->next)
 
102
        add_block();
 
103
      else
 
104
        _writer = _writer->next;
 
105
    }
 
106
  }
 
107
  return alen;
 
108
}
 
109
 
 
110
 
 
111
#ifdef WRITE_AND_TRANSFER
 
112
  /*
 
113
   * Same functionality as write but for the one small difference.
 
114
   * The space available in the last block is taken from the original
 
115
   * and this space becomes available to the copy.
 
116
   *
 
117
   */
 
118
int64_t
 
119
MIOBuffer::write_and_transfer_left_over_space(IOBufferReader * r, int64_t alen, int64_t offset)
 
120
{
 
121
  int64_t rval = write(r, alen, offset);
 
122
  // reset the end markers of the original so that it cannot
 
123
  // make use of the space in the current block
 
124
  if (r->mbuf->_writer)
 
125
    r->mbuf->_writer->_buf_end = r->mbuf->_writer->_end;
 
126
  // reset the end marker of the clone so that it can make
 
127
  // use of the space in the current block
 
128
  if (_writer) {
 
129
    _writer->_buf_end = _writer->data->data() + _writer->block_size();
 
130
  }
 
131
  return rval;
 
132
}
 
133
 
 
134
#endif
 
135
 
 
136
 
 
137
int64_t
 
138
MIOBuffer::write(IOBufferReader * r, int64_t alen, int64_t offset)
 
139
{
 
140
  int64_t len = alen;
 
141
  IOBufferBlock *b = r->block;
 
142
  offset += r->start_offset;
 
143
 
 
144
  while (b && len > 0) {
 
145
    int64_t max_bytes = b->read_avail();
 
146
    max_bytes -= offset;
 
147
    if (max_bytes <= 0) {
 
148
      offset = -max_bytes;
 
149
      b = b->next;
 
150
      continue;
 
151
    }
 
152
    int64_t bytes;
 
153
    if (len<0 || len>= max_bytes)
 
154
      bytes = max_bytes;
 
155
    else
 
156
      bytes = len;
 
157
    IOBufferBlock *bb = b->clone();
 
158
    bb->_start += offset;
 
159
    bb->_buf_end = bb->_end = bb->_start + bytes;
 
160
    append_block(bb);
 
161
    offset = 0;
 
162
    len -= bytes;
 
163
    b = b->next;
 
164
  }
 
165
  return alen - len;
 
166
}
 
167
 
 
168
int64_t
 
169
MIOBuffer::puts(char *s, int64_t len)
 
170
{
 
171
  char *pc = end();
 
172
  char *pb = s;
 
173
  while (pc < buf_end()) {
 
174
    if (len-- <= 0)
 
175
      return -1;
 
176
    if (!*pb || *pb == '\n') {
 
177
      int64_t n = (int64_t) (pb - s);
 
178
      memcpy(end(), s, n + 1);  // Upto and including '\n'
 
179
      end()[n + 1] = 0;
 
180
      fill(n + 1);
 
181
      return n + 1;
 
182
    }
 
183
    pc++;
 
184
    pb++;
 
185
  }
 
186
  return 0;
 
187
}
 
188
 
 
189
int64_t
 
190
IOBufferReader::read(void *ab, int64_t len)
 
191
{
 
192
  char *b = (char*)ab;
 
193
  int64_t max_bytes = read_avail();
 
194
  int64_t bytes = len <= max_bytes ? len : max_bytes;
 
195
  int64_t n = bytes;
 
196
 
 
197
  while (n) {
 
198
    int64_t l = block_read_avail();
 
199
    if (n < l)
 
200
      l = n;
 
201
    ::memcpy(b, start(), l);
 
202
    consume(l);
 
203
    b += l;
 
204
    n -= l;
 
205
  }
 
206
  return bytes;
 
207
}
 
208
 
 
209
int64_t
 
210
IOBufferReader::memchr(char c, int64_t len, int64_t offset)
 
211
{
 
212
  IOBufferBlock *b = block;
 
213
  offset += start_offset;
 
214
  int64_t o = offset;
 
215
 
 
216
  while (b && len) {
 
217
    int64_t max_bytes = b->read_avail();
 
218
    max_bytes -= offset;
 
219
    if (max_bytes <= 0) {
 
220
      offset = -max_bytes;
 
221
      b = b->next;
 
222
      continue;
 
223
    }
 
224
    int64_t bytes;
 
225
    if (len<0 || len>= max_bytes)
 
226
      bytes = max_bytes;
 
227
    else
 
228
      bytes = len;
 
229
    char *s = b->start() + offset;
 
230
    char *p = (char *) ink_memchr(s, c, bytes);
 
231
    if (p)
 
232
      return (int64_t) (o - start_offset + p - s);
 
233
    o += bytes;
 
234
    len -= bytes;
 
235
    b = b->next;
 
236
    offset = 0;
 
237
  }
 
238
 
 
239
  return -1;
 
240
}
 
241
 
 
242
char *
 
243
IOBufferReader::memcpy(const void *ap, int64_t len, int64_t offset)
 
244
{
 
245
  char *p = (char*)ap;
 
246
  IOBufferBlock *b = block;
 
247
  offset += start_offset;
 
248
 
 
249
  while (b && len) {
 
250
    int64_t max_bytes = b->read_avail();
 
251
    max_bytes -= offset;
 
252
    if (max_bytes <= 0) {
 
253
      offset = -max_bytes;
 
254
      b = b->next;
 
255
      continue;
 
256
    }
 
257
    int64_t bytes;
 
258
    if (len<0 || len>= max_bytes)
 
259
      bytes = max_bytes;
 
260
    else
 
261
      bytes = len;
 
262
    ::memcpy(p, b->start() + offset, bytes);
 
263
    p += bytes;
 
264
    len -= bytes;
 
265
    b = b->next;
 
266
    offset = 0;
 
267
  }
 
268
 
 
269
  return p;
 
270
}