tagged 0.6.0-beta2

git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/tags/cassandra-0.6.0-beta2@915498 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eric Evans 2010-02-23 19:04:39 +00:00
parent 12cb7efc36
commit 60fa998afd
71 changed files with 3575 additions and 2155 deletions

View File

@ -17,7 +17,7 @@
~ specific language governing permissions and limitations
~ under the License.
-->
<project basedir="." default="build" name="apache-cassandra-incubating"
<project basedir="." default="build" name="apache-cassandra"
xmlns:ivy="antlib:org.apache.ivy.ant">
<property environment="env"/>
<property file="build.properties" />
@ -42,7 +42,7 @@
<property name="test.name" value="*Test"/>
<property name="test.unit.src" value="${test.dir}/unit"/>
<property name="dist.dir" value="${build.dir}/dist"/>
<property name="version" value="0.5.0"/>
<property name="version" value="0.6.0-beta1"/>
<property name="final.name" value="${ant.project.name}-${version}"/>
<property name="ivy.version" value="2.1.0" />
<property name="ivy.url"
@ -314,6 +314,7 @@
<include name="**"/>
<exclude name="build/**" />
<exclude name="src/gen-java/**" />
<exclude name="interface/avro/**" />
</tarfileset>
</tar>
</target>

View File

@ -1,3 +1,21 @@
<!--
~ 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.
-->
<Storage>
<!-- ZooKeeper options -->

View File

@ -1,3 +1,21 @@
/**
* 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.
*/
import java.io.IOException;
import java.util.Arrays;
import java.util.SortedMap;
@ -117,4 +135,4 @@ public class WordCount extends Configured implements Tool
}
return 0;
}
}
}

View File

@ -1,61 +1,79 @@
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.apache.cassandra.db.*;
import org.apache.cassandra.service.StorageProxy;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.thrift.ConsistencyLevel;
public class WordCountSetup
{
private static final Logger logger = Logger.getLogger(WordCountSetup.class);
public static final int TEST_COUNT = 4;
public static void main(String[] args) throws Exception
{
StorageService.instance.initClient();
logger.info("Sleeping " + WordCount.RING_DELAY);
Thread.sleep(WordCount.RING_DELAY);
assert !StorageService.instance.getLiveNodes().isEmpty();
RowMutation rm;
ColumnFamily cf;
byte[] columnName;
// text0: no rows
// text1: 1 row, 1 word
columnName = "text1".getBytes();
rm = new RowMutation(WordCount.KEYSPACE, "Key0");
cf = ColumnFamily.create(WordCount.KEYSPACE, WordCount.COLUMN_FAMILY);
cf.addColumn(new Column(columnName, "word1".getBytes(), 0));
rm.add(cf);
StorageProxy.mutateBlocking(Arrays.asList(rm), ConsistencyLevel.ONE);
logger.info("added text1");
// text2: 1 row, 2 words
columnName = "text2".getBytes();
rm = new RowMutation(WordCount.KEYSPACE, "Key0");
cf = ColumnFamily.create(WordCount.KEYSPACE, WordCount.COLUMN_FAMILY);
cf.addColumn(new Column(columnName, "word1 word2".getBytes(), 0));
rm.add(cf);
StorageProxy.mutateBlocking(Arrays.asList(rm), ConsistencyLevel.ONE);
logger.info("added text2");
// text3: 1000 rows, 1 word
columnName = "text3".getBytes();
for (int i = 0; i < 1000; i++)
{
rm = new RowMutation(WordCount.KEYSPACE, "Key" + i);
cf = ColumnFamily.create(WordCount.KEYSPACE, WordCount.COLUMN_FAMILY);
cf.addColumn(new Column(columnName, "word1".getBytes(), 0));
rm.add(cf);
StorageProxy.mutateBlocking(Arrays.asList(rm), ConsistencyLevel.ONE);
}
logger.info("added text3");
System.exit(0);
}
}
/**
* 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.
*/
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.apache.cassandra.db.*;
import org.apache.cassandra.service.StorageProxy;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.thrift.ConsistencyLevel;
public class WordCountSetup
{
private static final Logger logger = Logger.getLogger(WordCountSetup.class);
public static final int TEST_COUNT = 4;
public static void main(String[] args) throws Exception
{
StorageService.instance.initClient();
logger.info("Sleeping " + WordCount.RING_DELAY);
Thread.sleep(WordCount.RING_DELAY);
assert !StorageService.instance.getLiveNodes().isEmpty();
RowMutation rm;
ColumnFamily cf;
byte[] columnName;
// text0: no rows
// text1: 1 row, 1 word
columnName = "text1".getBytes();
rm = new RowMutation(WordCount.KEYSPACE, "Key0");
cf = ColumnFamily.create(WordCount.KEYSPACE, WordCount.COLUMN_FAMILY);
cf.addColumn(new Column(columnName, "word1".getBytes(), 0));
rm.add(cf);
StorageProxy.mutateBlocking(Arrays.asList(rm), ConsistencyLevel.ONE);
logger.info("added text1");
// text2: 1 row, 2 words
columnName = "text2".getBytes();
rm = new RowMutation(WordCount.KEYSPACE, "Key0");
cf = ColumnFamily.create(WordCount.KEYSPACE, WordCount.COLUMN_FAMILY);
cf.addColumn(new Column(columnName, "word1 word2".getBytes(), 0));
rm.add(cf);
StorageProxy.mutateBlocking(Arrays.asList(rm), ConsistencyLevel.ONE);
logger.info("added text2");
// text3: 1000 rows, 1 word
columnName = "text3".getBytes();
for (int i = 0; i < 1000; i++)
{
rm = new RowMutation(WordCount.KEYSPACE, "Key" + i);
cf = ColumnFamily.create(WordCount.KEYSPACE, WordCount.COLUMN_FAMILY);
cf.addColumn(new Column(columnName, "word1".getBytes(), 0));
rm.add(cf);
StorageProxy.mutateBlocking(Arrays.asList(rm), ConsistencyLevel.ONE);
}
logger.info("added text3");
System.exit(0);
}
}

2
debian/init vendored
View File

@ -22,7 +22,7 @@ JSVC=/usr/bin/jsvc
JVM_MAX_MEM="1G"
JVM_START_MEM="128M"
[ -e /usr/share/cassandra/apache-cassandra-incubating.jar ] || exit 0
[ -e /usr/share/cassandra/apache-cassandra.jar ] || exit 0
[ -e /etc/cassandra/storage-conf.xml ] || exit 0
# Read configuration variable file if it is present

6
debian/rules vendored
View File

@ -36,10 +36,10 @@ install: build
dh_install
# Copy in the jar and symlink to something stable
dh_install build/apache-cassandra-incubating-$(VERSION).jar \
dh_install build/apache-cassandra-$(VERSION).jar \
usr/share/cassandra
dh_link usr/share/cassandra/apache-cassandra-incubating-$(VERSION).jar \
usr/share/cassandra/apache-cassandra-incubating.jar
dh_link usr/share/cassandra/apache-cassandra-$(VERSION).jar \
usr/share/cassandra/apache-cassandra.jar
# Build architecture-independent files here.
binary-indep: build install

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.Map;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -4,6 +4,27 @@
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*/
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;
import java.util.ArrayList;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.auth;
/*
*
* 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.
*
*/
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.AuthenticationRequest;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.auth;
/*
*
* 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.
*
*/
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.AuthenticationRequest;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.auth;
/*
*
* 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.
*
*/
import java.io.*;
import java.security.MessageDigest;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.avro;
/*
*
* 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.
*
*/
import java.util.Arrays;
import org.apache.avro.util.Utf8;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.avro;
/*
*
* 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.
*
*/
import java.io.IOException;
import java.nio.ByteBuffer;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.avro;
/*
*
* 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.
*
*/
import org.apache.avro.util.Utf8;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.avro;
/*
*
* 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.
*
*/
import java.nio.ByteBuffer;
import org.apache.avro.generic.GenericArray;
@ -105,4 +126,4 @@ class ErrorFactory
{
return newUnavailableException(new Utf8(why));
}
}
}

View File

@ -1,22 +1,43 @@
package org.apache.cassandra.cache;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class AbstractCache
{
static void registerMBean(Object cache, String table, String name)
{
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try
{
String mbeanName = "org.apache.cassandra.db:type=Caches,keyspace=" + table + ",cache=" + name;
mbs.registerMBean(cache, new ObjectName(mbeanName));
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
package org.apache.cassandra.cache;
/*
*
* 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.
*
*/
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class AbstractCache
{
static void registerMBean(Object cache, String table, String name)
{
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try
{
String mbeanName = "org.apache.cassandra.db:type=Caches,keyspace=" + table + ",cache=" + name;
mbs.registerMBean(cache, new ObjectName(mbeanName));
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}

View File

@ -1,7 +1,28 @@
package org.apache.cassandra.cache;
public interface IAggregatableCacheProvider<K, V>
{
public InstrumentedCache<K, V> getCache();
public long getObjectCount();
}
package org.apache.cassandra.cache;
/*
*
* 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.
*
*/
public interface IAggregatableCacheProvider<K, V>
{
public InstrumentedCache<K, V> getCache();
public long getObjectCount();
}

View File

@ -1,85 +1,106 @@
package org.apache.cassandra.cache;
import java.util.concurrent.atomic.AtomicLong;
import com.reardencommerce.kernel.collections.shared.evictable.ConcurrentLinkedHashMap;
public class InstrumentedCache<K, V>
{
private int capacity;
private final ConcurrentLinkedHashMap<K, V> map;
private final AtomicLong requests = new AtomicLong(0);
private final AtomicLong hits = new AtomicLong(0);
long lastRequests, lastHits;
public InstrumentedCache(int capacity)
{
this.capacity = capacity;
map = ConcurrentLinkedHashMap.create(ConcurrentLinkedHashMap.EvictionPolicy.SECOND_CHANCE, capacity);
}
public void put(K key, V value)
{
map.put(key, value);
}
public V get(K key)
{
V v = map.get(key);
requests.incrementAndGet();
if (v != null)
hits.incrementAndGet();
return v;
}
public V getInternal(K key)
{
return map.get(key);
}
public void remove(K key)
{
map.remove(key);
}
public int getCapacity()
{
return capacity;
}
public void setCapacity(int capacity)
{
map.setCapacity(capacity);
this.capacity = capacity;
}
public int getSize()
{
return map.size();
}
public long getHits()
{
return hits.get();
}
public long getRequests()
{
return requests.get();
}
public double getRecentHitRate()
{
long r = requests.get();
long h = hits.get();
try
{
return ((double)(h - lastHits)) / (r - lastRequests);
}
finally
{
lastRequests = r;
lastHits = h;
}
}
}
package org.apache.cassandra.cache;
/*
*
* 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.
*
*/
import java.util.concurrent.atomic.AtomicLong;
import com.reardencommerce.kernel.collections.shared.evictable.ConcurrentLinkedHashMap;
public class InstrumentedCache<K, V>
{
private int capacity;
private final ConcurrentLinkedHashMap<K, V> map;
private final AtomicLong requests = new AtomicLong(0);
private final AtomicLong hits = new AtomicLong(0);
long lastRequests, lastHits;
public InstrumentedCache(int capacity)
{
this.capacity = capacity;
map = ConcurrentLinkedHashMap.create(ConcurrentLinkedHashMap.EvictionPolicy.SECOND_CHANCE, capacity);
}
public void put(K key, V value)
{
map.put(key, value);
}
public V get(K key)
{
V v = map.get(key);
requests.incrementAndGet();
if (v != null)
hits.incrementAndGet();
return v;
}
public V getInternal(K key)
{
return map.get(key);
}
public void remove(K key)
{
map.remove(key);
}
public int getCapacity()
{
return capacity;
}
public void setCapacity(int capacity)
{
map.setCapacity(capacity);
this.capacity = capacity;
}
public int getSize()
{
return map.size();
}
public long getHits()
{
return hits.get();
}
public long getRequests()
{
return requests.get();
}
public double getRecentHitRate()
{
long r = requests.get();
long h = hits.get();
try
{
return ((double)(h - lastHits)) / (r - lastRequests);
}
finally
{
lastRequests = r;
lastHits = h;
}
}
}

View File

@ -1,78 +1,99 @@
package org.apache.cassandra.cache;
public class JMXAggregatingCache implements JMXAggregatingCacheMBean
{
private final Iterable<IAggregatableCacheProvider> cacheProviders;
public JMXAggregatingCache(Iterable<IAggregatableCacheProvider> caches, String table, String name)
{
this.cacheProviders = caches;
AbstractCache.registerMBean(this, table, name);
}
public int getCapacity()
{
int capacity = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
capacity += cacheProvider.getCache().getCapacity();
}
return capacity;
}
public void setCapacity(int capacity)
{
long totalObjects = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
totalObjects += cacheProvider.getObjectCount();
}
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
double ratio = ((double)cacheProvider.getObjectCount()) / totalObjects;
cacheProvider.getCache().setCapacity((int)(capacity * ratio));
}
}
public int getSize()
{
int size = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
size += cacheProvider.getCache().getSize();
}
return size;
}
public long getRequests()
{
long requests = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
requests += cacheProvider.getCache().getRequests();
}
return requests;
}
public long getHits()
{
long hits = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
hits += cacheProvider.getCache().getHits();
}
return hits;
}
public double getRecentHitRate()
{
int n = 0;
double rate = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
rate += cacheProvider.getCache().getRecentHitRate();
n++;
}
return rate / n;
}
}
package org.apache.cassandra.cache;
/*
*
* 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.
*
*/
public class JMXAggregatingCache implements JMXAggregatingCacheMBean
{
private final Iterable<IAggregatableCacheProvider> cacheProviders;
public JMXAggregatingCache(Iterable<IAggregatableCacheProvider> caches, String table, String name)
{
this.cacheProviders = caches;
AbstractCache.registerMBean(this, table, name);
}
public int getCapacity()
{
int capacity = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
capacity += cacheProvider.getCache().getCapacity();
}
return capacity;
}
public void setCapacity(int capacity)
{
long totalObjects = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
totalObjects += cacheProvider.getObjectCount();
}
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
double ratio = ((double)cacheProvider.getObjectCount()) / totalObjects;
cacheProvider.getCache().setCapacity((int)(capacity * ratio));
}
}
public int getSize()
{
int size = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
size += cacheProvider.getCache().getSize();
}
return size;
}
public long getRequests()
{
long requests = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
requests += cacheProvider.getCache().getRequests();
}
return requests;
}
public long getHits()
{
long hits = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
hits += cacheProvider.getCache().getHits();
}
return hits;
}
public double getRecentHitRate()
{
int n = 0;
double rate = 0;
for (IAggregatableCacheProvider cacheProvider : cacheProviders)
{
rate += cacheProvider.getCache().getRecentHitRate();
n++;
}
return rate / n;
}
}

View File

@ -1,12 +1,33 @@
package org.apache.cassandra.cache;
public interface JMXAggregatingCacheMBean
{
public int getCapacity();
public void setCapacity(int capacity);
public int getSize();
public long getRequests();
public long getHits();
public double getRecentHitRate();
}
package org.apache.cassandra.cache;
/*
*
* 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.
*
*/
public interface JMXAggregatingCacheMBean
{
public int getCapacity();
public void setCapacity(int capacity);
public int getSize();
public long getRequests();
public long getHits();
public double getRecentHitRate();
}

View File

@ -1,10 +1,31 @@
package org.apache.cassandra.cache;
public class JMXInstrumentedCache<K, V> extends InstrumentedCache<K, V> implements JMXInstrumentedCacheMBean
{
public JMXInstrumentedCache(String table, String name, int capacity)
{
super(capacity);
AbstractCache.registerMBean(this, table, name);
}
}
package org.apache.cassandra.cache;
/*
*
* 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.
*
*/
public class JMXInstrumentedCache<K, V> extends InstrumentedCache<K, V> implements JMXInstrumentedCacheMBean
{
public JMXInstrumentedCache(String table, String name, int capacity)
{
super(capacity);
AbstractCache.registerMBean(this, table, name);
}
}

View File

@ -1,21 +1,42 @@
package org.apache.cassandra.cache;
public interface JMXInstrumentedCacheMBean
{
public int getCapacity();
public void setCapacity(int capacity);
public int getSize();
/** total request count since cache creation */
public long getRequests();
/** total cache hit count since cache creation */
public long getHits();
/**
* hits / requests since the last time getHitRate was called. serious telemetry apps should not use this,
* and should instead track the deltas from getHits / getRequests themselves, since those will not be
* affected by multiple users calling it. Provided for convenience only.
*/
public double getRecentHitRate();
}
package org.apache.cassandra.cache;
/*
*
* 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.
*
*/
public interface JMXInstrumentedCacheMBean
{
public int getCapacity();
public void setCapacity(int capacity);
public int getSize();
/** total request count since cache creation */
public long getRequests();
/** total cache hit count since cache creation */
public long getHits();
/**
* hits / requests since the last time getHitRate was called. serious telemetry apps should not use this,
* and should instead track the deltas from getHits / getRequests themselves, since those will not be
* affected by multiple users calling it. Provided for convenience only.
*/
public double getRecentHitRate();
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.concurrent;
/*
*
* 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.
*
*/
import java.util.concurrent.*;

View File

@ -1,213 +1,234 @@
package org.apache.cassandra.db.commitlog;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.utils.WrappedRunnable;
class CommitLogExecutorService extends AbstractExecutorService implements CommitLogExecutorServiceMBean
{
private final BlockingQueue<CheaterFutureTask> queue;
private volatile long completedTaskCount = 0;
public CommitLogExecutorService()
{
this(DatabaseDescriptor.getCommitLogSync() == DatabaseDescriptor.CommitLogSync.batch
? DatabaseDescriptor.getConcurrentWriters()
: 1024 * Runtime.getRuntime().availableProcessors());
}
public CommitLogExecutorService(int queueSize)
{
queue = new LinkedBlockingQueue<CheaterFutureTask>(queueSize);
Runnable runnable = new WrappedRunnable()
{
public void runMayThrow() throws Exception
{
if (DatabaseDescriptor.getCommitLogSync() == DatabaseDescriptor.CommitLogSync.batch)
{
while (true)
{
processWithSyncBatch();
completedTaskCount++;
}
}
else
{
while (true)
{
process();
completedTaskCount++;
}
}
}
};
new Thread(runnable, "COMMIT-LOG-WRITER").start();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try
{
mbs.registerMBean(this, new ObjectName("org.apache.cassandra.db:type=Commitlog"));
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
/**
* Get the current number of running tasks
*/
public int getActiveCount()
{
return 1;
}
/**
* Get the number of completed tasks
*/
public long getCompletedTasks()
{
return completedTaskCount;
}
/**
* Get the number of tasks waiting to be executed
*/
public long getPendingTasks()
{
return queue.size();
}
private void process() throws InterruptedException
{
queue.take().run();
}
private final ArrayList<CheaterFutureTask> incompleteTasks = new ArrayList<CheaterFutureTask>();
private final ArrayList taskValues = new ArrayList(); // TODO not sure how to generify this
private void processWithSyncBatch() throws Exception
{
CheaterFutureTask firstTask = queue.take();
if (!(firstTask.getRawCallable() instanceof CommitLog.LogRecordAdder))
{
firstTask.run();
return;
}
// attempt to do a bunch of LogRecordAdder ops before syncing
// (this is a little clunky since there is no blocking peek method,
// so we have to break it into firstTask / extra tasks)
incompleteTasks.clear();
taskValues.clear();
long end = System.nanoTime() + (long)(1000000 * DatabaseDescriptor.getCommitLogSyncBatchWindow());
// it doesn't seem worth bothering future-izing the exception
// since if a commitlog op throws, we're probably screwed anyway
incompleteTasks.add(firstTask);
taskValues.add(firstTask.getRawCallable().call());
while (!queue.isEmpty()
&& queue.peek().getRawCallable() instanceof CommitLog.LogRecordAdder
&& System.nanoTime() < end)
{
CheaterFutureTask task = queue.remove();
incompleteTasks.add(task);
taskValues.add(task.getRawCallable().call());
}
// now sync and set the tasks' values (which allows thread calling get() to proceed)
try
{
CommitLog.instance().sync();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
for (int i = 0; i < incompleteTasks.size(); i++)
{
incompleteTasks.get(i).set(taskValues.get(i));
}
}
@Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value)
{
return newTaskFor(Executors.callable(runnable, value));
}
@Override
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable)
{
return new CheaterFutureTask(callable);
}
public void execute(Runnable command)
{
try
{
queue.put((CheaterFutureTask)command);
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
public boolean isShutdown()
{
return false;
}
public boolean isTerminated()
{
return false;
}
// cassandra is crash-only so there's no need to implement the shutdown methods
public void shutdown()
{
throw new UnsupportedOperationException();
}
public List<Runnable> shutdownNow()
{
throw new UnsupportedOperationException();
}
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
{
throw new UnsupportedOperationException();
}
private static class CheaterFutureTask<V> extends FutureTask<V>
{
private final Callable rawCallable;
public CheaterFutureTask(Callable<V> callable)
{
super(callable);
rawCallable = callable;
}
public Callable getRawCallable()
{
return rawCallable;
}
@Override
public void set(V v)
{
super.set(v);
}
}
}
package org.apache.cassandra.db.commitlog;
/*
*
* 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.
*
*/
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.utils.WrappedRunnable;
class CommitLogExecutorService extends AbstractExecutorService implements CommitLogExecutorServiceMBean
{
private final BlockingQueue<CheaterFutureTask> queue;
private volatile long completedTaskCount = 0;
public CommitLogExecutorService()
{
this(DatabaseDescriptor.getCommitLogSync() == DatabaseDescriptor.CommitLogSync.batch
? DatabaseDescriptor.getConcurrentWriters()
: 1024 * Runtime.getRuntime().availableProcessors());
}
public CommitLogExecutorService(int queueSize)
{
queue = new LinkedBlockingQueue<CheaterFutureTask>(queueSize);
Runnable runnable = new WrappedRunnable()
{
public void runMayThrow() throws Exception
{
if (DatabaseDescriptor.getCommitLogSync() == DatabaseDescriptor.CommitLogSync.batch)
{
while (true)
{
processWithSyncBatch();
completedTaskCount++;
}
}
else
{
while (true)
{
process();
completedTaskCount++;
}
}
}
};
new Thread(runnable, "COMMIT-LOG-WRITER").start();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try
{
mbs.registerMBean(this, new ObjectName("org.apache.cassandra.db:type=Commitlog"));
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
/**
* Get the current number of running tasks
*/
public int getActiveCount()
{
return 1;
}
/**
* Get the number of completed tasks
*/
public long getCompletedTasks()
{
return completedTaskCount;
}
/**
* Get the number of tasks waiting to be executed
*/
public long getPendingTasks()
{
return queue.size();
}
private void process() throws InterruptedException
{
queue.take().run();
}
private final ArrayList<CheaterFutureTask> incompleteTasks = new ArrayList<CheaterFutureTask>();
private final ArrayList taskValues = new ArrayList(); // TODO not sure how to generify this
private void processWithSyncBatch() throws Exception
{
CheaterFutureTask firstTask = queue.take();
if (!(firstTask.getRawCallable() instanceof CommitLog.LogRecordAdder))
{
firstTask.run();
return;
}
// attempt to do a bunch of LogRecordAdder ops before syncing
// (this is a little clunky since there is no blocking peek method,
// so we have to break it into firstTask / extra tasks)
incompleteTasks.clear();
taskValues.clear();
long end = System.nanoTime() + (long)(1000000 * DatabaseDescriptor.getCommitLogSyncBatchWindow());
// it doesn't seem worth bothering future-izing the exception
// since if a commitlog op throws, we're probably screwed anyway
incompleteTasks.add(firstTask);
taskValues.add(firstTask.getRawCallable().call());
while (!queue.isEmpty()
&& queue.peek().getRawCallable() instanceof CommitLog.LogRecordAdder
&& System.nanoTime() < end)
{
CheaterFutureTask task = queue.remove();
incompleteTasks.add(task);
taskValues.add(task.getRawCallable().call());
}
// now sync and set the tasks' values (which allows thread calling get() to proceed)
try
{
CommitLog.instance().sync();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
for (int i = 0; i < incompleteTasks.size(); i++)
{
incompleteTasks.get(i).set(taskValues.get(i));
}
}
@Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value)
{
return newTaskFor(Executors.callable(runnable, value));
}
@Override
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable)
{
return new CheaterFutureTask(callable);
}
public void execute(Runnable command)
{
try
{
queue.put((CheaterFutureTask)command);
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
public boolean isShutdown()
{
return false;
}
public boolean isTerminated()
{
return false;
}
// cassandra is crash-only so there's no need to implement the shutdown methods
public void shutdown()
{
throw new UnsupportedOperationException();
}
public List<Runnable> shutdownNow()
{
throw new UnsupportedOperationException();
}
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
{
throw new UnsupportedOperationException();
}
private static class CheaterFutureTask<V> extends FutureTask<V>
{
private final Callable rawCallable;
public CheaterFutureTask(Callable<V> callable)
{
super(callable);
rawCallable = callable;
}
public Callable getRawCallable()
{
return rawCallable;
}
@Override
public void set(V v)
{
super.set(v);
}
}
}

View File

@ -1,193 +1,214 @@
package org.apache.cassandra.db.commitlog;
import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import org.apache.log4j.Logger;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.ColumnFamily;
import org.apache.cassandra.db.RowMutation;
import org.apache.cassandra.db.Table;
import org.apache.cassandra.io.util.BufferedRandomAccessFile;
import org.apache.cassandra.io.util.DataOutputBuffer;
public class CommitLogSegment
{
private static final Logger logger = Logger.getLogger(CommitLogSegment.class);
private final BufferedRandomAccessFile logWriter;
private final CommitLogHeader header;
public CommitLogSegment(int cfCount)
{
this.header = new CommitLogHeader(cfCount);
String logFile = DatabaseDescriptor.getLogFileLocation() + File.separator + "CommitLog-" + System.currentTimeMillis() + ".log";
logger.info("Creating new commitlog segment " + logFile);
try
{
logWriter = createWriter(logFile);
writeCommitLogHeader(header.toByteArray());
}
catch (IOException e)
{
throw new IOError(e);
}
}
public void writeHeader() throws IOException
{
seekAndWriteCommitLogHeader(header.toByteArray());
}
/** writes header at the beginning of the file, then seeks back to current position */
void seekAndWriteCommitLogHeader(byte[] bytes) throws IOException
{
long currentPos = logWriter.getFilePointer();
logWriter.seek(0);
writeCommitLogHeader(bytes);
logWriter.seek(currentPos);
}
private void writeCommitLogHeader(byte[] bytes) throws IOException
{
logWriter.writeLong(bytes.length);
logWriter.write(bytes);
logWriter.sync();
}
private static BufferedRandomAccessFile createWriter(String file) throws IOException
{
return new BufferedRandomAccessFile(file, "rw", 128 * 1024);
}
public CommitLogSegment.CommitLogContext write(RowMutation rowMutation, Object serializedRow) throws IOException
{
long currentPosition = -1L;
try
{
currentPosition = logWriter.getFilePointer();
CommitLogSegment.CommitLogContext cLogCtx = new CommitLogSegment.CommitLogContext(currentPosition);
Table table = Table.open(rowMutation.getTable());
// update header
for (ColumnFamily columnFamily : rowMutation.getColumnFamilies())
{
int id = table.getColumnFamilyId(columnFamily.name());
if (!header.isDirty(id))
{
header.turnOn(id, logWriter.getFilePointer());
seekAndWriteCommitLogHeader(header.toByteArray());
}
}
// write mutation, w/ checksum
Checksum checkum = new CRC32();
if (serializedRow instanceof DataOutputBuffer)
{
DataOutputBuffer buffer = (DataOutputBuffer) serializedRow;
logWriter.writeLong(buffer.getLength());
logWriter.write(buffer.getData(), 0, buffer.getLength());
checkum.update(buffer.getData(), 0, buffer.getLength());
}
else
{
assert serializedRow instanceof byte[];
byte[] bytes = (byte[]) serializedRow;
logWriter.writeLong(bytes.length);
logWriter.write(bytes);
checkum.update(bytes, 0, bytes.length);
}
logWriter.writeLong(checkum.getValue());
return cLogCtx;
}
catch (IOException e)
{
if (currentPosition != -1)
logWriter.seek(currentPosition);
throw e;
}
}
public void sync() throws IOException
{
logWriter.sync();
}
public CommitLogContext getContext()
{
return new CommitLogContext(logWriter.getFilePointer());
}
public CommitLogHeader getHeader()
{
return header;
}
public String getPath()
{
return logWriter.getPath();
}
public long length()
{
try
{
return logWriter.length();
}
catch (IOException e)
{
throw new IOError(e);
}
}
public void close()
{
try
{
logWriter.close();
}
catch (IOException e)
{
throw new IOError(e);
}
}
@Override
public String toString()
{
return "CommitLogSegment(" + logWriter.getPath() + ')';
}
public class CommitLogContext
{
public final long position;
public CommitLogContext(long position)
{
assert position >= 0;
this.position = position;
}
public CommitLogSegment getSegment()
{
return CommitLogSegment.this;
}
@Override
public String toString()
{
return "CommitLogContext(" +
"file='" + logWriter.getPath() + '\'' +
", position=" + position +
')';
}
}
}
package org.apache.cassandra.db.commitlog;
/*
*
* 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.
*
*/
import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import org.apache.log4j.Logger;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.ColumnFamily;
import org.apache.cassandra.db.RowMutation;
import org.apache.cassandra.db.Table;
import org.apache.cassandra.io.util.BufferedRandomAccessFile;
import org.apache.cassandra.io.util.DataOutputBuffer;
public class CommitLogSegment
{
private static final Logger logger = Logger.getLogger(CommitLogSegment.class);
private final BufferedRandomAccessFile logWriter;
private final CommitLogHeader header;
public CommitLogSegment(int cfCount)
{
this.header = new CommitLogHeader(cfCount);
String logFile = DatabaseDescriptor.getLogFileLocation() + File.separator + "CommitLog-" + System.currentTimeMillis() + ".log";
logger.info("Creating new commitlog segment " + logFile);
try
{
logWriter = createWriter(logFile);
writeCommitLogHeader(header.toByteArray());
}
catch (IOException e)
{
throw new IOError(e);
}
}
public void writeHeader() throws IOException
{
seekAndWriteCommitLogHeader(header.toByteArray());
}
/** writes header at the beginning of the file, then seeks back to current position */
void seekAndWriteCommitLogHeader(byte[] bytes) throws IOException
{
long currentPos = logWriter.getFilePointer();
logWriter.seek(0);
writeCommitLogHeader(bytes);
logWriter.seek(currentPos);
}
private void writeCommitLogHeader(byte[] bytes) throws IOException
{
logWriter.writeLong(bytes.length);
logWriter.write(bytes);
logWriter.sync();
}
private static BufferedRandomAccessFile createWriter(String file) throws IOException
{
return new BufferedRandomAccessFile(file, "rw", 128 * 1024);
}
public CommitLogSegment.CommitLogContext write(RowMutation rowMutation, Object serializedRow) throws IOException
{
long currentPosition = -1L;
try
{
currentPosition = logWriter.getFilePointer();
CommitLogSegment.CommitLogContext cLogCtx = new CommitLogSegment.CommitLogContext(currentPosition);
Table table = Table.open(rowMutation.getTable());
// update header
for (ColumnFamily columnFamily : rowMutation.getColumnFamilies())
{
int id = table.getColumnFamilyId(columnFamily.name());
if (!header.isDirty(id))
{
header.turnOn(id, logWriter.getFilePointer());
seekAndWriteCommitLogHeader(header.toByteArray());
}
}
// write mutation, w/ checksum
Checksum checkum = new CRC32();
if (serializedRow instanceof DataOutputBuffer)
{
DataOutputBuffer buffer = (DataOutputBuffer) serializedRow;
logWriter.writeLong(buffer.getLength());
logWriter.write(buffer.getData(), 0, buffer.getLength());
checkum.update(buffer.getData(), 0, buffer.getLength());
}
else
{
assert serializedRow instanceof byte[];
byte[] bytes = (byte[]) serializedRow;
logWriter.writeLong(bytes.length);
logWriter.write(bytes);
checkum.update(bytes, 0, bytes.length);
}
logWriter.writeLong(checkum.getValue());
return cLogCtx;
}
catch (IOException e)
{
if (currentPosition != -1)
logWriter.seek(currentPosition);
throw e;
}
}
public void sync() throws IOException
{
logWriter.sync();
}
public CommitLogContext getContext()
{
return new CommitLogContext(logWriter.getFilePointer());
}
public CommitLogHeader getHeader()
{
return header;
}
public String getPath()
{
return logWriter.getPath();
}
public long length()
{
try
{
return logWriter.length();
}
catch (IOException e)
{
throw new IOError(e);
}
}
public void close()
{
try
{
logWriter.close();
}
catch (IOException e)
{
throw new IOError(e);
}
}
@Override
public String toString()
{
return "CommitLogSegment(" + logWriter.getPath() + ')';
}
public class CommitLogContext
{
public final long position;
public CommitLogContext(long position)
{
assert position >= 0;
this.position = position;
}
public CommitLogSegment getSegment()
{
return CommitLogSegment.this;
}
@Override
public String toString()
{
return "CommitLogContext(" +
"file='" + logWriter.getPath() + '\'' +
", position=" + position +
')';
}
}
}

View File

@ -1,71 +1,92 @@
package org.apache.cassandra.dht;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import org.apache.cassandra.io.ICompactSerializer2;
public abstract class AbstractBounds implements Serializable
{
private static AbstractBoundsSerializer serializer = new AbstractBoundsSerializer();
public static ICompactSerializer2<AbstractBounds> serializer()
{
return serializer;
}
private enum Type
{
RANGE,
BOUNDS
}
public final Token left;
public final Token right;
protected transient final IPartitioner partitioner;
public AbstractBounds(Token left, Token right, IPartitioner partitioner)
{
this.left = left;
this.right = right;
this.partitioner = partitioner;
}
@Override
public int hashCode()
{
return toString().hashCode();
}
@Override
public abstract boolean equals(Object obj);
public abstract boolean contains(Token start);
public abstract Set<AbstractBounds> restrictTo(Range range);
public abstract List<AbstractBounds> unwrap();
private static class AbstractBoundsSerializer implements ICompactSerializer2<AbstractBounds>
{
public void serialize(AbstractBounds range, DataOutput out) throws IOException
{
out.writeInt(range instanceof Range ? Type.RANGE.ordinal() : Type.BOUNDS.ordinal());
Token.serializer().serialize(range.left, out);
Token.serializer().serialize(range.right, out);
}
public AbstractBounds deserialize(DataInput in) throws IOException
{
if (in.readInt() == Type.RANGE.ordinal())
return new Range(Token.serializer().deserialize(in), Token.serializer().deserialize(in));
return new Bounds(Token.serializer().deserialize(in), Token.serializer().deserialize(in));
}
}
}
package org.apache.cassandra.dht;
/*
*
* 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.
*
*/
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import org.apache.cassandra.io.ICompactSerializer2;
public abstract class AbstractBounds implements Serializable
{
private static AbstractBoundsSerializer serializer = new AbstractBoundsSerializer();
public static ICompactSerializer2<AbstractBounds> serializer()
{
return serializer;
}
private enum Type
{
RANGE,
BOUNDS
}
public final Token left;
public final Token right;
protected transient final IPartitioner partitioner;
public AbstractBounds(Token left, Token right, IPartitioner partitioner)
{
this.left = left;
this.right = right;
this.partitioner = partitioner;
}
@Override
public int hashCode()
{
return toString().hashCode();
}
@Override
public abstract boolean equals(Object obj);
public abstract boolean contains(Token start);
public abstract Set<AbstractBounds> restrictTo(Range range);
public abstract List<AbstractBounds> unwrap();
private static class AbstractBoundsSerializer implements ICompactSerializer2<AbstractBounds>
{
public void serialize(AbstractBounds range, DataOutput out) throws IOException
{
out.writeInt(range instanceof Range ? Type.RANGE.ordinal() : Type.BOUNDS.ordinal());
Token.serializer().serialize(range.left, out);
Token.serializer().serialize(range.right, out);
}
public AbstractBounds deserialize(DataInput in) throws IOException
{
if (in.readInt() == Type.RANGE.ordinal())
return new Range(Token.serializer().deserialize(in), Token.serializer().deserialize(in));
return new Bounds(Token.serializer().deserialize(in), Token.serializer().deserialize(in));
}
}
}

View File

@ -1,73 +1,94 @@
package org.apache.cassandra.dht;
import java.util.*;
import org.apache.cassandra.service.StorageService;
public class Bounds extends AbstractBounds
{
public Bounds(Token left, Token right)
{
this(left, right, StorageService.getPartitioner());
}
Bounds(Token left, Token right, IPartitioner partitioner)
{
super(left, right, partitioner);
// unlike a Range, a Bounds may not wrap
assert left.compareTo(right) <= 0 || right.equals(partitioner.getMinimumToken()) : "[" + left + "," + right + "]";
}
@Override
public boolean contains(Token token)
{
return Range.contains(left, right, token) || left.equals(token);
}
public Set<AbstractBounds> restrictTo(Range range)
{
Token min = partitioner.getMinimumToken();
// special case Bounds where left=right (single Token)
if (this.left.equals(this.right) && !this.right.equals(min))
return range.contains(this.left)
? Collections.unmodifiableSet(new HashSet<AbstractBounds>(Arrays.asList(this)))
: Collections.<AbstractBounds>emptySet();
// get the intersection of a Range w/ same left & right
Set<Range> ranges = range.intersectionWith(new Range(this.left, this.right));
// if range doesn't contain left token anyway, that's the correct answer
if (!range.contains(this.left))
return (Set) ranges;
// otherwise, add back in the left token
Set<AbstractBounds> S = new HashSet<AbstractBounds>(ranges.size());
for (Range restricted : ranges)
{
if (restricted.left.equals(this.left))
S.add(new Bounds(restricted.left, restricted.right));
else
S.add(restricted);
}
return Collections.unmodifiableSet(S);
}
public List<AbstractBounds> unwrap()
{
// Bounds objects never wrap
return (List)Arrays.asList(this);
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof Bounds))
return false;
Bounds rhs = (Bounds)o;
return left.equals(rhs.left) && right.equals(rhs.right);
}
public String toString()
{
return "[" + left + "," + right + "]";
}
}
package org.apache.cassandra.dht;
/*
*
* 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.
*
*/
import java.util.*;
import org.apache.cassandra.service.StorageService;
public class Bounds extends AbstractBounds
{
public Bounds(Token left, Token right)
{
this(left, right, StorageService.getPartitioner());
}
Bounds(Token left, Token right, IPartitioner partitioner)
{
super(left, right, partitioner);
// unlike a Range, a Bounds may not wrap
assert left.compareTo(right) <= 0 || right.equals(partitioner.getMinimumToken()) : "[" + left + "," + right + "]";
}
@Override
public boolean contains(Token token)
{
return Range.contains(left, right, token) || left.equals(token);
}
public Set<AbstractBounds> restrictTo(Range range)
{
Token min = partitioner.getMinimumToken();
// special case Bounds where left=right (single Token)
if (this.left.equals(this.right) && !this.right.equals(min))
return range.contains(this.left)
? Collections.unmodifiableSet(new HashSet<AbstractBounds>(Arrays.asList(this)))
: Collections.<AbstractBounds>emptySet();
// get the intersection of a Range w/ same left & right
Set<Range> ranges = range.intersectionWith(new Range(this.left, this.right));
// if range doesn't contain left token anyway, that's the correct answer
if (!range.contains(this.left))
return (Set) ranges;
// otherwise, add back in the left token
Set<AbstractBounds> S = new HashSet<AbstractBounds>(ranges.size());
for (Range restricted : ranges)
{
if (restricted.left.equals(this.left))
S.add(new Bounds(restricted.left, restricted.right));
else
S.add(restricted);
}
return Collections.unmodifiableSet(S);
}
public List<AbstractBounds> unwrap()
{
// Bounds objects never wrap
return (List)Arrays.asList(this);
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof Bounds))
return false;
Bounds rhs = (Bounds)o;
return left.equals(rhs.left) && right.equals(rhs.right);
}
public String toString()
{
return "[" + left + "," + right + "]";
}
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.hadoop;
/*
*
* 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.
*
*/
import java.io.IOException;
import java.net.InetAddress;
@ -226,4 +247,4 @@ public class ColumnFamilyInputFormat extends InputFormat<String, SortedMap<byte[
{
return new ColumnFamilyRecordReader();
}
}
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.hadoop;
/*
*
* 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.
*
*/
import java.io.IOException;
import java.net.InetAddress;
@ -188,4 +209,4 @@ public class ColumnFamilyRecordReader extends RecordReader<String, SortedMap<byt
{
return new org.apache.cassandra.db.Column(column.name, column.value, column.timestamp);
}
}
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.hadoop;
/*
*
* 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.
*
*/
import java.io.DataInput;
import java.io.DataOutput;
@ -132,4 +153,4 @@ public class ColumnFamilySplit extends InputSplit implements Writable
w.readFields(in);
return w;
}
}
}

View File

@ -1,67 +1,88 @@
package org.apache.cassandra.io;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutor;
import org.apache.cassandra.concurrent.NamedThreadFactory;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.utils.WrappedRunnable;
public class DeletionService
{
public static final int MAX_RETRIES = 10;
public static final ExecutorService executor = new JMXEnabledThreadPoolExecutor("FILEUTILS-DELETE-POOL");
public static void submitDelete(final String file)
{
Runnable deleter = new WrappedRunnable()
{
@Override
protected void runMayThrow() throws IOException
{
FileUtils.deleteWithConfirm(new File(file));
}
};
executor.submit(deleter);
}
public static void submitDeleteWithRetry(String file)
{
submitDeleteWithRetry(file, 0);
}
private static void submitDeleteWithRetry(final String file, final int retryCount)
{
Runnable deleter = new WrappedRunnable()
{
@Override
protected void runMayThrow() throws IOException
{
if (!new File(file).delete())
{
if (retryCount > MAX_RETRIES)
throw new IOException("Unable to delete " + file + " after " + MAX_RETRIES + " tries");
new Thread(new Runnable()
{
public void run()
{
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
throw new AssertionError(e);
}
submitDeleteWithRetry(file, retryCount + 1);
}
}, "Delete submission: " + file).start();
}
}
};
executor.submit(deleter);
}
}
package org.apache.cassandra.io;
/*
*
* 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.
*
*/
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import org.apache.cassandra.concurrent.JMXEnabledThreadPoolExecutor;
import org.apache.cassandra.concurrent.NamedThreadFactory;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.utils.WrappedRunnable;
public class DeletionService
{
public static final int MAX_RETRIES = 10;
public static final ExecutorService executor = new JMXEnabledThreadPoolExecutor("FILEUTILS-DELETE-POOL");
public static void submitDelete(final String file)
{
Runnable deleter = new WrappedRunnable()
{
@Override
protected void runMayThrow() throws IOException
{
FileUtils.deleteWithConfirm(new File(file));
}
};
executor.submit(deleter);
}
public static void submitDeleteWithRetry(String file)
{
submitDeleteWithRetry(file, 0);
}
private static void submitDeleteWithRetry(final String file, final int retryCount)
{
Runnable deleter = new WrappedRunnable()
{
@Override
protected void runMayThrow() throws IOException
{
if (!new File(file).delete())
{
if (retryCount > MAX_RETRIES)
throw new IOException("Unable to delete " + file + " after " + MAX_RETRIES + " tries");
new Thread(new Runnable()
{
public void run()
{
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
throw new AssertionError(e);
}
submitDeleteWithRetry(file, retryCount + 1);
}
}, "Delete submission: " + file).start();
}
}
};
executor.submit(deleter);
}
}

View File

@ -1,86 +1,107 @@
package org.apache.cassandra.io;
import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.log4j.Logger;
import org.apache.cassandra.io.util.FileUtils;
public class SSTableDeletingReference extends PhantomReference<SSTableReader>
{
private static final Logger logger = Logger.getLogger(SSTableDeletingReference.class);
private static final Timer timer = new Timer("SSTABLE-CLEANUP-TIMER");
public static final int RETRY_DELAY = 10000;
private final SSTableTracker tracker;
public final String path;
private final long size;
private boolean deleteOnCleanup;
SSTableDeletingReference(SSTableTracker tracker, SSTableReader referent, ReferenceQueue<? super SSTableReader> q)
{
super(referent, q);
this.tracker = tracker;
this.path = referent.path;
this.size = referent.bytesOnDisk();
}
public void deleteOnCleanup()
{
deleteOnCleanup = true;
}
public void cleanup() throws IOException
{
if (deleteOnCleanup)
{
// this is tricky because the mmapping might not have been finalized yet,
// and delete will fail until it is. additionally, we need to make sure to
// delete the data file first, so on restart the others will be recognized as GCable
// even if the compaction marker gets deleted next.
timer.schedule(new CleanupTask(), RETRY_DELAY);
}
}
private class CleanupTask extends TimerTask
{
int attempts = 0;
@Override
public void run()
{
File datafile = new File(path);
if (!datafile.delete())
{
if (attempts++ < DeletionService.MAX_RETRIES)
{
timer.schedule(this, RETRY_DELAY);
return;
}
else
{
throw new RuntimeException("Unable to delete " + path);
}
}
try
{
FileUtils.deleteWithConfirm(new File(SSTable.indexFilename(path)));
FileUtils.deleteWithConfirm(new File(SSTable.filterFilename(path)));
FileUtils.deleteWithConfirm(new File(SSTable.compactedFilename(path)));
}
catch (IOException e)
{
throw new IOError(e);
}
tracker.spaceReclaimed(size);
logger.info("Deleted " + path);
}
}
}
package org.apache.cassandra.io;
/*
*
* 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.
*
*/
import java.io.File;
import java.io.IOError;
import java.io.IOException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.log4j.Logger;
import org.apache.cassandra.io.util.FileUtils;
public class SSTableDeletingReference extends PhantomReference<SSTableReader>
{
private static final Logger logger = Logger.getLogger(SSTableDeletingReference.class);
private static final Timer timer = new Timer("SSTABLE-CLEANUP-TIMER");
public static final int RETRY_DELAY = 10000;
private final SSTableTracker tracker;
public final String path;
private final long size;
private boolean deleteOnCleanup;
SSTableDeletingReference(SSTableTracker tracker, SSTableReader referent, ReferenceQueue<? super SSTableReader> q)
{
super(referent, q);
this.tracker = tracker;
this.path = referent.path;
this.size = referent.bytesOnDisk();
}
public void deleteOnCleanup()
{
deleteOnCleanup = true;
}
public void cleanup() throws IOException
{
if (deleteOnCleanup)
{
// this is tricky because the mmapping might not have been finalized yet,
// and delete will fail until it is. additionally, we need to make sure to
// delete the data file first, so on restart the others will be recognized as GCable
// even if the compaction marker gets deleted next.
timer.schedule(new CleanupTask(), RETRY_DELAY);
}
}
private class CleanupTask extends TimerTask
{
int attempts = 0;
@Override
public void run()
{
File datafile = new File(path);
if (!datafile.delete())
{
if (attempts++ < DeletionService.MAX_RETRIES)
{
timer.schedule(this, RETRY_DELAY);
return;
}
else
{
throw new RuntimeException("Unable to delete " + path);
}
}
try
{
FileUtils.deleteWithConfirm(new File(SSTable.indexFilename(path)));
FileUtils.deleteWithConfirm(new File(SSTable.filterFilename(path)));
FileUtils.deleteWithConfirm(new File(SSTable.compactedFilename(path)));
}
catch (IOException e)
{
throw new IOError(e);
}
tracker.spaceReclaimed(size);
logger.info("Deleted " + path);
}
}
}

View File

@ -1,18 +1,39 @@
package org.apache.cassandra.io.util;
import java.io.DataInput;
import java.io.IOException;
import java.io.Closeable;
public interface FileDataInput extends DataInput, Closeable
{
public String getPath();
public boolean isEOF() throws IOException;
public void mark();
public void reset() throws IOException;
public int bytesPastMark();
}
package org.apache.cassandra.io.util;
/*
*
* 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.
*
*/
import java.io.DataInput;
import java.io.IOException;
import java.io.Closeable;
public interface FileDataInput extends DataInput, Closeable
{
public String getPath();
public boolean isEOF() throws IOException;
public void mark();
public void reset() throws IOException;
public int bytesPastMark();
}

View File

@ -1,404 +1,425 @@
package org.apache.cassandra.io.util;
import java.nio.MappedByteBuffer;
import java.io.*;
public class MappedFileDataInput extends InputStream implements FileDataInput
{
private final MappedByteBuffer buffer;
private final String filename;
private int position;
private int markedPosition;
public MappedFileDataInput(MappedByteBuffer buffer, String filename)
{
this(buffer, filename, 0);
}
public MappedFileDataInput(MappedByteBuffer buffer, String filename, int position)
{
assert buffer != null;
this.buffer = buffer;
this.filename = filename;
this.position = position;
}
// don't make this public, this is only for seeking WITHIN the current mapped segment
private void seekInternal(int pos) throws IOException
{
position = pos;
}
@Override
public boolean markSupported()
{
return true;
}
@Override
public void mark(int ignored)
{
markedPosition = position;
}
@Override
public void reset() throws IOException
{
seekInternal(markedPosition);
}
public void mark()
{
mark(-1);
}
public int bytesPastMark()
{
assert position >= markedPosition;
return position - markedPosition;
}
public boolean isEOF() throws IOException
{
return position == buffer.capacity();
}
public String getPath()
{
return filename;
}
public int read() throws IOException
{
if (isEOF())
return -1;
return buffer.get(position++) & 0xFF;
}
public int skipBytes(int n) throws IOException
{
if (n <= 0)
return 0;
int oldPosition = position;
assert ((long)oldPosition) + n <= Integer.MAX_VALUE;
position = Math.min(buffer.capacity(), position + n);
return position - oldPosition;
}
/*
!! DataInput methods below are copied from the implementation in Apache Harmony RandomAccessFile.
*/
/**
* Reads a boolean from the current position in this file. Blocks until one
* byte has been read, the end of the file is reached or an exception is
* thrown.
*
* @return the next boolean value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final boolean readBoolean() throws IOException {
int temp = this.read();
if (temp < 0) {
throw new EOFException();
}
return temp != 0;
}
/**
* Reads an 8-bit byte from the current position in this file. Blocks until
* one byte has been read, the end of the file is reached or an exception is
* thrown.
*
* @return the next signed 8-bit byte value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final byte readByte() throws IOException {
int temp = this.read();
if (temp < 0) {
throw new EOFException();
}
return (byte) temp;
}
/**
* Reads a 16-bit character from the current position in this file. Blocks until
* two bytes have been read, the end of the file is reached or an exception is
* thrown.
*
* @return the next char value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final char readChar() throws IOException {
byte[] buffer = new byte[2];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return (char) (((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff));
}
/**
* Reads a 64-bit double from the current position in this file. Blocks
* until eight bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next double value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
/**
* Reads a 32-bit float from the current position in this file. Blocks
* until four bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next float value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
/**
* Reads bytes from this file into {@code buffer}. Blocks until {@code
* buffer.length} number of bytes have been read, the end of the file is
* reached or an exception is thrown.
*
* @param buffer
* the buffer to read bytes into.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
*/
public final void readFully(byte[] buffer) throws IOException {
readFully(buffer, 0, buffer.length);
}
/**
* Read bytes from this file into {@code buffer} starting at offset {@code
* offset}. This method blocks until {@code count} number of bytes have been
* read.
*
* @param buffer
* the buffer to read bytes into.
* @param offset
* the initial position in {@code buffer} to store the bytes read
* from this file.
* @param count
* the maximum number of bytes to store in {@code buffer}.
* @throws EOFException
* if the end of this file is detected.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is greater than the length of {@code buffer}.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
*/
public final void readFully(byte[] buffer, int offset, int count)
throws IOException {
if (buffer == null) {
throw new NullPointerException();
}
// avoid int overflow
if (offset < 0 || offset > buffer.length || count < 0
|| count > buffer.length - offset) {
throw new IndexOutOfBoundsException();
}
while (count > 0) {
int result = read(buffer, offset, count);
if (result < 0) {
throw new EOFException();
}
offset += result;
count -= result;
}
}
/**
* Reads a 32-bit integer from the current position in this file. Blocks
* until four bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next int value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final int readInt() throws IOException {
byte[] buffer = new byte[4];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return ((buffer[0] & 0xff) << 24) + ((buffer[1] & 0xff) << 16)
+ ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff);
}
/**
* Reads a line of text form the current position in this file. A line is
* represented by zero or more characters followed by {@code '\n'}, {@code
* '\r'}, {@code "\r\n"} or the end of file marker. The string does not
* include the line terminating sequence.
* <p>
* Blocks until a line terminating sequence has been read, the end of the
* file is reached or an exception is thrown.
*
* @return the contents of the line or {@code null} if no characters have
* been read before the end of the file has been reached.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final String readLine() throws IOException {
StringBuilder line = new StringBuilder(80); // Typical line length
boolean foundTerminator = false;
int unreadPosition = 0;
while (true) {
int nextByte = read();
switch (nextByte) {
case -1:
return line.length() != 0 ? line.toString() : null;
case (byte) '\r':
if (foundTerminator) {
seekInternal(unreadPosition);
return line.toString();
}
foundTerminator = true;
/* Have to be able to peek ahead one byte */
unreadPosition = position;
break;
case (byte) '\n':
return line.toString();
default:
if (foundTerminator) {
seekInternal(unreadPosition);
return line.toString();
}
line.append((char) nextByte);
}
}
}
/**
* Reads a 64-bit long from the current position in this file. Blocks until
* eight bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next long value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final long readLong() throws IOException {
byte[] buffer = new byte[8];
int n = read(buffer, 0, buffer.length);
if (n != buffer.length) {
throw new EOFException("expected 8 bytes; read " + n + " at final position " + position);
}
return ((long) (((buffer[0] & 0xff) << 24) + ((buffer[1] & 0xff) << 16)
+ ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff)) << 32)
+ ((long) (buffer[4] & 0xff) << 24)
+ ((buffer[5] & 0xff) << 16)
+ ((buffer[6] & 0xff) << 8)
+ (buffer[7] & 0xff);
}
/**
* Reads a 16-bit short from the current position in this file. Blocks until
* two bytes have been read, the end of the file is reached or an exception
* is thrown.
*
* @return the next short value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final short readShort() throws IOException {
byte[] buffer = new byte[2];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return (short) (((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff));
}
/**
* Reads an unsigned 8-bit byte from the current position in this file and
* returns it as an integer. Blocks until one byte has been read, the end of
* the file is reached or an exception is thrown.
*
* @return the next unsigned byte value from this file as an int.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final int readUnsignedByte() throws IOException {
int temp = this.read();
if (temp < 0) {
throw new EOFException();
}
return temp;
}
/**
* Reads an unsigned 16-bit short from the current position in this file and
* returns it as an integer. Blocks until two bytes have been read, the end of
* the file is reached or an exception is thrown.
*
* @return the next unsigned short value from this file as an int.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final int readUnsignedShort() throws IOException {
byte[] buffer = new byte[2];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return ((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff);
}
/**
* Reads a string that is encoded in {@link DataInput modified UTF-8} from
* this file. The number of bytes that must be read for the complete string
* is determined by the first two bytes read from the file. Blocks until all
* required bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next string encoded in {@link DataInput modified UTF-8} from
* this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @throws UTFDataFormatException
* if the bytes read cannot be decoded into a character string.
*/
public final String readUTF() throws IOException {
return DataInputStream.readUTF(this);
}
}
package org.apache.cassandra.io.util;
/*
*
* 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.
*
*/
import java.nio.MappedByteBuffer;
import java.io.*;
public class MappedFileDataInput extends InputStream implements FileDataInput
{
private final MappedByteBuffer buffer;
private final String filename;
private int position;
private int markedPosition;
public MappedFileDataInput(MappedByteBuffer buffer, String filename)
{
this(buffer, filename, 0);
}
public MappedFileDataInput(MappedByteBuffer buffer, String filename, int position)
{
assert buffer != null;
this.buffer = buffer;
this.filename = filename;
this.position = position;
}
// don't make this public, this is only for seeking WITHIN the current mapped segment
private void seekInternal(int pos) throws IOException
{
position = pos;
}
@Override
public boolean markSupported()
{
return true;
}
@Override
public void mark(int ignored)
{
markedPosition = position;
}
@Override
public void reset() throws IOException
{
seekInternal(markedPosition);
}
public void mark()
{
mark(-1);
}
public int bytesPastMark()
{
assert position >= markedPosition;
return position - markedPosition;
}
public boolean isEOF() throws IOException
{
return position == buffer.capacity();
}
public String getPath()
{
return filename;
}
public int read() throws IOException
{
if (isEOF())
return -1;
return buffer.get(position++) & 0xFF;
}
public int skipBytes(int n) throws IOException
{
if (n <= 0)
return 0;
int oldPosition = position;
assert ((long)oldPosition) + n <= Integer.MAX_VALUE;
position = Math.min(buffer.capacity(), position + n);
return position - oldPosition;
}
/*
!! DataInput methods below are copied from the implementation in Apache Harmony RandomAccessFile.
*/
/**
* Reads a boolean from the current position in this file. Blocks until one
* byte has been read, the end of the file is reached or an exception is
* thrown.
*
* @return the next boolean value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final boolean readBoolean() throws IOException {
int temp = this.read();
if (temp < 0) {
throw new EOFException();
}
return temp != 0;
}
/**
* Reads an 8-bit byte from the current position in this file. Blocks until
* one byte has been read, the end of the file is reached or an exception is
* thrown.
*
* @return the next signed 8-bit byte value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final byte readByte() throws IOException {
int temp = this.read();
if (temp < 0) {
throw new EOFException();
}
return (byte) temp;
}
/**
* Reads a 16-bit character from the current position in this file. Blocks until
* two bytes have been read, the end of the file is reached or an exception is
* thrown.
*
* @return the next char value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final char readChar() throws IOException {
byte[] buffer = new byte[2];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return (char) (((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff));
}
/**
* Reads a 64-bit double from the current position in this file. Blocks
* until eight bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next double value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
/**
* Reads a 32-bit float from the current position in this file. Blocks
* until four bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next float value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
/**
* Reads bytes from this file into {@code buffer}. Blocks until {@code
* buffer.length} number of bytes have been read, the end of the file is
* reached or an exception is thrown.
*
* @param buffer
* the buffer to read bytes into.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
*/
public final void readFully(byte[] buffer) throws IOException {
readFully(buffer, 0, buffer.length);
}
/**
* Read bytes from this file into {@code buffer} starting at offset {@code
* offset}. This method blocks until {@code count} number of bytes have been
* read.
*
* @param buffer
* the buffer to read bytes into.
* @param offset
* the initial position in {@code buffer} to store the bytes read
* from this file.
* @param count
* the maximum number of bytes to store in {@code buffer}.
* @throws EOFException
* if the end of this file is detected.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is greater than the length of {@code buffer}.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
*/
public final void readFully(byte[] buffer, int offset, int count)
throws IOException {
if (buffer == null) {
throw new NullPointerException();
}
// avoid int overflow
if (offset < 0 || offset > buffer.length || count < 0
|| count > buffer.length - offset) {
throw new IndexOutOfBoundsException();
}
while (count > 0) {
int result = read(buffer, offset, count);
if (result < 0) {
throw new EOFException();
}
offset += result;
count -= result;
}
}
/**
* Reads a 32-bit integer from the current position in this file. Blocks
* until four bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next int value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final int readInt() throws IOException {
byte[] buffer = new byte[4];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return ((buffer[0] & 0xff) << 24) + ((buffer[1] & 0xff) << 16)
+ ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff);
}
/**
* Reads a line of text form the current position in this file. A line is
* represented by zero or more characters followed by {@code '\n'}, {@code
* '\r'}, {@code "\r\n"} or the end of file marker. The string does not
* include the line terminating sequence.
* <p>
* Blocks until a line terminating sequence has been read, the end of the
* file is reached or an exception is thrown.
*
* @return the contents of the line or {@code null} if no characters have
* been read before the end of the file has been reached.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final String readLine() throws IOException {
StringBuilder line = new StringBuilder(80); // Typical line length
boolean foundTerminator = false;
int unreadPosition = 0;
while (true) {
int nextByte = read();
switch (nextByte) {
case -1:
return line.length() != 0 ? line.toString() : null;
case (byte) '\r':
if (foundTerminator) {
seekInternal(unreadPosition);
return line.toString();
}
foundTerminator = true;
/* Have to be able to peek ahead one byte */
unreadPosition = position;
break;
case (byte) '\n':
return line.toString();
default:
if (foundTerminator) {
seekInternal(unreadPosition);
return line.toString();
}
line.append((char) nextByte);
}
}
}
/**
* Reads a 64-bit long from the current position in this file. Blocks until
* eight bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next long value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final long readLong() throws IOException {
byte[] buffer = new byte[8];
int n = read(buffer, 0, buffer.length);
if (n != buffer.length) {
throw new EOFException("expected 8 bytes; read " + n + " at final position " + position);
}
return ((long) (((buffer[0] & 0xff) << 24) + ((buffer[1] & 0xff) << 16)
+ ((buffer[2] & 0xff) << 8) + (buffer[3] & 0xff)) << 32)
+ ((long) (buffer[4] & 0xff) << 24)
+ ((buffer[5] & 0xff) << 16)
+ ((buffer[6] & 0xff) << 8)
+ (buffer[7] & 0xff);
}
/**
* Reads a 16-bit short from the current position in this file. Blocks until
* two bytes have been read, the end of the file is reached or an exception
* is thrown.
*
* @return the next short value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final short readShort() throws IOException {
byte[] buffer = new byte[2];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return (short) (((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff));
}
/**
* Reads an unsigned 8-bit byte from the current position in this file and
* returns it as an integer. Blocks until one byte has been read, the end of
* the file is reached or an exception is thrown.
*
* @return the next unsigned byte value from this file as an int.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final int readUnsignedByte() throws IOException {
int temp = this.read();
if (temp < 0) {
throw new EOFException();
}
return temp;
}
/**
* Reads an unsigned 16-bit short from the current position in this file and
* returns it as an integer. Blocks until two bytes have been read, the end of
* the file is reached or an exception is thrown.
*
* @return the next unsigned short value from this file as an int.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
*/
public final int readUnsignedShort() throws IOException {
byte[] buffer = new byte[2];
if (read(buffer, 0, buffer.length) != buffer.length) {
throw new EOFException();
}
return ((buffer[0] & 0xff) << 8) + (buffer[1] & 0xff);
}
/**
* Reads a string that is encoded in {@link DataInput modified UTF-8} from
* this file. The number of bytes that must be read for the complete string
* is determined by the first two bytes read from the file. Blocks until all
* required bytes have been read, the end of the file is reached or an
* exception is thrown.
*
* @return the next string encoded in {@link DataInput modified UTF-8} from
* this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @throws UTFDataFormatException
* if the bytes read cannot be decoded into a character string.
*/
public final String readUTF() throws IOException {
return DataInputStream.readUTF(this);
}
}

View File

@ -1,69 +1,90 @@
package org.apache.cassandra.net;
import java.io.*;
import java.net.Socket;
import org.apache.log4j.Logger;
import org.apache.cassandra.streaming.IncomingStreamReader;
public class IncomingTcpConnection extends Thread
{
private static Logger logger = Logger.getLogger(IncomingTcpConnection.class);
private final DataInputStream input;
private Socket socket;
public IncomingTcpConnection(Socket socket)
{
this.socket = socket;
try
{
input = new DataInputStream(socket.getInputStream());
}
catch (IOException e)
{
throw new IOError(e);
}
}
@Override
public void run()
{
while (true)
{
try
{
MessagingService.validateMagic(input.readInt());
int header = input.readInt();
int type = MessagingService.getBits(header, 1, 2);
boolean isStream = MessagingService.getBits(header, 3, 1) == 1;
int version = MessagingService.getBits(header, 15, 8);
if (isStream)
{
new IncomingStreamReader(socket.getChannel()).read();
}
else
{
int size = input.readInt();
byte[] contentBytes = new byte[size];
input.readFully(contentBytes);
MessagingService.getDeserializationExecutor().submit(new MessageDeserializationTask(new ByteArrayInputStream(contentBytes)));
}
}
catch (EOFException e)
{
if (logger.isTraceEnabled())
logger.trace("eof reading from socket; closing", e);
break;
}
catch (IOException e)
{
if (logger.isDebugEnabled())
logger.debug("error reading from socket; closing", e);
break;
}
}
}
}
package org.apache.cassandra.net;
/*
*
* 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.
*
*/
import java.io.*;
import java.net.Socket;
import org.apache.log4j.Logger;
import org.apache.cassandra.streaming.IncomingStreamReader;
public class IncomingTcpConnection extends Thread
{
private static Logger logger = Logger.getLogger(IncomingTcpConnection.class);
private final DataInputStream input;
private Socket socket;
public IncomingTcpConnection(Socket socket)
{
this.socket = socket;
try
{
input = new DataInputStream(socket.getInputStream());
}
catch (IOException e)
{
throw new IOError(e);
}
}
@Override
public void run()
{
while (true)
{
try
{
MessagingService.validateMagic(input.readInt());
int header = input.readInt();
int type = MessagingService.getBits(header, 1, 2);
boolean isStream = MessagingService.getBits(header, 3, 1) == 1;
int version = MessagingService.getBits(header, 15, 8);
if (isStream)
{
new IncomingStreamReader(socket.getChannel()).read();
}
else
{
int size = input.readInt();
byte[] contentBytes = new byte[size];
input.readFully(contentBytes);
MessagingService.getDeserializationExecutor().submit(new MessageDeserializationTask(new ByteArrayInputStream(contentBytes)));
}
}
catch (EOFException e)
{
if (logger.isTraceEnabled())
logger.trace("eof reading from socket; closing", e);
break;
}
catch (IOException e)
{
if (logger.isDebugEnabled())
logger.debug("error reading from socket; closing", e);
break;
}
}
}
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.net;
/*
*
* 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.
*
*/
import java.io.DataOutputStream;
import java.io.IOException;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.service;
/*
*
* 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.
*
*/
import java.io.File;
import java.io.FileOutputStream;

View File

@ -1,100 +1,121 @@
package org.apache.cassandra.streaming;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.cassandra.io.ICompactSerializer;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
class CompletedFileStatus
{
private static ICompactSerializer<CompletedFileStatus> serializer_;
public static enum StreamCompletionAction
{
DELETE,
STREAM
}
static
{
serializer_ = new CompletedFileStatusSerializer();
}
public static ICompactSerializer<CompletedFileStatus> serializer()
{
return serializer_;
}
private String file_;
private long expectedBytes_;
private StreamCompletionAction action_;
public CompletedFileStatus(String file, long expectedBytes)
{
file_ = file;
expectedBytes_ = expectedBytes;
action_ = StreamCompletionAction.DELETE;
}
public String getFile()
{
return file_;
}
public long getExpectedBytes()
{
return expectedBytes_;
}
public void setAction(StreamCompletionAction action)
{
action_ = action;
}
public StreamCompletionAction getAction()
{
return action_;
}
public Message makeStreamStatusMessage() throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream( bos );
CompletedFileStatus.serializer().serialize(this, dos);
return new Message(FBUtilities.getLocalAddress(), "", StorageService.Verb.STREAM_FINISHED, bos.toByteArray());
}
private static class CompletedFileStatusSerializer implements ICompactSerializer<CompletedFileStatus>
{
public void serialize(CompletedFileStatus streamStatus, DataOutputStream dos) throws IOException
{
dos.writeUTF(streamStatus.getFile());
dos.writeLong(streamStatus.getExpectedBytes());
dos.writeInt(streamStatus.getAction().ordinal());
}
public CompletedFileStatus deserialize(DataInputStream dis) throws IOException
{
String targetFile = dis.readUTF();
long expectedBytes = dis.readLong();
CompletedFileStatus streamStatus = new CompletedFileStatus(targetFile, expectedBytes);
int ordinal = dis.readInt();
if ( ordinal == StreamCompletionAction.DELETE.ordinal() )
{
streamStatus.setAction(StreamCompletionAction.DELETE);
}
else if ( ordinal == StreamCompletionAction.STREAM.ordinal() )
{
streamStatus.setAction(StreamCompletionAction.STREAM);
}
return streamStatus;
}
}
}
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.cassandra.io.ICompactSerializer;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
class CompletedFileStatus
{
private static ICompactSerializer<CompletedFileStatus> serializer_;
public static enum StreamCompletionAction
{
DELETE,
STREAM
}
static
{
serializer_ = new CompletedFileStatusSerializer();
}
public static ICompactSerializer<CompletedFileStatus> serializer()
{
return serializer_;
}
private String file_;
private long expectedBytes_;
private StreamCompletionAction action_;
public CompletedFileStatus(String file, long expectedBytes)
{
file_ = file;
expectedBytes_ = expectedBytes;
action_ = StreamCompletionAction.DELETE;
}
public String getFile()
{
return file_;
}
public long getExpectedBytes()
{
return expectedBytes_;
}
public void setAction(StreamCompletionAction action)
{
action_ = action;
}
public StreamCompletionAction getAction()
{
return action_;
}
public Message makeStreamStatusMessage() throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream( bos );
CompletedFileStatus.serializer().serialize(this, dos);
return new Message(FBUtilities.getLocalAddress(), "", StorageService.Verb.STREAM_FINISHED, bos.toByteArray());
}
private static class CompletedFileStatusSerializer implements ICompactSerializer<CompletedFileStatus>
{
public void serialize(CompletedFileStatus streamStatus, DataOutputStream dos) throws IOException
{
dos.writeUTF(streamStatus.getFile());
dos.writeLong(streamStatus.getExpectedBytes());
dos.writeInt(streamStatus.getAction().ordinal());
}
public CompletedFileStatus deserialize(DataInputStream dis) throws IOException
{
String targetFile = dis.readUTF();
long expectedBytes = dis.readLong();
CompletedFileStatus streamStatus = new CompletedFileStatus(targetFile, expectedBytes);
int ordinal = dis.readInt();
if ( ordinal == StreamCompletionAction.DELETE.ordinal() )
{
streamStatus.setAction(StreamCompletionAction.DELETE);
}
else if ( ordinal == StreamCompletionAction.STREAM.ordinal() )
{
streamStatus.setAction(StreamCompletionAction.STREAM);
}
return streamStatus;
}
}
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;

View File

@ -1,62 +1,83 @@
package org.apache.cassandra.streaming;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import org.apache.log4j.Logger;
import org.apache.cassandra.db.Table;
import org.apache.cassandra.io.SSTableReader;
import org.apache.cassandra.io.SSTableWriter;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.streaming.IStreamComplete;
import org.apache.cassandra.streaming.StreamInManager;
import org.apache.cassandra.service.StorageService;
/**
* This is the callback handler that is invoked when we have
* completely received a single file from a remote host.
*
* TODO if we move this into CFS we could make addSSTables private, improving encapsulation.
*/
class StreamCompletionHandler implements IStreamComplete
{
private static Logger logger = Logger.getLogger(StreamCompletionHandler.class);
public void onStreamCompletion(InetAddress host, PendingFile pendingFile, CompletedFileStatus streamStatus) throws IOException
{
/* Parse the stream context and the file to the list of SSTables in the associated Column Family Store. */
if (pendingFile.getTargetFile().contains("-Data.db"))
{
String tableName = pendingFile.getTable();
File file = new File( pendingFile.getTargetFile() );
String fileName = file.getName();
String [] temp = fileName.split("-");
//Open the file to see if all parts are now here
try
{
SSTableReader sstable = SSTableWriter.renameAndOpen(pendingFile.getTargetFile());
//TODO add a sanity check that this sstable has all its parts and is ok
Table.open(tableName).getColumnFamilyStore(temp[0]).addSSTable(sstable);
logger.info("Streaming added " + sstable.getFilename());
}
catch (IOException e)
{
throw new RuntimeException("Not able to add streamed file " + pendingFile.getTargetFile(), e);
}
}
if (logger.isDebugEnabled())
logger.debug("Sending a streaming finished message with " + streamStatus + " to " + host);
/* Send a StreamStatus message which may require the source node to re-stream certain files. */
MessagingService.instance.sendOneWay(streamStatus.makeStreamStatusMessage(), host);
/* If we're done with everything for this host, remove from bootstrap sources */
if (StreamInManager.isDone(host) && StorageService.instance.isBootstrapMode())
{
StorageService.instance.removeBootstrapSource(host, pendingFile.getTable());
}
}
}
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import org.apache.log4j.Logger;
import org.apache.cassandra.db.Table;
import org.apache.cassandra.io.SSTableReader;
import org.apache.cassandra.io.SSTableWriter;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.streaming.IStreamComplete;
import org.apache.cassandra.streaming.StreamInManager;
import org.apache.cassandra.service.StorageService;
/**
* This is the callback handler that is invoked when we have
* completely received a single file from a remote host.
*
* TODO if we move this into CFS we could make addSSTables private, improving encapsulation.
*/
class StreamCompletionHandler implements IStreamComplete
{
private static Logger logger = Logger.getLogger(StreamCompletionHandler.class);
public void onStreamCompletion(InetAddress host, PendingFile pendingFile, CompletedFileStatus streamStatus) throws IOException
{
/* Parse the stream context and the file to the list of SSTables in the associated Column Family Store. */
if (pendingFile.getTargetFile().contains("-Data.db"))
{
String tableName = pendingFile.getTable();
File file = new File( pendingFile.getTargetFile() );
String fileName = file.getName();
String [] temp = fileName.split("-");
//Open the file to see if all parts are now here
try
{
SSTableReader sstable = SSTableWriter.renameAndOpen(pendingFile.getTargetFile());
//TODO add a sanity check that this sstable has all its parts and is ok
Table.open(tableName).getColumnFamilyStore(temp[0]).addSSTable(sstable);
logger.info("Streaming added " + sstable.getFilename());
}
catch (IOException e)
{
throw new RuntimeException("Not able to add streamed file " + pendingFile.getTargetFile(), e);
}
}
if (logger.isDebugEnabled())
logger.debug("Sending a streaming finished message with " + streamStatus + " to " + host);
/* Send a StreamStatus message which may require the source node to re-stream certain files. */
MessagingService.instance.sendOneWay(streamStatus.makeStreamStatusMessage(), host);
/* If we're done with everything for this host, remove from bootstrap sources */
if (StreamInManager.isDone(host) && StorageService.instance.isBootstrapMode())
{
StorageService.instance.removeBootstrapSource(host, pendingFile.getTable());
}
}
}

View File

@ -1,48 +1,69 @@
package org.apache.cassandra.streaming;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOError;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.apache.cassandra.net.IVerbHandler;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.streaming.StreamOutManager;
public class StreamFinishedVerbHandler implements IVerbHandler
{
private static Logger logger = Logger.getLogger(StreamFinishedVerbHandler.class);
public void doVerb(Message message)
{
byte[] body = message.getMessageBody();
ByteArrayInputStream bufIn = new ByteArrayInputStream(body);
try
{
CompletedFileStatus streamStatus = CompletedFileStatus.serializer().deserialize(new DataInputStream(bufIn));
switch (streamStatus.getAction())
{
case DELETE:
StreamOutManager.get(message.getFrom()).finishAndStartNext(streamStatus.getFile());
break;
case STREAM:
if (logger.isDebugEnabled())
logger.debug("Need to re-stream file " + streamStatus.getFile());
StreamOutManager.get(message.getFrom()).startNext();
break;
default:
break;
}
}
catch (IOException ex)
{
throw new IOError(ex);
}
}
}
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOError;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.apache.cassandra.net.IVerbHandler;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.streaming.StreamOutManager;
public class StreamFinishedVerbHandler implements IVerbHandler
{
private static Logger logger = Logger.getLogger(StreamFinishedVerbHandler.class);
public void doVerb(Message message)
{
byte[] body = message.getMessageBody();
ByteArrayInputStream bufIn = new ByteArrayInputStream(body);
try
{
CompletedFileStatus streamStatus = CompletedFileStatus.serializer().deserialize(new DataInputStream(bufIn));
switch (streamStatus.getAction())
{
case DELETE:
StreamOutManager.get(message.getFrom()).finishAndStartNext(streamStatus.getFile());
break;
case STREAM:
if (logger.isDebugEnabled())
logger.debug("Need to re-stream file " + streamStatus.getFile());
StreamOutManager.get(message.getFrom()).startNext();
break;
default:
break;
}
}
catch (IOException ex)
{
throw new IOError(ex);
}
}
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.net.InetAddress;
import java.util.Collection;

View File

@ -1,19 +1,40 @@
package org.apache.cassandra.streaming;
import org.apache.log4j.Logger;
import org.apache.cassandra.net.IVerbHandler;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.streaming.StreamOutManager;
public class StreamInitiateDoneVerbHandler implements IVerbHandler
{
private static Logger logger = Logger.getLogger(StreamInitiateDoneVerbHandler.class);
public void doVerb(Message message)
{
if (logger.isDebugEnabled())
logger.debug("Received a stream initiate done message ...");
StreamOutManager.get(message.getFrom()).startNext();
}
}
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import org.apache.log4j.Logger;
import org.apache.cassandra.net.IVerbHandler;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.streaming.StreamOutManager;
public class StreamInitiateDoneVerbHandler implements IVerbHandler
{
private static Logger logger = Logger.getLogger(StreamInitiateDoneVerbHandler.class);
public void doVerb(Message message)
{
if (logger.isDebugEnabled())
logger.debug("Received a stream initiate done message ...");
StreamOutManager.get(message.getFrom()).startNext();
}
}

View File

@ -1,145 +1,166 @@
package org.apache.cassandra.streaming;
import java.io.*;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Table;
import org.apache.cassandra.streaming.StreamInitiateMessage;
import org.apache.cassandra.net.IVerbHandler;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.streaming.StreamInManager;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
public class StreamInitiateVerbHandler implements IVerbHandler
{
private static Logger logger = Logger.getLogger(StreamInitiateVerbHandler.class);
/*
* Here we handle the StreamInitiateMessage. Here we get the
* array of StreamContexts. We get file names for the column
* families associated with the files and replace them with the
* file names as obtained from the column family store on the
* receiving end.
*/
public void doVerb(Message message)
{
byte[] body = message.getMessageBody();
ByteArrayInputStream bufIn = new ByteArrayInputStream(body);
if (logger.isDebugEnabled())
logger.debug(String.format("StreamInitiateVerbeHandler.doVerb %s %s %s", message.getVerb(), message.getMessageId(), message.getMessageType()));
try
{
StreamInitiateMessage biMsg = StreamInitiateMessage.serializer().deserialize(new DataInputStream(bufIn));
PendingFile[] pendingFiles = biMsg.getStreamContext();
if (pendingFiles.length == 0)
{
if (logger.isDebugEnabled())
logger.debug("no data needed from " + message.getFrom());
if (StorageService.instance.isBootstrapMode())
StorageService.instance.removeBootstrapSource(message.getFrom(), new String(message.getHeader(StreamOut.TABLE_NAME)));
return;
}
Map<String, String> fileNames = getNewNames(pendingFiles);
Map<String, String> pathNames = new HashMap<String, String>();
for (String ssName : fileNames.keySet())
pathNames.put(ssName, DatabaseDescriptor.getNextAvailableDataLocation());
/*
* For each of stream context's in the incoming message
* generate the new file names and store the new file names
* in the StreamContextManager.
*/
for (PendingFile pendingFile : pendingFiles)
{
CompletedFileStatus streamStatus = new CompletedFileStatus(pendingFile.getTargetFile(), pendingFile.getExpectedBytes() );
String file = getNewFileNameFromOldContextAndNames(fileNames, pathNames, pendingFile);
if (logger.isDebugEnabled())
logger.debug("Received Data from : " + message.getFrom() + " " + pendingFile.getTargetFile() + " " + file);
pendingFile.setTargetFile(file);
addStreamContext(message.getFrom(), pendingFile, streamStatus);
}
StreamInManager.registerStreamCompletionHandler(message.getFrom(), new StreamCompletionHandler());
if (logger.isDebugEnabled())
logger.debug("Sending a stream initiate done message ...");
Message doneMessage = new Message(FBUtilities.getLocalAddress(), "", StorageService.Verb.STREAM_INITIATE_DONE, new byte[0] );
MessagingService.instance.sendOneWay(doneMessage, message.getFrom());
}
catch (IOException ex)
{
throw new IOError(ex);
}
}
public String getNewFileNameFromOldContextAndNames(Map<String, String> fileNames,
Map<String, String> pathNames,
PendingFile pendingFile)
{
File sourceFile = new File( pendingFile.getTargetFile() );
String[] piece = FBUtilities.strip(sourceFile.getName(), "-");
String cfName = piece[0];
String ssTableNum = piece[1];
String typeOfFile = piece[2];
String newFileNameExpanded = fileNames.get(pendingFile.getTable() + "-" + cfName + "-" + ssTableNum);
String path = pathNames.get(pendingFile.getTable() + "-" + cfName + "-" + ssTableNum);
//Drop type (Data.db) from new FileName
String newFileName = newFileNameExpanded.replace("Data.db", typeOfFile);
return path + File.separator + pendingFile.getTable() + File.separator + newFileName;
}
// todo: this method needs to be private, or package at the very least for easy unit testing.
public Map<String, String> getNewNames(PendingFile[] pendingFiles) throws IOException
{
/*
* Mapping for each file with unique CF-i ---> new file name. For eg.
* for a file with name <CF>-<i>-Data.db there is a corresponding
* <CF>-<i>-Index.db. We maintain a mapping from <CF>-<i> to a newly
* generated file name.
*/
Map<String, String> fileNames = new HashMap<String, String>();
/* Get the distinct entries from StreamContexts i.e have one entry per Data/Index/Filter file set */
Set<String> distinctEntries = new HashSet<String>();
for ( PendingFile pendingFile : pendingFiles)
{
String[] pieces = FBUtilities.strip(new File(pendingFile.getTargetFile()).getName(), "-");
distinctEntries.add(pendingFile.getTable() + "-" + pieces[0] + "-" + pieces[1] );
}
/* Generate unique file names per entry */
for ( String distinctEntry : distinctEntries )
{
String tableName;
String[] pieces = FBUtilities.strip(distinctEntry, "-");
tableName = pieces[0];
Table table = Table.open( tableName );
ColumnFamilyStore cfStore = table.getColumnFamilyStore(pieces[1]);
if (logger.isDebugEnabled())
logger.debug("Generating file name for " + distinctEntry + " ...");
fileNames.put(distinctEntry, cfStore.getTempSSTableFileName());
}
return fileNames;
}
private void addStreamContext(InetAddress host, PendingFile pendingFile, CompletedFileStatus streamStatus)
{
if (logger.isDebugEnabled())
logger.debug("Adding stream context " + pendingFile + " for " + host + " ...");
StreamInManager.addStreamContext(host, pendingFile, streamStatus);
}
}
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.io.*;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Table;
import org.apache.cassandra.streaming.StreamInitiateMessage;
import org.apache.cassandra.net.IVerbHandler;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.streaming.StreamInManager;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
public class StreamInitiateVerbHandler implements IVerbHandler
{
private static Logger logger = Logger.getLogger(StreamInitiateVerbHandler.class);
/*
* Here we handle the StreamInitiateMessage. Here we get the
* array of StreamContexts. We get file names for the column
* families associated with the files and replace them with the
* file names as obtained from the column family store on the
* receiving end.
*/
public void doVerb(Message message)
{
byte[] body = message.getMessageBody();
ByteArrayInputStream bufIn = new ByteArrayInputStream(body);
if (logger.isDebugEnabled())
logger.debug(String.format("StreamInitiateVerbeHandler.doVerb %s %s %s", message.getVerb(), message.getMessageId(), message.getMessageType()));
try
{
StreamInitiateMessage biMsg = StreamInitiateMessage.serializer().deserialize(new DataInputStream(bufIn));
PendingFile[] pendingFiles = biMsg.getStreamContext();
if (pendingFiles.length == 0)
{
if (logger.isDebugEnabled())
logger.debug("no data needed from " + message.getFrom());
if (StorageService.instance.isBootstrapMode())
StorageService.instance.removeBootstrapSource(message.getFrom(), new String(message.getHeader(StreamOut.TABLE_NAME)));
return;
}
Map<String, String> fileNames = getNewNames(pendingFiles);
Map<String, String> pathNames = new HashMap<String, String>();
for (String ssName : fileNames.keySet())
pathNames.put(ssName, DatabaseDescriptor.getNextAvailableDataLocation());
/*
* For each of stream context's in the incoming message
* generate the new file names and store the new file names
* in the StreamContextManager.
*/
for (PendingFile pendingFile : pendingFiles)
{
CompletedFileStatus streamStatus = new CompletedFileStatus(pendingFile.getTargetFile(), pendingFile.getExpectedBytes() );
String file = getNewFileNameFromOldContextAndNames(fileNames, pathNames, pendingFile);
if (logger.isDebugEnabled())
logger.debug("Received Data from : " + message.getFrom() + " " + pendingFile.getTargetFile() + " " + file);
pendingFile.setTargetFile(file);
addStreamContext(message.getFrom(), pendingFile, streamStatus);
}
StreamInManager.registerStreamCompletionHandler(message.getFrom(), new StreamCompletionHandler());
if (logger.isDebugEnabled())
logger.debug("Sending a stream initiate done message ...");
Message doneMessage = new Message(FBUtilities.getLocalAddress(), "", StorageService.Verb.STREAM_INITIATE_DONE, new byte[0] );
MessagingService.instance.sendOneWay(doneMessage, message.getFrom());
}
catch (IOException ex)
{
throw new IOError(ex);
}
}
public String getNewFileNameFromOldContextAndNames(Map<String, String> fileNames,
Map<String, String> pathNames,
PendingFile pendingFile)
{
File sourceFile = new File( pendingFile.getTargetFile() );
String[] piece = FBUtilities.strip(sourceFile.getName(), "-");
String cfName = piece[0];
String ssTableNum = piece[1];
String typeOfFile = piece[2];
String newFileNameExpanded = fileNames.get(pendingFile.getTable() + "-" + cfName + "-" + ssTableNum);
String path = pathNames.get(pendingFile.getTable() + "-" + cfName + "-" + ssTableNum);
//Drop type (Data.db) from new FileName
String newFileName = newFileNameExpanded.replace("Data.db", typeOfFile);
return path + File.separator + pendingFile.getTable() + File.separator + newFileName;
}
// todo: this method needs to be private, or package at the very least for easy unit testing.
public Map<String, String> getNewNames(PendingFile[] pendingFiles) throws IOException
{
/*
* Mapping for each file with unique CF-i ---> new file name. For eg.
* for a file with name <CF>-<i>-Data.db there is a corresponding
* <CF>-<i>-Index.db. We maintain a mapping from <CF>-<i> to a newly
* generated file name.
*/
Map<String, String> fileNames = new HashMap<String, String>();
/* Get the distinct entries from StreamContexts i.e have one entry per Data/Index/Filter file set */
Set<String> distinctEntries = new HashSet<String>();
for ( PendingFile pendingFile : pendingFiles)
{
String[] pieces = FBUtilities.strip(new File(pendingFile.getTargetFile()).getName(), "-");
distinctEntries.add(pendingFile.getTable() + "-" + pieces[0] + "-" + pieces[1] );
}
/* Generate unique file names per entry */
for ( String distinctEntry : distinctEntries )
{
String tableName;
String[] pieces = FBUtilities.strip(distinctEntry, "-");
tableName = pieces[0];
Table table = Table.open( tableName );
ColumnFamilyStore cfStore = table.getColumnFamilyStore(pieces[1]);
if (logger.isDebugEnabled())
logger.debug("Generating file name for " + distinctEntry + " ...");
fileNames.put(distinctEntry, cfStore.getTempSSTableFileName());
}
return fileNames;
}
private void addStreamContext(InetAddress host, PendingFile pendingFile, CompletedFileStatus streamStatus)
{
if (logger.isDebugEnabled())
logger.debug("Adding stream context " + pendingFile + " for " + host + " ...");
StreamInManager.addStreamContext(host, pendingFile, streamStatus);
}
}

View File

@ -1,76 +1,97 @@
package org.apache.cassandra.streaming;
import java.io.*;
import org.apache.cassandra.concurrent.StageManager;
import org.apache.cassandra.io.ICompactSerializer;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
/**
* This class encapsulates the message that needs to be sent to nodes
* that handoff data. The message contains information about ranges
* that need to be transferred and the target node.
*/
class StreamRequestMessage
{
private static ICompactSerializer<StreamRequestMessage> serializer_;
static
{
serializer_ = new StreamRequestMessageSerializer();
}
protected static ICompactSerializer<StreamRequestMessage> serializer()
{
return serializer_;
}
protected static Message makeStreamRequestMessage(StreamRequestMessage streamRequestMessage)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
try
{
StreamRequestMessage.serializer().serialize(streamRequestMessage, dos);
}
catch (IOException e)
{
throw new IOError(e);
}
return new Message(FBUtilities.getLocalAddress(), StageManager.STREAM_STAGE, StorageService.Verb.STREAM_REQUEST, bos.toByteArray() );
}
protected StreamRequestMetadata[] streamRequestMetadata_ = new StreamRequestMetadata[0];
// TODO only actually ever need one BM, not an array
StreamRequestMessage(StreamRequestMetadata... streamRequestMetadata)
{
assert streamRequestMetadata != null;
streamRequestMetadata_ = streamRequestMetadata;
}
private static class StreamRequestMessageSerializer implements ICompactSerializer<StreamRequestMessage>
{
public void serialize(StreamRequestMessage streamRequestMessage, DataOutputStream dos) throws IOException
{
StreamRequestMetadata[] streamRequestMetadata = streamRequestMessage.streamRequestMetadata_;
dos.writeInt(streamRequestMetadata.length);
for (StreamRequestMetadata bsmd : streamRequestMetadata)
{
StreamRequestMetadata.serializer().serialize(bsmd, dos);
}
}
public StreamRequestMessage deserialize(DataInputStream dis) throws IOException
{
int size = dis.readInt();
StreamRequestMetadata[] streamRequestMetadata = new StreamRequestMetadata[size];
for (int i = 0; i < size; ++i)
{
streamRequestMetadata[i] = StreamRequestMetadata.serializer().deserialize(dis);
}
return new StreamRequestMessage(streamRequestMetadata);
}
}
}
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.io.*;
import org.apache.cassandra.concurrent.StageManager;
import org.apache.cassandra.io.ICompactSerializer;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.utils.FBUtilities;
/**
* This class encapsulates the message that needs to be sent to nodes
* that handoff data. The message contains information about ranges
* that need to be transferred and the target node.
*/
class StreamRequestMessage
{
private static ICompactSerializer<StreamRequestMessage> serializer_;
static
{
serializer_ = new StreamRequestMessageSerializer();
}
protected static ICompactSerializer<StreamRequestMessage> serializer()
{
return serializer_;
}
protected static Message makeStreamRequestMessage(StreamRequestMessage streamRequestMessage)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
try
{
StreamRequestMessage.serializer().serialize(streamRequestMessage, dos);
}
catch (IOException e)
{
throw new IOError(e);
}
return new Message(FBUtilities.getLocalAddress(), StageManager.STREAM_STAGE, StorageService.Verb.STREAM_REQUEST, bos.toByteArray() );
}
protected StreamRequestMetadata[] streamRequestMetadata_ = new StreamRequestMetadata[0];
// TODO only actually ever need one BM, not an array
StreamRequestMessage(StreamRequestMetadata... streamRequestMetadata)
{
assert streamRequestMetadata != null;
streamRequestMetadata_ = streamRequestMetadata;
}
private static class StreamRequestMessageSerializer implements ICompactSerializer<StreamRequestMessage>
{
public void serialize(StreamRequestMessage streamRequestMessage, DataOutputStream dos) throws IOException
{
StreamRequestMetadata[] streamRequestMetadata = streamRequestMessage.streamRequestMetadata_;
dos.writeInt(streamRequestMetadata.length);
for (StreamRequestMetadata bsmd : streamRequestMetadata)
{
StreamRequestMetadata.serializer().serialize(bsmd, dos);
}
}
public StreamRequestMessage deserialize(DataInputStream dis) throws IOException
{
int size = dis.readInt();
StreamRequestMetadata[] streamRequestMetadata = new StreamRequestMetadata[size];
for (int i = 0; i < size; ++i)
{
streamRequestMetadata[i] = StreamRequestMetadata.serializer().deserialize(dis);
}
return new StreamRequestMessage(streamRequestMetadata);
}
}
}

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.streaming;
/*
*
* 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.
*
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.thrift;
/*
*
* 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.
*
*/
import java.util.List;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.tools;
/*
*
* 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.
*
*/
import java.io.IOException;
import java.io.PrintStream;

View File

@ -1,4 +1,25 @@
package org.apache.cassandra.utils;
/*
*
* 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.
*
*/
import java.util.concurrent.atomic.AtomicLong;

View File

@ -1,73 +1,94 @@
package org.apache.cassandra.dht;
import java.util.*;
import junit.framework.TestCase;
import org.apache.cassandra.utils.FBUtilities;
public class BoundsTest extends TestCase
{
public void testRestrictTo() throws Exception
{
IPartitioner p = new OrderPreservingPartitioner();
Token min = p.getMinimumToken();
Range wraps = new Range(new StringToken("m"), new StringToken("e"));
Range normal = new Range(wraps.right, wraps.left);
Bounds all = new Bounds(min, min, p);
Bounds almostAll = new Bounds(new StringToken("a"), min, p);
Set<AbstractBounds> S;
Set<AbstractBounds> S2;
S = all.restrictTo(wraps);
assert S.equals(new HashSet<AbstractBounds>(Arrays.asList(wraps)));
S = almostAll.restrictTo(wraps);
S2 = new HashSet<AbstractBounds>(Arrays.asList(new Bounds(new StringToken("a"), new StringToken("e"), p),
new Range(new StringToken("m"), min)));
assert S.equals(S2);
S = all.restrictTo(normal);
assert S.equals(new HashSet<AbstractBounds>(Arrays.asList(normal)));
}
public void testNoIntersectionWrapped()
{
IPartitioner p = new OrderPreservingPartitioner();
Range node = new Range(new StringToken("z"), new StringToken("a"));
Bounds bounds;
bounds = new Bounds(new StringToken("m"), new StringToken("n"), p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
bounds = new Bounds(new StringToken("b"), node.left, p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
}
public void testSmallBoundsFullRange()
{
IPartitioner p = new OrderPreservingPartitioner();
Range node;
Bounds bounds = new Bounds(new StringToken("b"), new StringToken("c"), p);
node = new Range(new StringToken("d"), new StringToken("d"));
assert bounds.restrictTo(node).equals(new HashSet(Arrays.asList(bounds)));
}
public void testNoIntersectionUnwrapped()
{
IPartitioner p = new OrderPreservingPartitioner();
Token min = p.getMinimumToken();
Range node = new Range(new StringToken("m"), new StringToken("n"));
Bounds bounds;
bounds = new Bounds(new StringToken("z"), min, p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
bounds = new Bounds(new StringToken("a"), node.left, p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
bounds = new Bounds(min, new StringToken("b"), p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
}
}
package org.apache.cassandra.dht;
/*
*
* 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.
*
*/
import java.util.*;
import junit.framework.TestCase;
import org.apache.cassandra.utils.FBUtilities;
public class BoundsTest extends TestCase
{
public void testRestrictTo() throws Exception
{
IPartitioner p = new OrderPreservingPartitioner();
Token min = p.getMinimumToken();
Range wraps = new Range(new StringToken("m"), new StringToken("e"));
Range normal = new Range(wraps.right, wraps.left);
Bounds all = new Bounds(min, min, p);
Bounds almostAll = new Bounds(new StringToken("a"), min, p);
Set<AbstractBounds> S;
Set<AbstractBounds> S2;
S = all.restrictTo(wraps);
assert S.equals(new HashSet<AbstractBounds>(Arrays.asList(wraps)));
S = almostAll.restrictTo(wraps);
S2 = new HashSet<AbstractBounds>(Arrays.asList(new Bounds(new StringToken("a"), new StringToken("e"), p),
new Range(new StringToken("m"), min)));
assert S.equals(S2);
S = all.restrictTo(normal);
assert S.equals(new HashSet<AbstractBounds>(Arrays.asList(normal)));
}
public void testNoIntersectionWrapped()
{
IPartitioner p = new OrderPreservingPartitioner();
Range node = new Range(new StringToken("z"), new StringToken("a"));
Bounds bounds;
bounds = new Bounds(new StringToken("m"), new StringToken("n"), p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
bounds = new Bounds(new StringToken("b"), node.left, p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
}
public void testSmallBoundsFullRange()
{
IPartitioner p = new OrderPreservingPartitioner();
Range node;
Bounds bounds = new Bounds(new StringToken("b"), new StringToken("c"), p);
node = new Range(new StringToken("d"), new StringToken("d"));
assert bounds.restrictTo(node).equals(new HashSet(Arrays.asList(bounds)));
}
public void testNoIntersectionUnwrapped()
{
IPartitioner p = new OrderPreservingPartitioner();
Token min = p.getMinimumToken();
Range node = new Range(new StringToken("m"), new StringToken("n"));
Bounds bounds;
bounds = new Bounds(new StringToken("z"), min, p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
bounds = new Bounds(new StringToken("a"), node.left, p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
bounds = new Bounds(min, new StringToken("b"), p);
assert bounds.restrictTo(node).equals(Collections.<AbstractBounds>emptySet());
}
}

View File

@ -1,131 +1,152 @@
package org.apache.cassandra.dht;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
public class RangeIntersectionTest
{
static void assertIntersection(Range one, Range two, Range ... ranges)
{
Set<Range> correct = Range.rangeSet(ranges);
Set<Range> result1 = one.intersectionWith(two);
assert result1.equals(correct) : String.format("%s != %s",
StringUtils.join(result1, ","),
StringUtils.join(correct, ","));
Set<Range> result2 = two.intersectionWith(one);
assert result2.equals(correct) : String.format("%s != %s",
StringUtils.join(result2, ","),
StringUtils.join(correct, ","));
}
private void assertNoIntersection(Range wraps1, Range nowrap3)
{
assertIntersection(wraps1, nowrap3);
}
@Test
public void testIntersectionWithAll()
{
Range all0 = new Range(new BigIntegerToken("0"), new BigIntegerToken("0"));
Range all10 = new Range(new BigIntegerToken("10"), new BigIntegerToken("10"));
Range all100 = new Range(new BigIntegerToken("100"), new BigIntegerToken("100"));
Range all1000 = new Range(new BigIntegerToken("1000"), new BigIntegerToken("1000"));
Range wraps = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
assertIntersection(all0, wraps, wraps);
assertIntersection(all10, wraps, wraps);
assertIntersection(all100, wraps, wraps);
assertIntersection(all1000, wraps, wraps);
}
@Test
public void testIntersectionContains()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
Range wraps2 = new Range(new BigIntegerToken("90"), new BigIntegerToken("20"));
Range wraps3 = new Range(new BigIntegerToken("90"), new BigIntegerToken("0"));
Range nowrap1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("110"));
Range nowrap2 = new Range(new BigIntegerToken("0"), new BigIntegerToken("10"));
Range nowrap3 = new Range(new BigIntegerToken("0"), new BigIntegerToken("9"));
assertIntersection(wraps1, wraps2, wraps1);
assertIntersection(wraps3, wraps2, wraps3);
assertIntersection(wraps1, nowrap1, nowrap1);
assertIntersection(wraps1, nowrap2, nowrap2);
assertIntersection(nowrap2, nowrap3, nowrap3);
assertIntersection(wraps1, wraps1, wraps1);
assertIntersection(nowrap1, nowrap1, nowrap1);
assertIntersection(nowrap2, nowrap2, nowrap2);
assertIntersection(wraps3, wraps3, wraps3);
}
@Test
public void testNoIntersection()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
Range wraps2 = new Range(new BigIntegerToken("100"), new BigIntegerToken("0"));
Range nowrap1 = new Range(new BigIntegerToken("0"), new BigIntegerToken("100"));
Range nowrap2 = new Range(new BigIntegerToken("100"), new BigIntegerToken("200"));
Range nowrap3 = new Range(new BigIntegerToken("10"), new BigIntegerToken("100"));
assertNoIntersection(wraps1, nowrap3);
assertNoIntersection(wraps2, nowrap1);
assertNoIntersection(nowrap1, nowrap2);
}
@Test
public void testIntersectionOneWraps()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
Range wraps2 = new Range(new BigIntegerToken("100"), new BigIntegerToken("0"));
Range nowrap1 = new Range(new BigIntegerToken("0"), new BigIntegerToken("200"));
Range nowrap2 = new Range(new BigIntegerToken("0"), new BigIntegerToken("100"));
assertIntersection(wraps1,
nowrap1,
new Range(new BigIntegerToken("0"), new BigIntegerToken("10")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("200")));
assertIntersection(wraps2,
nowrap1,
new Range(new BigIntegerToken("100"), new BigIntegerToken("200")));
assertIntersection(wraps1,
nowrap2,
new Range(new BigIntegerToken("0"), new BigIntegerToken("10")));
}
@Test
public void testIntersectionTwoWraps()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("20"));
Range wraps2 = new Range(new BigIntegerToken("120"), new BigIntegerToken("90"));
Range wraps3 = new Range(new BigIntegerToken("120"), new BigIntegerToken("110"));
Range wraps4 = new Range(new BigIntegerToken("10"), new BigIntegerToken("0"));
Range wraps5 = new Range(new BigIntegerToken("10"), new BigIntegerToken("1"));
Range wraps6 = new Range(new BigIntegerToken("30"), new BigIntegerToken("10"));
assertIntersection(wraps1,
wraps2,
new Range(new BigIntegerToken("120"), new BigIntegerToken("20")));
assertIntersection(wraps1,
wraps3,
new Range(new BigIntegerToken("120"), new BigIntegerToken("20")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("110")));
assertIntersection(wraps1,
wraps4,
new Range(new BigIntegerToken("10"), new BigIntegerToken("20")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("0")));
assertIntersection(wraps1,
wraps5,
new Range(new BigIntegerToken("10"), new BigIntegerToken("20")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("1")));
assertIntersection(wraps1,
wraps6,
new Range(new BigIntegerToken("100"), new BigIntegerToken("10")));
}
}
package org.apache.cassandra.dht;
/*
*
* 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.
*
*/
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
public class RangeIntersectionTest
{
static void assertIntersection(Range one, Range two, Range ... ranges)
{
Set<Range> correct = Range.rangeSet(ranges);
Set<Range> result1 = one.intersectionWith(two);
assert result1.equals(correct) : String.format("%s != %s",
StringUtils.join(result1, ","),
StringUtils.join(correct, ","));
Set<Range> result2 = two.intersectionWith(one);
assert result2.equals(correct) : String.format("%s != %s",
StringUtils.join(result2, ","),
StringUtils.join(correct, ","));
}
private void assertNoIntersection(Range wraps1, Range nowrap3)
{
assertIntersection(wraps1, nowrap3);
}
@Test
public void testIntersectionWithAll()
{
Range all0 = new Range(new BigIntegerToken("0"), new BigIntegerToken("0"));
Range all10 = new Range(new BigIntegerToken("10"), new BigIntegerToken("10"));
Range all100 = new Range(new BigIntegerToken("100"), new BigIntegerToken("100"));
Range all1000 = new Range(new BigIntegerToken("1000"), new BigIntegerToken("1000"));
Range wraps = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
assertIntersection(all0, wraps, wraps);
assertIntersection(all10, wraps, wraps);
assertIntersection(all100, wraps, wraps);
assertIntersection(all1000, wraps, wraps);
}
@Test
public void testIntersectionContains()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
Range wraps2 = new Range(new BigIntegerToken("90"), new BigIntegerToken("20"));
Range wraps3 = new Range(new BigIntegerToken("90"), new BigIntegerToken("0"));
Range nowrap1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("110"));
Range nowrap2 = new Range(new BigIntegerToken("0"), new BigIntegerToken("10"));
Range nowrap3 = new Range(new BigIntegerToken("0"), new BigIntegerToken("9"));
assertIntersection(wraps1, wraps2, wraps1);
assertIntersection(wraps3, wraps2, wraps3);
assertIntersection(wraps1, nowrap1, nowrap1);
assertIntersection(wraps1, nowrap2, nowrap2);
assertIntersection(nowrap2, nowrap3, nowrap3);
assertIntersection(wraps1, wraps1, wraps1);
assertIntersection(nowrap1, nowrap1, nowrap1);
assertIntersection(nowrap2, nowrap2, nowrap2);
assertIntersection(wraps3, wraps3, wraps3);
}
@Test
public void testNoIntersection()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
Range wraps2 = new Range(new BigIntegerToken("100"), new BigIntegerToken("0"));
Range nowrap1 = new Range(new BigIntegerToken("0"), new BigIntegerToken("100"));
Range nowrap2 = new Range(new BigIntegerToken("100"), new BigIntegerToken("200"));
Range nowrap3 = new Range(new BigIntegerToken("10"), new BigIntegerToken("100"));
assertNoIntersection(wraps1, nowrap3);
assertNoIntersection(wraps2, nowrap1);
assertNoIntersection(nowrap1, nowrap2);
}
@Test
public void testIntersectionOneWraps()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("10"));
Range wraps2 = new Range(new BigIntegerToken("100"), new BigIntegerToken("0"));
Range nowrap1 = new Range(new BigIntegerToken("0"), new BigIntegerToken("200"));
Range nowrap2 = new Range(new BigIntegerToken("0"), new BigIntegerToken("100"));
assertIntersection(wraps1,
nowrap1,
new Range(new BigIntegerToken("0"), new BigIntegerToken("10")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("200")));
assertIntersection(wraps2,
nowrap1,
new Range(new BigIntegerToken("100"), new BigIntegerToken("200")));
assertIntersection(wraps1,
nowrap2,
new Range(new BigIntegerToken("0"), new BigIntegerToken("10")));
}
@Test
public void testIntersectionTwoWraps()
{
Range wraps1 = new Range(new BigIntegerToken("100"), new BigIntegerToken("20"));
Range wraps2 = new Range(new BigIntegerToken("120"), new BigIntegerToken("90"));
Range wraps3 = new Range(new BigIntegerToken("120"), new BigIntegerToken("110"));
Range wraps4 = new Range(new BigIntegerToken("10"), new BigIntegerToken("0"));
Range wraps5 = new Range(new BigIntegerToken("10"), new BigIntegerToken("1"));
Range wraps6 = new Range(new BigIntegerToken("30"), new BigIntegerToken("10"));
assertIntersection(wraps1,
wraps2,
new Range(new BigIntegerToken("120"), new BigIntegerToken("20")));
assertIntersection(wraps1,
wraps3,
new Range(new BigIntegerToken("120"), new BigIntegerToken("20")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("110")));
assertIntersection(wraps1,
wraps4,
new Range(new BigIntegerToken("10"), new BigIntegerToken("20")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("0")));
assertIntersection(wraps1,
wraps5,
new Range(new BigIntegerToken("10"), new BigIntegerToken("20")),
new Range(new BigIntegerToken("100"), new BigIntegerToken("1")));
assertIntersection(wraps1,
wraps6,
new Range(new BigIntegerToken("100"), new BigIntegerToken("10")));
}
}