SHOGUN  v2.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 }
42 
43 void CIOBuffer::use_file(int fd)
44 {
45  working_file = fd;
46 }
47 
48 int CIOBuffer::open_file(const char* name, char flag)
49 {
50  int ret=1;
51  switch(flag)
52  {
53  case 'r':
54  working_file = open(name, O_RDONLY|O_LARGEFILE);
55  break;
56 
57  case 'w':
58  working_file = open(name, O_CREAT|O_TRUNC|O_WRONLY, 0666);
59  break;
60 
61  default:
62  SG_ERROR("Unknown file operation. Something other than 'r'/'w' specified.\n");
63  ret = 0;
64  }
65  return ret;
66 }
67 
69 {
70  lseek(working_file, 0, SEEK_SET);
72  space.end = space.begin;
73 }
74 
75 void CIOBuffer::set(char *p)
76 {
77  space.end = p;
78 }
79 
80 ssize_t CIOBuffer::read_file(void* buf, size_t nbytes)
81 {
82  return read(working_file, buf, nbytes);
83 }
84 
86 {
87  if (space.end_array - endloaded == 0)
88  {
89  size_t offset = endloaded - space.begin;
91  endloaded = space.begin+offset;
92  }
93  ssize_t num_read = read_file(endloaded, space.end_array - endloaded);
94  if (num_read >= 0)
95  {
96  endloaded = endloaded+num_read;
97  return num_read;
98  }
99  else
100  return 0;
101 }
102 
103 ssize_t CIOBuffer::write_file(const void* buf, size_t nbytes)
104 {
105  return write(working_file, buf, nbytes);
106 }
107 
109 {
110  if (write_file(space.begin, space.index()) != (int) space.index())
111  SG_ERROR("Error, failed to write example!\n");
112  space.end = space.begin;
113  fsync(working_file);
114 }
115 
117 {
118  if (working_file < 0)
119  return false;
120  else
121  {
122  int r = close(working_file);
123  if (r < 0)
124  SG_ERROR("Error closing the file!\n");
125  return true;
126  }
127 }
128 
129 ssize_t CIOBuffer::readto(char* &pointer, char terminal)
130 {
131 //Return a pointer to the bytes before the terminal. Must be less
132 //than the buffer size.
133  pointer = space.end;
134  while (pointer != endloaded && *pointer != terminal)
135  pointer++;
136  if (pointer != endloaded)
137  {
138  size_t n = pointer - space.end;
139  space.end = pointer+1;
140  pointer -= n;
141  return n;
142  }
143  else
144  {
145  if (endloaded == space.end_array)
146  {
147  size_t left = endloaded - space.end;
148  memmove(space.begin, space.end, left);
149  space.end = space.begin;
150  endloaded = space.begin+left;
151  pointer = endloaded;
152  }
153  if (fill() > 0)// more bytes are read.
154  return readto(pointer,terminal);
155  else //no more bytes to read, return nothing.
156  return 0;
157  }
158 }
159 
160 void CIOBuffer::buf_write(char* &pointer, int n)
161 {
162  if (space.end + n <= space.end_array)
163  {
164  pointer = space.end;
165  space.end += n;
166  }
167  else // Time to dump the file
168  {
169  if (space.end != space.begin)
170  flush();
171  else // Array is short, so increase size.
172  {
175  }
176  buf_write(pointer,n);
177  }
178 }
179 
180 unsigned int CIOBuffer::buf_read(char* &pointer, int n)
181 {
182  // Return a pointer to the next n bytes.
183  // n must be smaller than the maximum size.
184  if (space.end + n <= endloaded)
185  {
186  pointer = space.end;
187  space.end += n;
188  return n;
189  }
190  else // out of bytes, so refill.
191  {
192  if (space.end != space.begin) //There exists room to shift.
193  {
194  // Out of buffer so swap to beginning.
195  int left = endloaded - space.end;
196  memmove(space.begin, space.end, left);
197  space.end = space.begin;
198  endloaded = space.begin+left;
199  }
200  if (fill() > 0)
201  return buf_read(pointer,n);// more bytes are read.
202  else
203  {
204  // No more bytes to read, return all that we have left.
205  pointer = space.end;
206  space.end = endloaded;
207  return endloaded - pointer;
208  }
209  }
210 }

SHOGUN Machine Learning Toolbox - Documentation