Client write refactor

Rewriting how client writes out blocks to make it easier to add remote blocks.

The current design is as follows:

Users requests access to a block

```java
Block block = Blocks.createBlock(tachyonFS, blockId, blockCapacityByte);
```

From there, the user can write to it by accessing its `Channel`.

```java
WritableBlockChannel channel = block.write();
channel.write(byteBuffer);
channel.close();
```

When the block is full, write returns -1, so you do this in a loop and create new blocks.

```java
while (buffer.remaining() > 0) {
  int n = mCurrentBlockChannel.write(buffer);
  if (n <= 0) {
    // block full, get new block
    getNextBlock();
  }
}
```

There is still one bug that I am tracking down (TachyonFSTest.unlockBlockTest2 and TachyonFSTest.lockBlockTest2 are failing), but I think the design is good enough to share.
We should talk about how to unify these two efforts: client api and
eviction; when I add remote write I don't want to reinvent this code again.

I have a local patch that delegates to handler but don't feel that it makes
things better.  It's trying to do the same thing as this patch, just won't
work for remote write case.

This patch should only go in once the unification is clear.
On Sep 11, 2014 1:44 AM, "shimingfei" <notifications@github.com> wrote:

> In core/src/main/java/tachyon/client/LocalWritableBlockChannel.java:
>
> > +
> > +  public LocalWritableBlockChannel(TachyonFS tachyonFS, long blockId) throws IOException {
> > +    mTachyonFS = tachyonFS;
> > +    mBlockId = blockId;
> > +    File localFolder = tachyonFS.createAndGetUserLocalTempFolder();
> > +    if (localFolder == null) {
> > +      throw new IOException("Failed to create temp user folder for tachyon client.");
> > +    }
> > +
> > +    mLocalFilePath = CommonUtils.concat(localFolder.getPath(), blockId);
> > +    mLocalFile = new RandomAccessFile(mLocalFilePath, "rw");
> > +    // change the permission of the temporary file in order that the worker can move it.
> > +    CommonUtils.changeLocalFileToFullPermission(mLocalFilePath);
> > +    // use the sticky bit, only the client and the worker can write to the block
> > +    CommonUtils.setLocalFileStickyBit(mLocalFilePath);
> > +    mLocalFileChannel = new CountingWritableByteChannel(mLocalFile.getChannel());
>
> @dcapwell <https://github.com/dcapwell>
> I think BlockHandler can implement ByteChannel, so that
> LocalWritableBlockChannel can delegate BlockHandler to do the job.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/amplab/tachyon/pull/427/files#r17410015>.
>