[JAVA-567] skip() throw exception with the source code version 2.7.2-141 Created: 14/May/12  Updated: 18/Jun/12  Resolved: 17/May/12

Status: Closed
Project: Java Driver
Component/s: GridFS
Affects Version/s: None
Fix Version/s: 2.8.0

Type: Bug Priority: Major - P3
Reporter: liugen Assignee: Daniel Gottlieb (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

windows7


Issue Links:
Related
is related to JAVA-332 GridFS: Allow seek/reads (get part of... Closed

 Description   

The java driver is compiled by myself, and source version is 2.7.2-141.
With java driver's 2.7.2 and 2.7.3, it works well, for the skip() is java's default function.
in my code:

try{
  Mongo mongo = new Mongo("localhost");
  DB db = mongo.getDB("test");
  GridFS gridFS = new GridFS(DB, "file");
  File file = new File("d:/logs.txt");  // the file's size is about 200 byte.
  GridFSInputFile input = gridFS.createFile(file);
  input.save():
  GridFSDBFile read = gridFS.find(new ObjectId(input.getId().toString()));
  try{
  }catch(IOException e){
    System.out.println(e.toString()); // here catch the exception: com.mongodb.MongoException: can't find a chunk! file id.....
  }
}catch(Exception e){
 System.out.println(e.toString());
}

When I run this sample code, a exception was throwed with error message:
com.mongodb.MongoException: can't find a chunk! file id.....

Then I debug in skip() function:

public long skip(long numBytesToSkip) throws IOException { 
            if (numBytesToSkip <= 0) 
                return 0; 
 
 
            if (_currentChunkIdx == _numChunks) 
                //We're actually skipping over the back end of the 
file, short-circuit here 
                //Don't count those extra bytes to skip in with the 
return value 
                return 0; 
 
 
            if (_offset + numBytesToSkip <= _chunkSize) { 
                //We're skipping over bytes in the current chunk, 
adjust the offset accordingly 
                _offset += numBytesToSkip; 
                if (_data == null && _currentChunkIdx < _numChunks) // 
if the _currentChunkIdx is -1, getChunk will throw exception 
                    _data = getChunk(_currentChunkIdx); 
 
 
                return numBytesToSkip; 
            } 
 
 
            //We skipping over the remainder of this chunk, could do 
this less recursively... 
            ++_currentChunkIdx; 
            long skippedBytes = 0; 
            if (_currentChunkIdx < _numChunks) 
                skippedBytes = _chunkSize - _offset; 
            else 
                skippedBytes = _lastChunkSize; 
 
 
            _offset = 0; 
            _data = null; 
 
 
            return skippedBytes + skip(numBytesToSkip - skippedBytes); 
        } 

In the line " _data = getChunk(_currentChunkIdx)", it throw exception
for _currentChunkIdx is -1.
So maybe this is a bug here.



 Comments   
Comment by Jeffrey Yemin [ 18/Jun/12 ]

Closing for 2.8.0 release.

Comment by Daniel Gottlieb (Inactive) [ 15/May/12 ]

The new skip method defined in the patch https://github.com/mongodb/mongo-java-driver/commit/c3e1d1ea7cc98e3350c74b23810fdda7ebdc152a does exactly that.

Comment by liugen [ 15/May/12 ]

Why not directly calculate the last chunk idx and the offset on that chunk like C# driver?

// in mongo-csharp-driver / Driver / GridFS / MongoGridFSStream.cs
public override long Seek(long offset, SeekOrigin origin)
{
if (_disposed)

{ throw new ObjectDisposedException("MongoGridFSStream"); }

switch (origin)

{ case SeekOrigin.Begin: _position = offset; break; case SeekOrigin.Current: _position += offset; break; case SeekOrigin.End: _position = _length + offset; break; default: throw new ArgumentException("origin"); }

if (_length < _position)

{ SetLength(_position); }

return _position;
}

Comment by Daniel Gottlieb (Inactive) [ 14/May/12 ]

The code that will presumably fix your issue are in the following patches:
https://github.com/mongodb/mongo-java-driver/commit/c3e1d1ea7cc98e3350c74b23810fdda7ebdc152a
https://github.com/mongodb/mongo-java-driver/commit/ac5769ef0d474016650123aa3361f7b5eb0892db

Comment by Jeffrey Yemin [ 14/May/12 ]

This bug was introduced by changes in scope of JAVA-332

Comment by Daniel Gottlieb (Inactive) [ 14/May/12 ]

I can't exactly reproduce your test case verbatim, but the skip function that you debugged got a facelift very recently on master for (seemingly) the same problem as you're seeing. You can try building the jar off master to see if that fixes your problem. Alternatively this problem only comes up when skip() is called before any read() methods are invoked. An (admittedly silly) workaround would be to read one byte then skip one less byte:

static long fixedSkip(GridFSDBFile gridFSFile, long numBytesToSkip) {
  if (numBytesToSkip <= 0)
    return 0;
 
  gridFSFile.read();
  return gridFSFile.skip(numBytesToSkip - 1) + 1;
}

Comment by Daniel Gottlieb (Inactive) [ 14/May/12 ]

adding code tags for readability

Comment by Jeffrey Yemin [ 14/May/12 ]

Can you check that this is a duplicate of the pull request you recently merged? I think it is.

Generated at Thu Feb 08 08:52:35 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.