private DataChunk readSamples(String channelName, Timestamp from) throws Exception {
    DataChunk chunk = new DataChunk(chunkSize);

    BufferedReader br = null;
    String currentLine = "";
    Timestamp lastIndex = indexes.floorKey(from);
    Integer lineToStart = lastIndex == null ? 1 : indexes.get(lastIndex);
    Integer lineNumber = -1;
    try {
      br = new BufferedReader(new FileReader(csvFile));
      while ((currentLine = br.readLine()) != null) {
        lineNumber++;
        if (lineNumber < lineToStart) continue;
        String[] columns = getColumns(currentLine);
        if (columns[channel_name] != null && columns[channel_name].equals(channelName)) {
          // Get time stamp
          final java.sql.Timestamp stamp = java.sql.Timestamp.valueOf(columns[smpl_time]);
          stamp.setNanos(Integer.valueOf(columns[nanosecs]));
          final Timestamp time = fromSQLTimestamp(stamp);
          if (time.compareTo(from) >= 0) {
            final VType value = decodeValue(columns, time);
            SourceData data = new SourceData(time, value);
            if (!chunk.add(data)) {
              TimeInterval i = chunk.getInterval();
              if (i != null) indexes.put(i.getEnd(), lineNumber);
              break;
            }
          }
        }
      }
    } finally {
      if (br != null) br.close();
    }
    return chunk;
  }
 /**
  * Returns <code>true</code> if {@link TimeInterval} i1 intersects {@link TimeInterval} i2, <code>
  * false</code> otherwise (<code>null</code> border means infinity).
  */
 public static boolean intersects(TimeInterval i1, TimeInterval i2) {
   if (i1 == null || i2 == null) return false;
   i1 = arrange(i1);
   i2 = arrange(i2);
   if (i1.getStart() == null && i1.getEnd() == null) {
     return true;
   } else if (i1.getStart() != null && i1.getEnd() == null) {
     if (i2.getEnd() == null) return true;
     else if (i2.getStart() == null && i2.getEnd() != null) return i1.contains(i2.getEnd());
     else return i1.contains(i2.getEnd()) || i1.contains(i2.getStart());
   } else if (i1.getStart() == null && i1.getEnd() != null) {
     if (i2.getStart() == null) return true;
     else if (i2.getStart() != null && i2.getEnd() == null) return i1.contains(i2.getStart());
     else return i1.contains(i2.getEnd()) || i1.contains(i2.getStart());
   } else {
     if (i2.getStart() == null && i2.getEnd() == null) return true;
     else if (i2.getStart() == null || i2.getEnd() == null)
       return i2.contains(i1.getEnd()) || i2.contains(i1.getStart());
     else
       return i1.contains(i2.getStart())
           || i1.contains(i2.getEnd())
           || i2.contains(i1.getStart())
           || i2.contains(i1.getEnd());
   }
 }
 /**
  * Returns <code>true</code> if {@link TimeInterval} i1 contains {@link TimeInterval} i2, <code>
  * false</code> otherwise (<code>null</code> border means infinity).
  */
 public static boolean contains(TimeInterval i1, TimeInterval i2) {
   if (i1 == null || i2 == null) return false;
   i1 = arrange(i1);
   i2 = arrange(i2);
   if (i2.getStart() == null && i2.getEnd() == null)
     return i1.getStart() == null && i1.getEnd() == null;
   else if (i2.getStart() != null && i2.getEnd() == null)
     return i1.contains(i2.getStart()) && i1.getEnd() == null;
   else if (i2.getStart() == null && i2.getEnd() != null)
     return i1.getStart() == null && i1.contains(i2.getEnd());
   else return i1.contains(i2.getStart()) && i1.contains(i2.getEnd());
 }
 /** Returns a formated {@link String} from the specified {@link TimeInterval}. */
 public static String format(TimeInterval i) {
   if (i == null) return "[]";
   return "[" + format(i.getStart()) + " - " + format(i.getEnd()) + "]";
 }
 /** Returns a re-arranged {@link TimeInterval} if borders order is reversed. */
 public static TimeInterval arrange(TimeInterval i) {
   if (i.getStart() != null && i.getEnd() != null && i.getStart().compareTo(i.getEnd()) > 0)
     return TimeInterval.between(i.getEnd(), i.getStart());
   return i;
 }
  /**
   * Returns the result of {@link TimeInterval} i1 &amp; i2 intersection, <code>null</code> if i1
   * does not intersects i2 (<code>null</code> border means infinity).
   */
  public static TimeInterval intersection(TimeInterval i1, TimeInterval i2) {
    if (i1 == null || i2 == null) return null;
    if (!intersects(i1, i2)) return null;
    i1 = arrange(i1);
    i2 = arrange(i2);
    Instant a = null;
    if (i1.getStart() == null && i2.getStart() == null) a = null;
    else if (i1.getStart() == null && i2.getStart() != null) a = i2.getStart();
    else if (i1.getStart() != null && i2.getStart() == null) a = i1.getStart();
    else a = max(i1.getStart(), i2.getStart());

    Instant b = null;
    if (i1.getEnd() == null && i2.getEnd() == null) b = null;
    else if (i1.getEnd() == null && i2.getEnd() != null) b = i2.getEnd();
    else if (i1.getEnd() != null && i2.getEnd() == null) b = i1.getEnd();
    else b = min(i1.getEnd(), i2.getEnd());

    return TimeInterval.between(a, b);
  }