SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 }
35 
37 {
38  size_t s = 1 << 16;
39  space.reserve(s);
41  working_file=-1;
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 (working_file>=0)
112  {
113  if (write_file(space.begin, space.index()) != (int) space.index())
114  SG_ERROR("Error, failed to write example!\n")
115  }
116  space.end = space.begin;
117  fsync(working_file);
118 }
119 
121 {
122  if (working_file < 0)
123  return false;
124  else
125  {
126  int r = close(working_file);
127  if (r < 0)
128  SG_ERROR("Error closing the file!\n")
129  return true;
130  }
131 }
132 
133 ssize_t CIOBuffer::readto(char* &pointer, char terminal)
134 {
135 //Return a pointer to the bytes before the terminal. Must be less
136 //than the buffer size.
137  pointer = space.end;
138  while (pointer != endloaded && *pointer != terminal)
139  pointer++;
140  if (pointer != endloaded)
141  {
142  size_t n = pointer - space.end;
143  space.end = pointer+1;
144  pointer -= n;
145  return n;
146  }
147  else
148  {
149  if (endloaded == space.end_array)
150  {
151  size_t left = endloaded - space.end;
152  memmove(space.begin, space.end, left);
153  space.end = space.begin;
154  endloaded = space.begin+left;
155  pointer = endloaded;
156  }
157  if (fill() > 0)// more bytes are read.
158  return readto(pointer,terminal);
159  else //no more bytes to read, return nothing.
160  return 0;
161  }
162 }
163 
164 void CIOBuffer::buf_write(char* &pointer, int n)
165 {
166  if (space.end + n <= space.end_array)
167  {
168  pointer = space.end;
169  space.end += n;
170  }
171  else // Time to dump the file
172  {
173  if (space.end != space.begin)
174  flush();
175  else // Array is short, so increase size.
176  {
179  }
180  buf_write(pointer,n);
181  }
182 }
183 
184 unsigned int CIOBuffer::buf_read(char* &pointer, int n)
185 {
186  // Return a pointer to the next n bytes.
187  // n must be smaller than the maximum size.
188  if (space.end + n <= endloaded)
189  {
190  pointer = space.end;
191  space.end += n;
192  return n;
193  }
194  else // out of bytes, so refill.
195  {
196  if (space.end != space.begin) //There exists room to shift.
197  {
198  // Out of buffer so swap to beginning.
199  int left = endloaded - space.end;
200  memmove(space.begin, space.end, left);
201  space.end = space.begin;
202  endloaded = space.begin+left;
203  }
204  if (fill() > 0)
205  return buf_read(pointer,n);// more bytes are read.
206  else
207  {
208  // No more bytes to read, return all that we have left.
209  pointer = space.end;
210  space.end = endloaded;
211  return endloaded - pointer;
212  }
213  }
214 }

SHOGUN Machine Learning Toolbox - Documentation