SHOGUN  v1.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IOBuffer.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2009 Yahoo! Inc. All rights reserved. The copyrights
3  embodied in the content of this file are licensed under the BSD
4  (revised) open source license.
5 
6  Copyright (c) 2011 Berlin Institute of Technology and Max-Planck-Society.
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  Shogun adjustments (w) 2011 Shashwat Lal Das
14 */
15 
16 #include <string.h>
17 #include <shogun/io/IOBuffer.h>
18 
19 using namespace shogun;
20 
22 {
23  init();
24 }
25 
27 {
28  init();
29  working_file = fd;
30 }
31 
33 {
34  free(space.begin);
35 }
36 
38 {
39  size_t s = 1 << 16;
40  space.reserve(s);
42 }
43 
44 void CIOBuffer::use_file(int fd)
45 {
46  working_file = fd;
47 }
48 
49 int CIOBuffer::open_file(const char* name, char flag)
50 {
51  int ret=1;
52  switch(flag)
53  {
54  case 'r':
55  working_file = open(name, O_RDONLY|O_LARGEFILE);
56  break;
57 
58  case 'w':
59  working_file = open(name, O_CREAT|O_TRUNC|O_WRONLY, 0666);
60  break;
61 
62  default:
63  SG_ERROR("Unknown file operation. Something other than 'r'/'w' specified.\n");
64  ret = 0;
65  }
66  return ret;
67 }
68 
70 {
71  lseek(working_file, 0, SEEK_SET);
73  space.end = space.begin;
74 }
75 
76 void CIOBuffer::set(char *p)
77 {
78  space.end = p;
79 }
80 
81 ssize_t CIOBuffer::read_file(void* buf, size_t nbytes)
82 {
83  return read(working_file, buf, nbytes);
84 }
85 
87 {
88  if (space.end_array - endloaded == 0)
89  {
90  size_t offset = endloaded - space.begin;
92  endloaded = space.begin+offset;
93  }
94  ssize_t num_read = read_file(endloaded, space.end_array - endloaded);
95  if (num_read >= 0)
96  {
97  endloaded = endloaded+num_read;
98  return num_read;
99  }
100  else
101  return 0;
102 }
103 
104 ssize_t CIOBuffer::write_file(const void* buf, size_t nbytes)
105 {
106  return write(working_file, buf, nbytes);
107 }
108 
110 {
111  if (write_file(space.begin, space.index()) != (int) space.index())
112  SG_ERROR("Error, failed to write example!\n");
113  space.end = space.begin;
114  fsync(working_file);
115 }
116 
118 {
119  if (working_file < 0)
120  return false;
121  else
122  {
123  int r = close(working_file);
124  if (r < 0)
125  SG_ERROR("Error closing the file!\n");
126  return true;
127  }
128 }
129 
130 ssize_t CIOBuffer::readto(char* &pointer, char terminal)
131 {
132 //Return a pointer to the bytes before the terminal. Must be less
133 //than the buffer size.
134  pointer = space.end;
135  while (pointer != endloaded && *pointer != terminal)
136  pointer++;
137  if (pointer != endloaded)
138  {
139  size_t n = pointer - space.end;
140  space.end = pointer+1;
141  pointer -= n;
142  return n;
143  }
144  else
145  {
146  if (endloaded == space.end_array)
147  {
148  size_t left = endloaded - space.end;
149  memmove(space.begin, space.end, left);
150  space.end = space.begin;
151  endloaded = space.begin+left;
152  pointer = endloaded;
153  }
154  if (fill() > 0)// more bytes are read.
155  return readto(pointer,terminal);
156  else //no more bytes to read, return nothing.
157  return 0;
158  }
159 }
160 
161 void CIOBuffer::buf_write(char* &pointer, int n)
162 {
163  if (space.end + n <= space.end_array)
164  {
165  pointer = space.end;
166  space.end += n;
167  }
168  else // Time to dump the file
169  {
170  if (space.end != space.begin)
171  flush();
172  else // Array is short, so increase size.
173  {
176  }
177  buf_write(pointer,n);
178  }
179 }
180 
181 unsigned int CIOBuffer::buf_read(char* &pointer, int n)
182 {
183  // Return a pointer to the next n bytes.
184  // n must be smaller than the maximum size.
185  if (space.end + n <= endloaded)
186  {
187  pointer = space.end;
188  space.end += n;
189  return n;
190  }
191  else // out of bytes, so refill.
192  {
193  if (space.end != space.begin) //There exists room to shift.
194  {
195  // Out of buffer so swap to beginning.
196  int left = endloaded - space.end;
197  memmove(space.begin, space.end, left);
198  space.end = space.begin;
199  endloaded = space.begin+left;
200  }
201  if (fill() > 0)
202  return buf_read(pointer,n);// more bytes are read.
203  else
204  {
205  // No more bytes to read, return all that we have left.
206  pointer = space.end;
207  space.end = endloaded;
208  return endloaded - pointer;
209  }
210  }
211 }

SHOGUN Machine Learning Toolbox - Documentation