Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E33B318987 for ; Sat, 10 Oct 2015 08:30:48 +0000 (UTC) Received: (qmail 20315 invoked by uid 500); 10 Oct 2015 08:30:48 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 20209 invoked by uid 500); 10 Oct 2015 08:30:48 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 19927 invoked by uid 99); 10 Oct 2015 08:30:48 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 10 Oct 2015 08:30:48 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C92B6E08DF; Sat, 10 Oct 2015 08:30:47 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: benedict@apache.org To: commits@cassandra.apache.org Date: Sat, 10 Oct 2015 08:30:52 -0000 Message-Id: <07cfd3eefa114e3ea77d17235ba453e2@git.apache.org> In-Reply-To: <65fb9c62ac174e2e8bc5c4fd647bbcc9@git.apache.org> References: <65fb9c62ac174e2e8bc5c4fd647bbcc9@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [06/10] cassandra git commit: Merge branch 'cassandra-2.1' into cassandra-2.2 Merge branch 'cassandra-2.1' into cassandra-2.2 Conflicts: CHANGES.txt Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/35292846 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/35292846 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/35292846 Branch: refs/heads/cassandra-2.2 Commit: 352928467b4ee3e42d96455b5c2d040d9728b060 Parents: 3573faf f87e34e Author: Benedict Elliott Smith Authored: Sat Oct 10 09:22:46 2015 +0100 Committer: Benedict Elliott Smith Committed: Sat Oct 10 09:22:46 2015 +0100 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/io/util/ByteBufferDataInput.java | 8 +-- .../io/util/ByteBufferDataInputTest.java | 67 ++++++++++++++++++++ 3 files changed, 69 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/35292846/CHANGES.txt ---------------------------------------------------------------------- diff --cc CHANGES.txt index d57cc07,20529e8..ea0a2db --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,7 -1,5 +1,8 @@@ -2.1.11 +2.2.3 + * cqlsh pg-style-strings broken (CASSANDRA-10484) + * Make Hadoop CF splits more polite to custom orderered partitioners (CASSANDRA-10400) +Merged from 2.1: + * Fix mmap file segment seeking to EOF (CASSANDRA-10478) * Allow LOCAL_JMX to be easily overridden (CASSANDRA-10275) * Mark nodes as dead even if they've already left (CASSANDRA-10205) * Update internal python driver used by cqlsh (CASSANDRA-10161) http://git-wip-us.apache.org/repos/asf/cassandra/blob/35292846/src/java/org/apache/cassandra/io/util/ByteBufferDataInput.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/io/util/ByteBufferDataInput.java index 2f00687,0000000..bf926e9 mode 100644,000000..100644 --- a/src/java/org/apache/cassandra/io/util/ByteBufferDataInput.java +++ b/src/java/org/apache/cassandra/io/util/ByteBufferDataInput.java @@@ -1,177 -1,0 +1,171 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.io.util; + +import java.io.*; +import java.nio.ByteBuffer; + +import org.apache.cassandra.utils.ByteBufferUtil; + +public class ByteBufferDataInput extends AbstractDataInput implements FileDataInput, DataInput +{ + private final ByteBuffer buffer; + private final String filename; + private final long segmentOffset; + private int position; + + public ByteBufferDataInput(ByteBuffer buffer, String filename, long segmentOffset, int position) + { + assert buffer != null; + this.buffer = buffer; + this.filename = filename; + this.segmentOffset = segmentOffset; + this.position = position; + } + + // Only use when we know the seek in within the mapped segment. Throws an + // IOException otherwise. + public void seek(long pos) throws IOException + { + long inSegmentPos = pos - segmentOffset; - if (!contains(pos)) ++ if (inSegmentPos < 0 || inSegmentPos > buffer.capacity()) + throw new IOException(String.format("Seek position %d is not within mmap segment (seg offs: %d, length: %d)", pos, segmentOffset, buffer.capacity())); + + position = (int) inSegmentPos; + } + - public boolean contains(long pos) - { - long inSegmentPos = pos - segmentOffset; - return inSegmentPos >= 0 && inSegmentPos < buffer.capacity(); - } - + public long getFilePointer() + { + return segmentOffset + position; + } + + public long getPosition() + { + return segmentOffset + position; + } + + public long getPositionLimit() + { + return segmentOffset + buffer.capacity(); + } + + @Override + public boolean markSupported() + { + return false; + } + + public void reset(FileMark mark) throws IOException + { + assert mark instanceof MappedFileDataInputMark; + position = ((MappedFileDataInputMark) mark).position; + } + + public FileMark mark() + { + return new MappedFileDataInputMark(position); + } + + public long bytesPastMark(FileMark mark) + { + assert mark instanceof MappedFileDataInputMark; + assert position >= ((MappedFileDataInputMark) mark).position; + return position - ((MappedFileDataInputMark) mark).position; + } + + public boolean isEOF() throws IOException + { + return position == buffer.capacity(); + } + + public long bytesRemaining() throws IOException + { + return buffer.capacity() - position; + } + + public String getPath() + { + return filename; + } + + public int read() throws IOException + { + if (isEOF()) + return -1; + return buffer.get(position++) & 0xFF; + } + + /** + * Does the same thing as readFully do but without copying data (thread safe) + * @param length length of the bytes to read + * @return buffer with portion of file content + * @throws IOException on any fail of I/O operation + */ + public ByteBuffer readBytes(int length) throws IOException + { + int remaining = buffer.remaining() - position; + if (length > remaining) + throw new IOException(String.format("mmap segment underflow; remaining is %d but %d requested", + remaining, length)); + + if (length == 0) + return ByteBufferUtil.EMPTY_BYTE_BUFFER; + + ByteBuffer bytes = buffer.duplicate(); + bytes.position(buffer.position() + position).limit(buffer.position() + position + length); + position += length; + + // we have to copy the data in case we unreference the underlying sstable. See CASSANDRA-3179 + ByteBuffer clone = ByteBuffer.allocate(bytes.remaining()); + clone.put(bytes); + clone.flip(); + return clone; + } + + @Override + public final void readFully(byte[] bytes) throws IOException + { + ByteBufferUtil.arrayCopy(buffer, buffer.position() + position, bytes, 0, bytes.length); + position += bytes.length; + } + + @Override + public final void readFully(byte[] bytes, int offset, int count) throws IOException + { + ByteBufferUtil.arrayCopy(buffer, buffer.position() + position, bytes, offset, count); + position += count; + } + + private static class MappedFileDataInputMark implements FileMark + { + int position; + + MappedFileDataInputMark(int position) + { + this.position = position; + } + } + + @Override + public String toString() { + return getClass().getSimpleName() + "(" + + "filename='" + filename + "'" + + ", position=" + position + + ")"; + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/35292846/test/unit/org/apache/cassandra/io/util/ByteBufferDataInputTest.java ---------------------------------------------------------------------- diff --cc test/unit/org/apache/cassandra/io/util/ByteBufferDataInputTest.java index 0000000,0000000..af2d1dc new file mode 100644 --- /dev/null +++ b/test/unit/org/apache/cassandra/io/util/ByteBufferDataInputTest.java @@@ -1,0 -1,0 +1,67 @@@ ++/* ++* Licensed to the Apache Software Foundation (ASF) under one ++* or more contributor license agreements. See the NOTICE file ++* distributed with this work for additional information ++* regarding copyright ownership. The ASF licenses this file ++* to you under the Apache License, Version 2.0 (the ++* "License"); you may not use this file except in compliance ++* with the License. You may obtain a copy of the License at ++* ++* http://www.apache.org/licenses/LICENSE-2.0 ++* ++* Unless required by applicable law or agreed to in writing, ++* software distributed under the License is distributed on an ++* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++* KIND, either express or implied. See the License for the ++* specific language governing permissions and limitations ++* under the License. ++*/ ++package org.apache.cassandra.io.util; ++ ++import java.io.IOException; ++import java.nio.ByteBuffer; ++import java.nio.MappedByteBuffer; ++ ++import org.junit.Test; ++ ++import junit.framework.Assert; ++ ++public class ByteBufferDataInputTest ++{ ++ ++ @Test ++ public void testPositionAndSeek() throws IOException ++ { ++ ByteBufferDataInput bbdi = new ByteBufferDataInput(ByteBuffer.allocate(100), "", 15, 1); ++ Assert.assertEquals(99, bbdi.bytesRemaining()); ++ Assert.assertEquals(16, bbdi.getPosition()); ++ Assert.assertEquals(16, bbdi.getFilePointer()); ++// Assert.assertTrue(bbdi.markSupported()); ++ FileMark mark = bbdi.mark(); ++ bbdi.seek(115); ++ Assert.assertEquals(115, bbdi.getFilePointer()); ++ Assert.assertEquals(115, bbdi.getPosition()); ++ Assert.assertEquals(99, bbdi.bytesPastMark(mark)); ++ Assert.assertTrue(bbdi.isEOF()); ++ bbdi.seek(15); ++ Assert.assertEquals(15, bbdi.getFilePointer()); ++ Assert.assertEquals(15, bbdi.getPosition()); ++ try ++ { ++ bbdi.seek(14); ++ Assert.assertTrue(false); ++ } ++ catch (IOException t) ++ { ++ } ++ try ++ { ++ bbdi.seek(116); ++ Assert.assertTrue(false); ++ } ++ catch (IOException t) ++ { ++ } ++ } ++ ++}