You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(414) |
Apr
(123) |
May
(448) |
Jun
(180) |
Jul
(17) |
Aug
(49) |
Sep
(3) |
Oct
(92) |
Nov
(101) |
Dec
(64) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(132) |
Feb
(230) |
Mar
(146) |
Apr
(146) |
May
|
Jun
|
Jul
(34) |
Aug
(4) |
Sep
(3) |
Oct
(10) |
Nov
(12) |
Dec
(24) |
2008 |
Jan
(6) |
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(11) |
Nov
(4) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
From: Bryan T. <tho...@us...> - 2007-03-20 14:59:38
|
Update of /cvsroot/cweb/junit-ext In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv6043 Modified Files: project.xml Log Message: Updated POM to 1-1.b3. Index: project.xml =================================================================== RCS file: /cvsroot/cweb/junit-ext/project.xml,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** project.xml 28 May 2006 12:56:11 -0000 1.8 --- project.xml 20 Mar 2007 14:12:32 -0000 1.9 *************** *** 6,10 **** <extends>../cweb/project.xml</extends> <groupId>org.CognitiveWeb</groupId> ! <currentVersion>1.1-b2-dev</currentVersion> <organization> --- 6,10 ---- <extends>../cweb/project.xml</extends> <groupId>org.CognitiveWeb</groupId> ! <currentVersion>1.1-b3-dev</currentVersion> <organization> *************** *** 53,56 **** --- 53,61 ---- <version> + <id>1.1-b2-dev</id> + <name>1.1-b2</name> + <tag>JUNIT_EXT_1_1_B2</tag> + </version> + <version> <id>1.1-b1-dev</id> <name>1.1-b1</name> |
From: Bryan T. <tho...@us...> - 2007-03-20 14:59:35
|
Update of /cvsroot/cweb/lgpl-utils In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv16387 Added Files: maven.xml project.xml project.properties Log Message: Added POM and junit JAR to facilitate builds of the JAR artifact. --- NEW FILE: maven.xml --- <project default="build" xmlns:j="jelly:core" xmlns:artifact="artifact" > <!-- --> <!-- Generate FAQ from xdocs/faq.fml. --> <!-- --> <preGoal name="xdoc:jelly-transform"> <attainGoal name="faq"/> </preGoal> <!-- --> <!-- Conditionally disable linkcheck based on a property. --> <!-- --> <postGoal name="xdoc:register-reports"> <j:if test="${maven.linkcheck.disable}"> <attainGoal name="maven-linkcheck-plugin:deregister"/> <echo>linkcheck is disabled.</echo> </j:if> </postGoal> <!-- --> <!-- Conditionally disable checkstyle based on a property. --> <!-- --> <postGoal name="xdoc:register-reports"> <j:if test="${maven.checkstyle.disable}"> <attainGoal name="maven-checkstyle-plugin:deregister"/> <echo>checkstyle is disabled.</echo> </j:if> </postGoal> <!-- --> <!-- Cause JAR to be built for install goal. --> <!-- --> <goal name="install"> <attainGoal name="jar"/> <artifact:install artifact="${maven.build.dir}/${maven.final.name}.jar" type="jar" project="${pom}" /> </goal> </project> --- NEW FILE: project.properties --- # The cweb artifacts and artifacts from a few open source projects # that are not already up on ibiblio may be automatically downloaded # from the cweb maven repository on source forge or on # proto.cognitiveweb.org. If the license does not permit # redistrubution, then you will have to get the artifact from its # authoritative source. maven.repo.remote=http://www.ibiblio.org/maven/,http://proto.cognitiveweb.org/maven-repository # Links to external packages. The package-list javadoc file for # directory referenced by the (relative) URLs MUST exist at the time # that the javadoc for this package is generated. maven.javadoc.links=\ http://java.sun.com/j2se/1.4.2/docs/api \ , http://www.junit.org/junit/javadoc/3.8.1/ maven.javadoc.offlineLinks=\ http://java.sun.com/j2se/1.4.2/docs/api#/j2sdk1.4.1_02/docs/api \ , http://www.junit.org/junit/javadoc/3.8#/usr/local/junit3.8.1/javadoc --- NEW FILE: project.xml --- <?xml version="1.0" encoding="ISO-8859-1"?> <project> <id>lgpl-utils</id> <name>LGPL Utilities</name> <package>lgpl-utils</package> <extends>../cweb/project.xml</extends> <groupId>org.CognitiveWeb</groupId> <currentVersion>1.0-b1-dev</currentVersion> <organization> <name>CognitiveWeb</name> <url>http://www.cognitiveweb.org/</url> <logo>http://www.cognitiveweb.org/Images/cogweb-logo.jpg</logo> </organization> <!-- required per-POM metadata. --> <inceptionYear>2002</inceptionYear> <url>http://www.cognitiveweb.org/</url> <logo>http://www.cognitiveweb.org/Images/tagline.gif</logo> <!-- The short description is used in the JAR manifest. For --> <!-- compatibility reasons, no leading/trailing newlines and --> <!-- 72 character length limit. --> <shortDescription>LGPL Utilities</shortDescription> <description> <![CDATA[ <p>This module is a collection of interesting LGPL utilities that have been extracted from larger LGPL projects and repackaged for light weight deployment. </p> ]]> </description> <versions> <!-- <version> <id>1.1-b2-dev</id> <name>1.1-b2</name> <tag>JUNIT_EXT_1_1_B2</tag> </version> --> </versions> <!-- copy down inheritance applies. --> <siteAddress>www.cognitiveweb.org</siteAddress> <siteDirectory> /home/groups/c/cw/cweb/htdocs/technology/projects/${pom.artifactId} </siteDirectory> <!-- copy down inheritance applies. --> <distributionSite>www.sourceforge.net</distributionSite> <distributionDirectory>/projects/cweb</distributionDirectory> <!-- copy down inheritance applies. --> <issueTrackingUrl> http://jira.cognitiveweb.org/browse/JUNITEXT </issueTrackingUrl> <!-- copy down inheritance applies. --> <repository> <connection> scm:cvs:pserver:anonymous@${maven.scm.cvs.host}:/cvsroot/cweb:lgpl-utils </connection> <developerConnection> scm:cvs:ext:user@${maven.scm.cvs.host}:/cvsroot/cweb:lgpl-utils </developerConnection> <url>http://cweb.cvs.sourceforge.net/cweb/lgpl-utils</url> </repository> <!-- Note: This module is under the LGPL license. --> <licenses> <license> <name>LGPL</name> <url>http://www.gnu.org/licenses/lgpl.html</url> <distribution>manual</distribution> </license> </licenses> <!-- copy down inheritance applies. --> <mailingLists> <mailingList> <name>Announce List</name> <subscribe> http://lists.sourceforge.net/lists/listinfo/cweb-announce </subscribe> <unsubscribe> http://lists.sourceforge.net/lists/listinfo/cweb-announce </unsubscribe> <archive> http://sourceforge.net/mailarchive/forum.php?forum=cweb-announce </archive> </mailingList> <mailingList> <name>Developer List</name> <subscribe> http://lists.sourceforge.net/lists/listinfo/cweb-developer </subscribe> <unsubscribe> http://lists.sourceforge.net/lists/listinfo/cweb-developer </unsubscribe> <archive> http://sourceforge.net/mailarchive/forum.php?forum=cweb-developer </archive> </mailingList> </mailingLists> <!-- copy down inheritance applies. --> <developers> <developer> <name>Bryan Thompson</name> <id>bryan</id> <email>tho...@us...</email> <organization>SYSTAP, LLC</organization> <!-- East coast. --> <timezone>-5</timezone> </developer> </developers> <contributors> <!-- <contributor> <name>...</name> <id>...</id> <email>...</email> <organization>...</organization> </contributor> --> </contributors> <!-- project-specific data. --> <dependencies> <!-- junit (tests only) --> <dependency> <id>junit</id> <version>3.8.1</version> <url>http://www.junit.org/</url> </dependency> </dependencies> <build> <nagEmailAddress> tho...@us... </nagEmailAddress> <sourceDirectory>${basedir}/src/java</sourceDirectory> <unitTestSourceDirectory>${basedir}/src/test</unitTestSourceDirectory> <aspectSourceDirectory/> <!-- Unit test cases --> <unitTest> <includes> <include>**/src/test/it/unimi/dsi/mg4j/util/BloomFilterTest.java</include> </includes> <!-- <excludes> <exclude>**/ProxyTestCase.java</exclude> </excludes> --> <!-- Resources for test cases are declared here. --> <resources> </resources> </unitTest> <!-- J A R R E S O U R C E S --> <resources> <!-- <resource> <directory>${basedir}/src/resources/logging</directory> <includes> <include>log4j.properties</include> </includes> </resource> --> </resources> <jars> </jars> </build> </project> |
From: Bryan T. <tho...@us...> - 2007-03-20 13:56:46
|
Update of /cvsroot/cweb/junit-ext/src/announcements In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv32341/src/announcements Added Files: README-1.1-b2.txt Log Message: Added announcement for 1-1.b2 release. --- NEW FILE: README-1.1-b2.txt --- Minor release includes some new test helpers, some more documentation, and some more support for running proxy test suites on an individual basis. |
From: Bryan T. <tho...@us...> - 2007-03-20 13:52:58
|
Update of /cvsroot/cweb/junit-ext/src/java/junit/framework In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv30815/src/java/junit/framework Modified Files: TestCase2.java Log Message: javadoc corrections. Index: TestCase2.java =================================================================== RCS file: /cvsroot/cweb/junit-ext/src/java/junit/framework/TestCase2.java,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** TestCase2.java 20 Mar 2007 13:40:33 -0000 1.21 --- TestCase2.java 20 Mar 2007 13:52:31 -0000 1.22 *************** *** 46,53 **** --- 46,55 ---- // Test resource loader. + import java.io.Externalizable; import java.io.Reader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; + import java.io.Serializable; // Properties hierarchy loader. *************** *** 2017,2021 **** * property.<p> * ! * @param UnsupportedOperationException if the project build * directory could NOT be determined since the * <i>maven.junit.sysproperties</i> property was NOT defined. --- 2019,2023 ---- * property.<p> * ! * @throws UnsupportedOperationException if the project build * directory could NOT be determined since the * <i>maven.junit.sysproperties</i> property was NOT defined. |
From: Bryan T. <tho...@us...> - 2007-03-20 13:52:39
|
Update of /cvsroot/cweb/junit-ext/src/java/junit/extensions/proxy In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv30815/src/java/junit/extensions/proxy Modified Files: ProxyTestSuite.java Log Message: javadoc corrections. Index: ProxyTestSuite.java =================================================================== RCS file: /cvsroot/cweb/junit-ext/src/java/junit/extensions/proxy/ProxyTestSuite.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ProxyTestSuite.java 23 May 2006 16:06:05 -0000 1.5 --- ProxyTestSuite.java 20 Mar 2007 13:52:30 -0000 1.6 *************** *** 53,63 **** /** * <p> ! * A simple wrapper around {@link TestSuite}that permits the caller to specify ! * the delegate {@link Test}for either directly or recursively contained ! * {@link IProxyTest}s added to a {@linkProxyTestSuite}. There are three cases * for junit: * <ol> * <li>An instantiated test. This is an instance of some class that extends ! * {@link TestCase}. If the class implements {@link IProxyTest}then the * <i>delegate </i> will be set on the test instance and will be available when * that test runs.</li> --- 53,63 ---- /** * <p> ! * A simple wrapper around {@link TestSuite} that permits the caller to specify ! * the delegate {@link Test} for either directly or recursively contained ! * {@link IProxyTest}s added to a {@link ProxyTestSuite}. There are three cases * for junit: * <ol> * <li>An instantiated test. This is an instance of some class that extends ! * {@link TestCase}. If the class implements {@link IProxyTest} then the * <i>delegate </i> will be set on the test instance and will be available when * that test runs.</li> *************** *** 70,74 **** * indirectly to that {@link ProxyTestSuite}. The various constructors all * invoke this method to flow down the delegate. In addition, the ! * {@link #addTest(TestSuite)}and {@link #addTestSuite(Class)}methods also * invoke this method to flow down the delegate to instantiated tests that * implement {@link IProxyTest}.</li> --- 70,74 ---- * indirectly to that {@link ProxyTestSuite}. The various constructors all * invoke this method to flow down the delegate. In addition, the ! * {@link #addTest(Test)} and {@link #addTestSuite(Class)} methods also * invoke this method to flow down the delegate to instantiated tests that * implement {@link IProxyTest}.</li> |
From: Bryan T. <tho...@us...> - 2007-03-20 13:52:38
|
Update of /cvsroot/cweb/junit-ext In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv30815 Modified Files: project.properties Log Message: javadoc corrections. Index: project.properties =================================================================== RCS file: /cvsroot/cweb/junit-ext/project.properties,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** project.properties 18 Mar 2005 19:00:41 -0000 1.2 --- project.properties 20 Mar 2007 13:52:31 -0000 1.3 *************** *** 9,15 **** maven.repo.remote=http://www.ibiblio.org/maven/,http://www.cognitiveweb.org/maven-repository,http://proto.cognitiveweb.org/maven-repository maven.javadoc.links=\ http://java.sun.com/j2se/1.4.2/docs/api \ ! , http://www.junit.org/junit/javadoc/3.8 maven.javadoc.offlineLinks=\ --- 9,19 ---- maven.repo.remote=http://www.ibiblio.org/maven/,http://www.cognitiveweb.org/maven-repository,http://proto.cognitiveweb.org/maven-repository + # Links to external packages. The package-list javadoc file for + # directory referenced by the (relative) URLs MUST exist at the time + # that the javadoc for this package is generated. + maven.javadoc.links=\ http://java.sun.com/j2se/1.4.2/docs/api \ ! , http://www.junit.org/junit/javadoc/3.8.1/ maven.javadoc.offlineLinks=\ |
From: Bryan T. <tho...@us...> - 2007-03-20 13:40:38
|
Update of /cvsroot/cweb/junit-ext/src/java/junit/framework In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv25865/src/java/junit/framework Modified Files: TestCase2.java Log Message: javadoc comments and modification to reduce logging. Index: TestCase2.java =================================================================== RCS file: /cvsroot/cweb/junit-ext/src/java/junit/framework/TestCase2.java,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** TestCase2.java 14 Feb 2007 15:53:55 -0000 1.20 --- TestCase2.java 20 Mar 2007 13:40:33 -0000 1.21 *************** *** 707,710 **** --- 707,714 ---- //************************************************************ + /** + * Test helper that can correctly compare arrays of primitives and + * arrays of objects as well as primitives and objects. + */ static public void assertSameValue( Object expected, Object actual ) { *************** *** 720,724 **** * the code to throw {@link AssertionFailedError} instead. */ - static public void assertSameValue( String msg, Object expected, Object actual ) { --- 724,727 ---- *************** *** 878,889 **** Object g = actual.next(); ! if (!expected[i].equals(g)) { /* * Only do message construction if we know that the assert will * fail. */ ! assertTrue(msg + ": Different objects at index=" + i ! + ": expected=" + expected[i] + ", actual=" + g, ! expected[i].equals(g)); } --- 881,894 ---- Object g = actual.next(); ! // if (!expected[i].equals(g)) { ! try { ! assertSameValue(expected[i],g); ! } catch(AssertionFailedError ex) { /* * Only do message construction if we know that the assert will * fail. */ ! fail(msg + ": Different objects at index=" + i + ": expected=" ! + expected[i] + ", actual=" + g); } |
From: Bryan T. <tho...@us...> - 2007-03-18 22:29:49
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/service In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv18893/src/java/com/bigdata/service Modified Files: DataService.java Added Files: IResourceTransfer.java IWritePipeline.java AbstractService.java Log Message: more work on jini support. --- NEW FILE: AbstractService.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 18, 2007 */ package com.bigdata.service; import java.io.IOException; import java.io.Serializable; import java.rmi.RemoteException; import net.jini.core.entry.Entry; import net.jini.core.lease.Lease; import net.jini.core.lookup.ServiceID; import net.jini.core.lookup.ServiceItem; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.lookup.ServiceRegistration; import net.jini.discovery.DiscoveryEvent; import net.jini.discovery.DiscoveryListener; import net.jini.discovery.LookupDiscovery; import net.jini.id.Uuid; import net.jini.id.UuidFactory; import net.jini.lease.LeaseListener; import net.jini.lease.LeaseRenewalEvent; import net.jini.lease.LeaseRenewalManager; import net.jini.lookup.entry.Address; import net.jini.lookup.entry.Comment; import net.jini.lookup.entry.Location; import net.jini.lookup.entry.Name; import net.jini.lookup.entry.ServiceInfo; import net.jini.lookup.entry.ServiceType; import net.jini.lookup.entry.Status; import net.jini.lookup.entry.StatusType; import org.apache.log4j.Logger; /** * Abstract base class for services discoverable using JINI. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ abstract public class AbstractService implements DiscoveryListener, LeaseListener, IServiceShutdown { public static Logger log = Logger.getLogger(AbstractService.class); private ServiceID serviceID; private ServiceItem item; private ServiceRegistration reg; final private LeaseRenewalManager leaseManager = new LeaseRenewalManager(); /** * Close down the service (no longer discoverable). * * @todo revoke lease, etc. */ private void _close() { } /** * Waits for existing leases to expire before shutting down, but does not * grant any new leases. */ public void shutdown() { /* * @todo wait for leases to expire and then shutdown. do not renew any * leases. */ _close(); } /** * Shutdown immediately, violating any existing leases. */ public void shutdownNow() { _close(); } /** * Return the {@link ServiceID}. Using a consistent {@link ServiceID} makes * it easier to register the same service against multiple lookup services. * <p> * This implementation generates a new {@link ServiceID} each time. * * @todo If you want to restart (or re-register) the same service, then you * need to read the serviceID from some persistent location. If you * are using activation, then the service can be remotely started * using its serviceID which takes that responsibility out of your * hands. When using activation, you will only create a serviceID once * when you install the service onto some component and activition * takes responsiblity for starting the service on demand. */ public ServiceID getServiceID() { Uuid uuid = UuidFactory.generate(); return new ServiceID(uuid.getMostSignificantBits(), uuid .getLeastSignificantBits()); } /** * Server startup performs asynchronous multicast lookup discovery. The * {@link #discovered(DiscoveryEvent)} method is invoked asynchronously to * register {@link TestServerImpl} instances. */ public AbstractService() { serviceID = getServiceID(); try { LookupDiscovery discover = new LookupDiscovery( LookupDiscovery.ALL_GROUPS); discover.addDiscoveryListener(this); } catch (IOException ex) { throw new RuntimeException(ex); } } /** * Log a message and register the {@link TestServerImpl}. Events are * aggregated but we can still receive multiple events depending on the * latency between discovery of various service registrars. Since the * multicast protocol was used to discover service registrars, we can wind * up registering with more than one registrar. * * @todo If we do not receive this message after some timeout then the * server should log an error (in main()) and exit with a non-zero * status code. This means that the service needs to expose an * indicator of whether or not it has been registered. * * @todo Modify service proxy to use RMI. * * @todo This should be a fast operation and should not make remote calls. * Service registration therefore needs to happen in another thread so * that the service registrar can continue about its business. */ public void discovered(DiscoveryEvent evt) { /* * At this point we have discovered one or more lookup services. */ registerService( evt.getRegistrars() ); } /** * Registers a service proxy with reach identified registrar. The * registration happens in another thread to keep the latency down for the * {@link DiscoveryListener#discovered(net.jini.discovery.DiscoveryEvent)} * event. * * @param registrars * One or more service registrars. */ private void registerService( final ServiceRegistrar[] registrars ) { AbstractService.log.info("Discovered "+registrars.length+" service registrars"); new Thread("Register Service") { public void run() { // Create an information item about a service item = new ServiceItem(serviceID, new TestServerImpl(), new Entry[] { new Comment("Test service(comment)"), // human facing comment. new Name("Test service(name)"), // human facing name. new MyServiceType("Test service (display name)", "Test Service (short description)"), // service type new MyStatus(StatusType.NORMAL), new Location("floor","room","building"), new Address("street", "organization", "organizationalUnit", "locality", "stateOrProvince", "postalCode", "country"), new ServiceInfo("bigdata", // product or package name "SYSTAP,LLC", // manufacturer "SYSTAP,LLC", // vendor "0.1-beta", // version "bigdata", // model "serial#" // serialNumber ) }); for (int i = 0; i < registrars.length; i++) { /* * Register a service. The service requests a "long" lease using * Lease.FOREVER. The registrar will decide on the actual length * of the lease. */ ServiceRegistrar registrar = registrars[i]; while (reg == null) { try { // Register the service. reg = registrar.register(item, Lease.FOREVER); } catch (RemoteException ex) { // retry until successful. try { Thread.sleep(100); } catch (InterruptedException ex2) { } } /* * Setup automatic lease renewal. * * Note: A single lease manager can handle multiple services * and the lease of a given service on multiple service * registrars. It knows which lease is about to expire and * preemptively extends the lease on the behalf of the * registered service. It will notify the LeaseListener iff * it is unable to renew a lease. */ AbstractService.log.info("lease will expire in " + (reg.getLease().getExpiration() - System .currentTimeMillis()) + "ms"); leaseManager .renewUntil(reg.getLease(), Lease.FOREVER, AbstractService.this); /* * Service has been registered and lease renewal is * operating. */ break; } } } }.start() ; } /** * Log a message. */ public void discarded(DiscoveryEvent arg0) { AbstractService.log.info(""); } /** * Note: This is only invoked if the automatic lease renewal by the * lease manager is denied by the service registrar. In that case we * should probably update the Status to indicate an error condition. */ public void notify(LeaseRenewalEvent event) { AbstractService.log.error("Lease could not be renewed: " + event); } /** * Launch the server in a separate thread. */ public static void launchServer() { new Thread("launchServer") { public void run() { AbstractService.main(new String[] {}); } }.start(); } /** * Run the server. It will die after a timeout. * * @param args * Ignored. */ public static void main(String[] args) { final long lifespan = 3 * 60 * 1000; // life span in seconds. AbstractService.log.info("Will start test server."); AbstractService testServer = new AbstractService(){ /* @todo this is an anonymous class - each service must provide its * own main() and registration information. */ }; AbstractService.log.info("Started test server."); try { Thread.sleep(lifespan); } catch( InterruptedException ex ) { AbstractService.log.warn(ex); } /* * @todo This forces a hard reference to remain for the test server. */ AbstractService.log.info("Server will die: "+testServer); } /** * {@link Status} is abstract so a service needs to provide their own * concrete implementation. * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson</a> */ public static class MyStatus extends Status { /** * */ private static final long serialVersionUID = 3431522046169284463L; /** * Deserialization constructor (required). */ public MyStatus(){} public MyStatus(StatusType statusType) { /* * Note: This just sets the read/write public [severity] field on * the super class. */ super(statusType); } } /** * {@link ServiceType} is abstract so a service basically needs to provide * their own concrete implementation. This class does not support icons * (always returns null for {@link ServiceType#getIcon(int)}. See * {@link java.beans.BeanInfo} for how to interpret and support the * getIcon() method. * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson * </a> */ public static class MyServiceType extends ServiceType { /** * */ private static final long serialVersionUID = -2088608425852657477L; public String displayName; public String shortDescription; /** * Deserialization constructor (required). */ public MyServiceType() {} public MyServiceType(String displayName, String shortDescription) { this.displayName = displayName; this.shortDescription = shortDescription; } public String getDisplayName() { return displayName; } public String getShortDescription() { return shortDescription; } } /** * The interfaces implemented by the service should be made locally * available to the client so that it can execute methods on those * interfaces without using reflection. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public static interface ITestService { /** * Method for testing remote invocation. */ public void invoke(); } /** * The proxy object that gets passed around. * * @todo It appears that multiple instances of this class are getting * created. This is consistent with the notion that the instance is * being "passed" around by state and not by reference. This implies * that instances are not consumed when they are discovered but merely * cloned using Java serialization. * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson * </a> */ public static class TestServerImpl implements ITestService, Serializable { /** * Note: Mark the {@link Logger} as transient since we do NOT need to * serialize its state. */ public static final transient Logger log = Logger.getLogger(TestServerImpl.class); /** * */ private static final long serialVersionUID = -920558820563934297L; /** * De-serialization constructor (required). */ public TestServerImpl() { // System.err.println("Created: "+this); log.info("Created: "+this); } public void invoke() { // System.err.println("invoked: "+this); log.info("invoked: "+this); } } } --- NEW FILE: IResourceTransfer.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 18, 2007 */ package com.bigdata.service; import java.net.InetSocketAddress; /** * An interface used to ship around journals and index segments among data * services in support of load-balancing, self-healing, and failover. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public interface IResourceTransfer { /** * Send a resource. * * @param filename * The local filename for the resource. * @param sink * The sink that will receive the resource. */ public void sendResource(String filename,InetSocketAddress sink); } --- NEW FILE: IWritePipeline.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 18, 2007 */ package com.bigdata.service; /** * An interface used to pipeline writes against index partitions over one or * more secondary data services providing high availability and failover for * that index partition. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ * * @todo define api for managing the write pipeline. any write operations on a * data service should indicate the index partition (name + partitionId) * on which they are writing and the write requests should be chained down * the configured write pipeline. */ public interface IWritePipeline { } Index: DataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/DataService.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** DataService.java 17 Mar 2007 23:14:58 -0000 1.2 --- DataService.java 18 Mar 2007 22:29:43 -0000 1.3 *************** *** 48,51 **** --- 48,52 ---- package com.bigdata.service; + import java.net.InetSocketAddress; import java.util.Properties; import java.util.concurrent.Callable; *************** *** 134,139 **** * {@link DataService} instance for the write when it needs to commit or * abort the tx. */ ! public class DataService implements IDataService, IServiceShutdown { protected Journal journal; --- 135,144 ---- * {@link DataService} instance for the write when it needs to commit or * abort the tx. + * + * @todo narrow file access permissions so that we only require + * {read,write,create,delete} access to a temporary directory and a data + * directory. */ ! public class DataService extends AbstractService implements IDataService, IWritePipeline, IResourceTransfer { protected Journal journal; *************** *** 873,875 **** --- 878,887 ---- } + /** + * @todo IResourceTransfer is not implemented. + */ + public void sendResource(String filename, InetSocketAddress sink) { + throw new UnsupportedOperationException(); + } + } |
From: Bryan T. <tho...@us...> - 2007-03-18 22:29:49
|
Update of /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv18893/src/test/org/CognitiveWeb/bigdata/jini Modified Files: TestServer.java TestServiceDiscovery.java Added Files: ITestService.java Log Message: more work on jini support. Index: TestServiceDiscovery.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini/TestServiceDiscovery.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TestServiceDiscovery.java 17 Mar 2007 23:14:59 -0000 1.2 --- TestServiceDiscovery.java 18 Mar 2007 22:29:43 -0000 1.3 *************** *** 48,52 **** import java.io.IOException; - import java.io.Serializable; import java.net.InetAddress; --- 48,51 ---- *************** *** 70,78 **** * Browser (you will see "Unknown service") unless you set the codebase when * executing this test class and the .class files are available for download ! * from the codebase URL. I jump start the tests myself using * </p> * * <pre> ! * -Djava.security.policy=policy.all -Djava.rmi.server.codebase=http://proto.cognitiveweb.org/maven-repository/bigdata/jars/ * </pre> * --- 69,80 ---- * Browser (you will see "Unknown service") unless you set the codebase when * executing this test class and the .class files are available for download ! * from the codebase URL. I jump start the tests myself by copying them onto an ! * HTTP server and using the following options in the command line to execute ! * the test: * </p> * * <pre> ! * -Djava.security.policy=policy.all ! * -Djava.rmi.server.codebase=http://proto.cognitiveweb.org/maven-repository/bigdata/jars/ * </pre> * *************** *** 97,118 **** * network. * ! * @todo Explore the jini {@link net.jini.core.transaction.Transaction}model. * Perhaps we can use this as is to support two phase commits across the * database segments? The transaction model does not impose any semantics, * e.g., there is no locking, but we can handle all of that. * - * @see http://archives.java.sun.com/cgi-bin/wa?A2=ind0311&L=jini-users&F=&S=&P=7182 - * for a description of policy files and - * http://www.dancres.org/cottage/jini-start-examples-2_1.zip for the - * policy files described.<br> - * When testing standalone with only trusted code and NO downloaded code, - * it is reasonable to consider running the test code using - * "-Djava.security.policy=policy.all" so that you can get things moving. - * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson * </a> */ - public class TestServiceDiscovery extends TestCase { --- 99,111 ---- * network. * ! * @todo Explore the jini {@link net.jini.core.transaction.Transaction} model. * Perhaps we can use this as is to support two phase commits across the * database segments? The transaction model does not impose any semantics, * e.g., there is no locking, but we can handle all of that. * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson * </a> */ public class TestServiceDiscovery extends TestCase { *************** *** 127,140 **** */ ! public void test_serviceDiscovery() throws IOException, ClassNotFoundException { ! /* ! * install suitable security manager. this is required before the ! * application can download code. ! */ ! System.setSecurityManager(new SecurityManager()); ! /* ! * Launch the server to which we will connect. */ TestServer.launchServer(); --- 120,141 ---- */ ! public void test_serviceDiscovery() throws IOException, ! ClassNotFoundException { ! /* ! * Install suitable security manager. this is required before the client ! * can download code. The code will be downloaded from the HTTP server ! * identified by the codebase property specified for the VM running the ! * service. For the purposes of this test, we are using the _same_ VM to ! * run the client and the service, so you have to specify the codebase ! * property when running the test. ! */ ! System.setSecurityManager(new SecurityManager()); ! /* ! * Launch the server to which we will connect (this is being done by the ! * test harness rather than setting up activation for the service since ! * we want to explicitly control the service instances for the purpose ! * of testing). */ TestServer.launchServer(); *************** *** 155,165 **** /* ! * What follows is an example of service lookup, but we have to register ! * the service first. */ ! ! // Prepare a template for lookup search ! ServiceTemplate template = new ServiceTemplate(null, ! new Class[] { TestServerImpl.class }, null); /* --- 156,179 ---- /* ! * Prepare a template for lookup search. ! * ! * Note: The client needs a local copy of the interface in order to be ! * able to invoke methods on the service without using reflection. The ! * implementation class will be downloaded from the codebase identified ! * by the server. */ ! ServiceTemplate template = new ServiceTemplate(// ! /* ! * use this to request the service by its serviceID. ! */ ! null, ! /* ! * Use this to filter services by an interface that they expose. ! */ ! new Class[] { ITestService.class }, ! /* ! * use this to filter for services by Entry attributes. ! */ ! null); /* *************** *** 172,239 **** * wait state). */ ! TestServerImpl service = null; ! for( int i=0; i<10 && service == null; i++) { ! service = (TestServerImpl) serviceRegistrar.lookup(template /*, maxMatches*/); ! if( service == null ) { ! log.info("Service not found: sleeping..."); ! try {Thread.sleep(100);} ! catch( InterruptedException ex) {} ! } ! } ! ! assertNotNull("Could not find service.", service ); ! ! service.invoke(); ! ! // Sleep for a bit so that I can inspect the service in the Service Browser. ! try {Thread.sleep(10000);} ! catch( InterruptedException ex) {} ! ! } ! ! public static interface ITestService ! { ! ! /** ! * Method for testing remote invocation. ! */ ! public void invoke(); ! ! } ! ! /** ! * The proxy object that gets passed around. ! * ! * @todo It appears that multiple instances of this class are getting ! * created. This is consistent with the notion that the instance is ! * being "passed" around by state and not by reference. This implies ! * that instances are not consumed when they are discovered but merely ! * cloned using Java serialization. ! * ! * @version $Id$ ! * @author <a href="mailto:tho...@us...">Bryan Thompson ! * </a> ! */ ! public static class TestServerImpl implements ITestService, Serializable ! { ! /** ! * ! */ ! private static final long serialVersionUID = -920558820563934297L; ! /** ! * De-serialization constructor (required). ! */ ! public TestServerImpl() { ! log.info("Created: "+this); ! } ! public void invoke() { ! log.info("invoked: "+this); } } ! public static void main(String[] args) throws Exception { --- 186,215 ---- * wait state). */ ! ITestService service = null; ! for (int i = 0; i < 10 && service == null; i++) { ! service = (ITestService) serviceRegistrar ! .lookup(template /* , maxMatches */); ! if (service == null) { ! log.info("Service not found: sleeping..."); ! try { ! Thread.sleep(200); ! } catch (InterruptedException ex) { ! } ! } ! } ! assertNotNull("Could not find service.", service); ! service.invoke(); ! // Sleep for a bit so that I can inspect the service in the Service ! // Browser. ! try { ! Thread.sleep(10000); ! } catch (InterruptedException ex) { } } ! public static void main(String[] args) throws Exception { --- NEW FILE: ITestService.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 18, 2007 */ package org.CognitiveWeb.bigdata.jini; import java.io.IOException; import java.rmi.Remote; import java.rmi.RemoteException; /** * The public interface for a test service. * <p> * Note: The interface extends {@link Remote} so that both the implementation of * this service and the proxy generated by jeri for the service will implement * this interface. This is necessary for service discovery or the resulting * proxy will NOT implement the interface and both service discovery (based on * the interface name) and use of the interface via the proxy will fail. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ * * @client This interface must be available to the client in order for it to * execute the methods defined by the interface without the use of * reflection. * * @server This interface must be available to the server since it exposes this * interface on its service. */ public interface ITestService extends Remote { /** * Method for testing remote invocation. * <p> * Note: The methods on a {@link Remote} interface MUST throw * {@link RemoteException} (or {@link IOException} if you want to reduce * your dependency on JINI for an interface that is also used outside of * JINI). */ public void invoke() throws RemoteException; } Index: TestServer.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini/TestServer.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TestServer.java 17 Mar 2007 23:14:59 -0000 1.2 --- TestServer.java 18 Mar 2007 22:29:43 -0000 1.3 *************** *** 48,54 **** import java.io.IOException; ! import java.rmi.RMISecurityManager; import java.rmi.RemoteException; import net.jini.core.entry.Entry; import net.jini.core.lease.Lease; --- 48,55 ---- import java.io.IOException; ! import java.rmi.Remote; import java.rmi.RemoteException; + import net.jini.admin.JoinAdmin; import net.jini.core.entry.Entry; import net.jini.core.lease.Lease; *************** *** 60,65 **** --- 61,71 ---- import net.jini.discovery.DiscoveryListener; import net.jini.discovery.LookupDiscovery; + import net.jini.export.Exporter; + import net.jini.export.ProxyAccessor; import net.jini.id.Uuid; import net.jini.id.UuidFactory; + import net.jini.jeri.BasicILFactory; + import net.jini.jeri.BasicJeriExporter; + import net.jini.jeri.tcp.TcpServerEndpoint; import net.jini.lease.LeaseListener; import net.jini.lease.LeaseRenewalEvent; *************** *** 74,78 **** import net.jini.lookup.entry.StatusType; ! import org.CognitiveWeb.bigdata.jini.TestServiceDiscovery.TestServerImpl; /** --- 80,84 ---- import net.jini.lookup.entry.StatusType; ! import org.apache.log4j.Logger; /** *************** *** 82,89 **** * invocation and one to shutdown the server. * - * @todo Look into {@link java.rmi.RMISecurityManager}. Simply adding this to - * main() causes things to fail, but gives us the trace that was otherwise - * missing. - * * @todo Look into the manager classes for service joins, discovery, etc. The * code in this class can probably be simplified drammatically. --- 88,91 ---- *************** *** 96,99 **** --- 98,103 ---- { + public static Logger log = Logger.getLogger(TestServer.class); + private ServiceID serviceID; private ServiceItem item; *************** *** 151,158 **** * indicator of whether or not it has been registered. * ! * @todo I can't figure out how to get the service to show up with its ! * metadata in the service browser. ! * ! * @todo Modify service proxy to use RMI. * * @todo This should be a fast operation and should not make remote calls. --- 155,161 ---- * indicator of whether or not it has been registered. * ! * @todo Modify service proxy to use RMI. The client stub should be ! * downloaded from the codebase and should know how to commuicate with ! * the discovered service, e.g., using RMI or a custom NIO protocol. * * @todo This should be a fast operation and should not make remote calls. *************** *** 171,175 **** /** ! * Registers a service proxy with reach identified registrar. The * registration happens in another thread to keep the latency down for the * {@link DiscoveryListener#discovered(net.jini.discovery.DiscoveryEvent)} --- 174,178 ---- /** ! * Registers a service proxy with each identified registrar. The * registration happens in another thread to keep the latency down for the * {@link DiscoveryListener#discovered(net.jini.discovery.DiscoveryEvent)} *************** *** 179,191 **** * One or more service registrars. */ - private void registerService( final ServiceRegistrar[] registrars ) { ! TestServiceDiscovery.log.info("Discovered "+registrars.length+" service registrars"); new Thread("Register Service") { public void run() { // Create an information item about a service ! item = new ServiceItem(serviceID, new TestServerImpl(), new Entry[] { new Comment("Test service(comment)"), // human facing comment. new Name("Test service(name)"), // human facing name. --- 182,195 ---- * One or more service registrars. */ private void registerService( final ServiceRegistrar[] registrars ) { ! log.info("Discovered "+registrars.length+" service registrars"); new Thread("Register Service") { public void run() { + // the service + Object impl = new TestServerImpl().getProxy(); // Create an information item about a service ! item = new ServiceItem(serviceID, impl, new Entry[] { new Comment("Test service(comment)"), // human facing comment. new Name("Test service(name)"), // human facing name. *************** *** 216,219 **** --- 220,243 ---- // Register the service. reg = registrar.register(item, Lease.FOREVER); + /* + * Setup automatic lease renewal. + * + * Note: A single lease manager can handle multiple services + * and the lease of a given service on multiple service + * registrars. It knows which lease is about to expire and + * preemptively extends the lease on the behalf of the + * registered service. It will notify the LeaseListener iff + * it is unable to renew a lease. + */ + log.info("lease will expire in " + + (reg.getLease().getExpiration() - System + .currentTimeMillis()) + "ms"); + leaseManager + .renewUntil(reg.getLease(), Lease.FOREVER, TestServer.this); + /* + * Service has been registered and lease renewal is + * operating. + */ + break; } catch (RemoteException ex) { // retry until successful. *************** *** 223,244 **** } } - /* - * Setup automatic lease renewal. - * - * Note: A single lease manager can handle multiple services - * and the lease of a given service on multiple service - * registrars. It knows which lease is about to expire and - * preemptively extends the lease on the behalf of the - * registered service. It will notify the LeaseListener iff - * it is unable to renew a lease. - */ - TestServiceDiscovery.log.info("lease will expire in " - + (reg.getLease().getExpiration() - System - .currentTimeMillis()) + "ms"); - leaseManager - .renewUntil(reg.getLease(), Lease.FOREVER, TestServer.this); - // Service has been registered and lease renewal is - // operating. - break; } } --- 247,250 ---- *************** *** 255,259 **** public void discarded(DiscoveryEvent arg0) { ! TestServiceDiscovery.log.info(""); } --- 261,265 ---- public void discarded(DiscoveryEvent arg0) { ! log.info(""); } *************** *** 266,270 **** public void notify(LeaseRenewalEvent event) { ! TestServiceDiscovery.log.error("Lease could not be renewed: " + event); } --- 272,276 ---- public void notify(LeaseRenewalEvent event) { ! log.error("Lease could not be renewed: " + event); } *************** *** 289,310 **** public static void main(String[] args) { final long lifespan = 3 * 60 * 1000; // life span in seconds. ! TestServiceDiscovery.log.info("Will start test server."); TestServer testServer = new TestServer(); ! TestServiceDiscovery.log.info("Started test server."); try { Thread.sleep(lifespan); } catch( InterruptedException ex ) { ! TestServiceDiscovery.log.warn(ex); } /* * @todo This forces a hard reference to remain for the test server. */ ! TestServiceDiscovery.log.info("Server will die: "+testServer); } /** ! * {@link Status} is abstract so a service basically needs to provide their ! * own concrete implementation. * * @version $Id$ --- 295,316 ---- public static void main(String[] args) { final long lifespan = 3 * 60 * 1000; // life span in seconds. ! log.info("Will start test server."); TestServer testServer = new TestServer(); ! log.info("Started test server."); try { Thread.sleep(lifespan); } catch( InterruptedException ex ) { ! log.warn(ex); } /* * @todo This forces a hard reference to remain for the test server. */ ! log.info("Server will die: "+testServer); } /** ! * {@link Status} is abstract so a service needs to provide their own ! * concrete implementation. * * @version $Id$ *************** *** 318,326 **** private static final long serialVersionUID = 3431522046169284463L; - /* - * Note: public fields are required and must be Serializable. - */ - public StatusType statusType; - /** * Deserialization constructor (required). --- 324,327 ---- *************** *** 329,333 **** public MyStatus(StatusType statusType) { ! this.statusType = statusType; } --- 330,340 ---- public MyStatus(StatusType statusType) { ! ! /* ! * Note: This just sets the read/write public [severity] field on ! * the super class. ! */ ! super(statusType); ! } *************** *** 376,378 **** } ! } \ No newline at end of file --- 383,553 ---- } ! /** ! * The remote service implementation object. This implements the ! * {@link Remote} interface and uses JERI to create a proxy for the remote ! * object and configure and manage the protocol for communications between ! * the client (service proxy) and the remote object (the service ! * implementation). ! * <p> ! * Note: You have to implement {@link JoinAdmin} in order to show up as an ! * administerable service (blue folder) in the jini Service Browser. ! * ! * @version $Id$ ! * @author <a href="mailto:tho...@us...">Bryan Thompson ! * </a> ! */ ! public static class TestServerImpl implements ProxyAccessor, ITestService/*, Serializable*/ ! { ! ! /** ! * Note: Mark the {@link Logger} as transient since we do NOT need to ! * serialize its state. ! * <p> ! * ! * @todo When the service uses a proxy and a remote communications ! * protocol, the service instance is remote and this object is not ! * instantiated on the client (test this hypothesis by removing ! * log4j from the codebase). ! */ ! public static final transient Logger log = Logger.getLogger(TestServerImpl.class); ! ! // Note required when using a service proxy. the Exporter handles the proxy generation. ! // /** ! // * ! // */ ! // private static final long serialVersionUID = -920558820563934297L; ! ! /** ! * The location of the JERI configuration file. ! * ! * @todo provide a command line option to override the file location. ! */ ! private transient static String CONFIG_FILE = "jeri/jeri.config"; ! ! private ITestService proxy; ! ! // /** ! // * ! // * @param args ! // * @throws Exception ! // * ! // * @see http://jan.newmarch.name/java/jini/tutorial/Jeri.xml for an ! // * explanation of what is going on here. ! // */ ! // public static void main(String[] args) throws Exception { ! // ! // String[] configArgs = new String[] { CONFIG_FILE }; ! // ! // // get the configuration (by default a FileConfiguration) ! // Configuration config = ConfigurationProvider ! // .getInstance(configArgs); ! // System.out.println("Configuration: " + config.toString()); ! // ! // // and use the configuration to construct an exporter ! // Exporter exporter = (Exporter) config.getEntry( ! // // ! // TestServerImpl.class.getName(), // component ! // "exporter", // name ! // Exporter.class, // type (of the return object) ! // new BasicJeriExporter(TcpServerEndpoint.getInstance(0), ! // new BasicILFactory()) /* default */,// ! // Configuration.NO_DATA // data. ! // ); ! // ! // // export an object of this class ! // Remote proxy = exporter.export(new TestServerImpl()); ! // System.out.println("Proxy is " + proxy.toString()); ! // ! // // now unexport it once finished ! // exporter.unexport(true); ! // ! // } ! ! /* ! * @todo presumably service shutdown should clear the proxy reference ! * once the service has been removed from the registry. ! */ ! public Object getProxy() { ! ! return proxy; ! ! } ! ! /** ! * Service constructor. ! * ! * @todo can the constructor accept arguments? ! */ ! public TestServerImpl() /*@todo throws RemoteException ?*/ { ! ! /* ! * @todo when this is added the test will succeed the first time but ! * thereafter will fail with a connection refused to the end point ! * for the _expired_ service. While that exception makes sense in ! * that the expired service should not be connectable, I do not ! * understand why adding or dropping this line has any influence. ! * Perhaps the problem is that it changes GC behavior and the prior ! * test service is otherwise NOT expired? Look into what this ! * service is doing to shutdown after the test and what is should ! * be doing. ! * ! * So - the test does NOT attempt to close down the service - I was ! * deliberately leaving it open so that I could explore the service ! * in the Service Browser. The issue may be that this replaces the ! * SecurityManager after one was already installed in the VM by the ! * test itself! ! */ ! // System.setSecurityManager(new SecurityManager()); ! ! try { ! ! // @todo work out use of a configuration file. ! // String[] configArgs = new String[] { CONFIG_FILE }; ! // ! // // get the configuration (by default a FileConfiguration) ! // Configuration config = ConfigurationProvider ! // .getInstance(configArgs); ! // System.out.println("Configuration: " + config.toString()); ! // ! // // and use the configuration to construct an exporter ! // Exporter exporter = (Exporter) config.getEntry( ! // // ! // TestServerImpl.class.getName(), // component ! // "exporter", // name ! // Exporter.class, // type (of the return object) ! // new BasicJeriExporter(TcpServerEndpoint.getInstance(0), ! // new BasicILFactory()) /* default */,// ! // Configuration.NO_DATA // data. ! // ); ! ! // hardwired jeri exporter using TCP. ! Exporter exporter = new BasicJeriExporter(TcpServerEndpoint ! .getInstance(0), new BasicILFactory()); ! ! // export an object of this class ! proxy = (ITestService) exporter.export(this); ! log.info("Proxy is " + proxy + "(" + proxy.getClass() + ")"); ! ! } catch(Exception ex) { ! // @todo should we retry the operation? ! log.error(ex); ! throw new RuntimeException(ex); ! } ! ! // @todo who will unexport the proxy? ! ! // // now unexport it once finished ! // exporter.unexport(true); ! ! // System.err.println("Created: "+this); ! log.info("Created: "+this); ! } ! ! public void invoke() { ! // System.err.println("invoked: "+this); ! log.info("invoked: "+this); ! } ! ! } ! ! } |
From: Bryan T. <tho...@us...> - 2007-03-18 22:29:48
|
Update of /cvsroot/cweb/bigdata In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv18893 Modified Files: build.xml Log Message: more work on jini support. Index: build.xml =================================================================== RCS file: /cvsroot/cweb/bigdata/build.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** build.xml 17 Mar 2007 23:14:59 -0000 1.1 --- build.xml 18 Mar 2007 22:29:43 -0000 1.2 *************** *** 72,75 **** --- 72,79 ---- themselves are available for download (only .class files are downloaded, NOT JARs). + + cd /home/groups/c/cw/cweb/maven-repository/bigdata/jars + + /usr/java/j2sdk1.4.2_05/bin/jar xf bigdata.jar Finally, the code that will expose services with downloadable code MUST set *************** *** 96,102 **** --- 100,124 ---- for some (very good) guidence in debugging jini services. + Note: You may have to restart jini locally in order to force download of + updated classes from the codebase! + See http://archives.java.sun.com/cgi-bin/wa?A2=ind0512&L=jini-users&P=R391&I=-3 for instructions on setting up an "download jar" (dljar) ANT task that can make life much simpler (one supposes). + + See http://archives.java.sun.com/cgi-bin/wa?A2=ind0311&L=jini-users&F=&S=&P=7182 + for a description of policy files and + http://www.dancres.org/cottage/jini-start-examples-2_1.zip for the + policy files described. + + See http://jan.newmarch.name/java/jini/tutorial/Ant.xml for a description of + one (simple) approach to using ant for jini projects (it does not use the + dljar ant task but explicitly enumerates what goes where). + + See http://jan.newmarch.name/java/jini/tutorial/TroubleShooting.xml#RMI%20Stubs + for common errors when using RMI stubs. + + See https://java.sun.com/products/jini/2.1/doc/api/com/sun/jini/example/browser/package-summary.html + for the dirty on the jini Service Browser. @todo you need to install the client and server deployments on machines |
From: Bryan T. <tho...@us...> - 2007-03-18 22:29:48
|
Update of /cvsroot/cweb/bigdata/src/java/org/CognitiveWeb/bigdata In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv18893/src/java/org/CognitiveWeb/bigdata Modified Files: LockServer.java Log Message: more work on jini support. Index: LockServer.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/org/CognitiveWeb/bigdata/LockServer.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** LockServer.java 26 Aug 2006 19:30:20 -0000 1.1 --- LockServer.java 18 Mar 2007 22:29:43 -0000 1.2 *************** *** 49,53 **** import net.jini.discovery.DiscoveryEvent; - import org.CognitiveWeb.bigdata.jini.TestServiceDiscovery.TestServerImpl; import org.CognitiveWeb.concurrent.locking.TxDag; import org.apache.log4j.Logger; --- 49,52 ---- |
From: Bryan T. <tho...@us...> - 2007-03-18 12:59:59
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/journal In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12438/src/java/com/bigdata/journal Modified Files: ITxCommitProtocol.java AbstractJournal.java Log Message: A little more work setting up for the services architecture. Index: AbstractJournal.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/journal/AbstractJournal.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** AbstractJournal.java 15 Mar 2007 16:11:12 -0000 1.3 --- AbstractJournal.java 17 Mar 2007 23:14:59 -0000 1.4 *************** *** 187,191 **** * persistence data structure. */ ! public abstract class AbstractJournal implements IJournal, ITimestampService { /** --- 187,191 ---- * persistence data structure. */ ! public abstract class AbstractJournal implements IJournal, ITimestampService, ITxCommitProtocol { /** Index: ITxCommitProtocol.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/journal/ITxCommitProtocol.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ITxCommitProtocol.java 15 Mar 2007 16:11:12 -0000 1.1 --- ITxCommitProtocol.java 17 Mar 2007 23:14:59 -0000 1.2 *************** *** 65,72 **** * * FIXME in order to support 2-/3-phase commit, the [commitTime] from the ! * transaction manager service must be passed through to the journal. There also ! * needs to be a distinct "prepare" message that validates the write set of the ! * transaction and makes it restart safe. finally, i have to coordinate the ! * serialization of the wait for the "commit" message. */ public interface ITxCommitProtocol { --- 65,73 ---- * * FIXME in order to support 2-/3-phase commit, the [commitTime] from the ! * transaction manager service must be passed through to the journal rather than ! * being returned from {@link #commit(long)}. There also needs to be a distinct ! * "prepare" message that validates the write set of the transaction and makes ! * it restart safe. finally, i have to coordinate the serialization of the wait ! * for the "commit" message. */ public interface ITxCommitProtocol { *************** *** 75,79 **** * Request commit of the transaction write set. */ ! public void commit(long tx); /** --- 76,80 ---- * Request commit of the transaction write set. */ ! public long commit(long tx) throws ValidationError; /** |
From: Bryan T. <tho...@us...> - 2007-03-18 12:59:41
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/scaleup In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12438/src/java/com/bigdata/scaleup Modified Files: MasterJournal.java Log Message: A little more work setting up for the services architecture. Index: MasterJournal.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/scaleup/MasterJournal.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MasterJournal.java 15 Mar 2007 16:11:10 -0000 1.2 --- MasterJournal.java 17 Mar 2007 23:14:58 -0000 1.3 *************** *** 66,70 **** import com.bigdata.journal.IsolationEnum; import com.bigdata.journal.Journal; - import com.bigdata.journal.ResourceManager; import com.bigdata.journal.Name2Addr.Entry; import com.bigdata.objndx.AbstractBTree; --- 66,69 ---- |
From: Bryan T. <tho...@us...> - 2007-03-18 12:59:39
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/service In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12438/src/java/com/bigdata/service Modified Files: EmbeddedDataService.java IDataService.java DataService.java IMapOp.java DataServiceClient.java NIODataService.java TransactionService.java Added Files: MapReduceService.java IMetadataService.java IServiceShutdown.java package.html MetadataService.java Log Message: A little more work setting up for the services architecture. Index: NIODataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/NIODataService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** NIODataService.java 15 Mar 2007 16:11:10 -0000 1.1 --- NIODataService.java 17 Mar 2007 23:14:58 -0000 1.2 *************** *** 86,90 **** * replication. */ ! public class NIODataService { // --- 86,100 ---- * replication. */ ! public class NIODataService implements IServiceShutdown { ! ! public void shutdown() { ! // TODO Auto-generated method stub ! ! } ! ! public void shutdownNow() { ! // TODO Auto-generated method stub ! ! } // Index: DataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/DataService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** DataService.java 15 Mar 2007 16:11:11 -0000 1.1 --- DataService.java 17 Mar 2007 23:14:58 -0000 1.2 *************** *** 135,139 **** * abort the tx. */ ! public class DataService implements IDataService { protected Journal journal; --- 135,139 ---- * abort the tx. */ ! public class DataService implements IDataService, IServiceShutdown { protected Journal journal; *************** *** 286,293 **** */ ! public void commit(long tx) { // will place task on writeService and block iff necessary. ! journal.commit(tx); } --- 286,293 ---- */ ! public long commit(long tx) { // will place task on writeService and block iff necessary. ! return journal.commit(tx); } *************** *** 390,396 **** } ! public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, byte[] toKey, ! boolean countOnly, boolean keysOnly, boolean valuesOnly) ! throws InterruptedException, ExecutionException { if( name == null ) throw new IllegalArgumentException(); --- 390,395 ---- } ! public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, ! byte[] toKey, int flags) throws InterruptedException, ExecutionException { if( name == null ) throw new IllegalArgumentException(); *************** *** 400,406 **** "Unisolated context not allowed"); ! RangeQueryResult result = (RangeQueryResult)txService.submit( ! new RangeQueryTask(tx, name, fromKey, toKey, countOnly, ! keysOnly, valuesOnly)).get(); return result; --- 399,404 ---- "Unisolated context not allowed"); ! RangeQueryResult result = (RangeQueryResult) txService.submit( ! new RangeQueryTask(tx, name, fromKey, toKey, flags)).get(); return result; *************** *** 408,445 **** } ! /** ! * @todo if unisolated or isolated at the read-commit level, then the ! * operation really needs to be broken down by partition or perhaps by ! * index segment leaf so that we do not have too much latency during a ! * read (this could be done for rangeQuery as well). ! * ! * @todo if fully isolated, then there is no problem running map. ! * ! * @todo The definition of a row is different if using a key formed from the ! * column name, application key, and timestamp. ! * ! * @todo For at least GOM we need to deserialize rows from byte[]s, so we ! * need to have the (de-)serializer to the application level value on ! * hand. ! */ ! public void map(long tx, String name, byte[] fromKey, byte[] toKey, ! IMapOp op) throws InterruptedException, ExecutionException { ! ! if( name == null ) throw new IllegalArgumentException(); ! ! if (tx == 0L) ! throw new UnsupportedOperationException( ! "Unisolated context not allowed"); ! ! RangeQueryResult result = (RangeQueryResult) txService.submit( ! new RangeQueryTask(tx, name, fromKey, toKey, false, false, ! false)).get(); ! ! // @todo resolve the reducer service. ! IReducer reducer = null; ! ! op.apply(result.itr, reducer); ! ! } /** --- 406,444 ---- } ! // /** ! // * @todo if unisolated or isolated at the read-commit level, then the ! // * operation really needs to be broken down by partition or perhaps by ! // * index segment leaf so that we do not have too much latency during a ! // * read (this could be done for rangeQuery as well). ! // * ! // * @todo if fully isolated, then there is no problem running map. ! // * ! // * @todo The definition of a row is different if using a key formed from the ! // * column name, application key, and timestamp. ! // * ! // * @todo For at least GOM we need to deserialize rows from byte[]s, so we ! // * need to have the (de-)serializer to the application level value on ! // * hand. ! // */ ! // public void map(long tx, String name, byte[] fromKey, byte[] toKey, ! // IMapOp op) throws InterruptedException, ExecutionException { ! // ! // if( name == null ) throw new IllegalArgumentException(); ! // ! // if (tx == 0L) ! // throw new UnsupportedOperationException( ! // "Unisolated context not allowed"); ! // ! // int flags = 0; // @todo set to deliver keys + values for map op. ! // ! // RangeQueryResult result = (RangeQueryResult) txService.submit( ! // new RangeQueryTask(tx, name, fromKey, toKey, flags)).get(); ! // ! // // @todo resolve the reducer service. ! // IReducer reducer = null; ! // ! // op.apply(result.itr, reducer); ! // ! // } /** *************** *** 630,641 **** private final byte[] fromKey; private final byte[] toKey; ! private final boolean countOnly; ! private final boolean keysOnly; ! private final boolean valuesOnly; private final ITx tx; ! public RangeQueryTask(long startTime, String name, byte[] fromKey, byte[] toKey, ! boolean countOnly, boolean keysOnly, boolean valuesOnly) { assert startTime != 0L; --- 629,638 ---- private final byte[] fromKey; private final byte[] toKey; ! private final int flags; private final ITx tx; ! public RangeQueryTask(long startTime, String name, byte[] fromKey, ! byte[] toKey, int flags) { assert startTime != 0L; *************** *** 664,670 **** this.fromKey = fromKey; this.toKey = toKey; ! this.countOnly = countOnly; ! this.keysOnly = keysOnly; ! this.valuesOnly = valuesOnly; } --- 661,665 ---- this.fromKey = fromKey; this.toKey = toKey; ! this.flags = flags; } *************** *** 681,684 **** --- 676,681 ---- final int count = ndx.rangeCount(fromKey, toKey); + + boolean countOnly = false; final IEntryIterator itr = (countOnly ? null : ndx.rangeIterator( *************** *** 686,690 **** return new RangeQueryResult(count, itr, tx.getStartTimestamp(), ! name, fromKey, toKey, countOnly, keysOnly, valuesOnly); } --- 683,687 ---- return new RangeQueryResult(count, itr, tx.getStartTimestamp(), ! name, fromKey, toKey, flags); } *************** *** 709,719 **** public final byte[] fromKey; public final byte[] toKey; ! public final boolean countOnly; ! public final boolean keysOnly; ! public final boolean valuesOnly; public RangeQueryResult(int count, IEntryIterator itr, long startTime, String name, ! byte[] fromKey, byte[] toKey, boolean countOnly, ! boolean keysOnly, boolean valuesOnly) { this.count = count; --- 706,713 ---- public final byte[] fromKey; public final byte[] toKey; ! public final int flags; public RangeQueryResult(int count, IEntryIterator itr, long startTime, String name, ! byte[] fromKey, byte[] toKey, int flags) { this.count = count; *************** *** 725,731 **** this.fromKey = fromKey; this.toKey = toKey; ! this.countOnly = countOnly; ! this.keysOnly = keysOnly; ! this.valuesOnly = valuesOnly; } --- 719,723 ---- this.fromKey = fromKey; this.toKey = toKey; ! this.flags = flags; } Index: IDataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/IDataService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** IDataService.java 15 Mar 2007 16:11:11 -0000 1.1 --- IDataService.java 17 Mar 2007 23:14:58 -0000 1.2 *************** *** 174,180 **** * @param fromKey * @param toKey ! * @param countOnly ! * @param keysOnly ! * @param valuesOnly * * @exception InterruptedException --- 174,178 ---- * @param fromKey * @param toKey ! * @param flags (@todo define flags: count yes/no, keys yes/no, values yes/no) * * @exception InterruptedException *************** *** 191,203 **** */ public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, ! byte[] toKey, boolean countOnly, boolean keysOnly, ! boolean valuesOnly) throws InterruptedException, ExecutionException; ! /** ! * Maps an operation against all key/value pairs in a key range, writing the ! * result onto a reducer service. ! */ ! public void map(long tx, String name, byte[] fromKey, byte[] toKey, ! IMapOp op) throws InterruptedException, ExecutionException; } --- 189,200 ---- */ public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, ! byte[] toKey, int flags) throws InterruptedException, ExecutionException; ! // /** ! // * Execute a map worker task against all key/value pairs in a key range, ! // * writing the results onto N partitions of an intermediate file. ! // */ ! // public void map(long tx, String name, byte[] fromKey, byte[] toKey, ! // IMapOp op) throws InterruptedException, ExecutionException; } Index: DataServiceClient.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/DataServiceClient.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** DataServiceClient.java 15 Mar 2007 16:11:12 -0000 1.1 --- DataServiceClient.java 17 Mar 2007 23:14:58 -0000 1.2 *************** *** 116,125 **** } ! public void map(long tx, String name, byte[] fromKey, byte[] toKey, IMapOp op) throws InterruptedException, ExecutionException { ! delegate.map(tx, name, fromKey, toKey, op); ! } ! public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, byte[] toKey, boolean countOnly, boolean keysOnly, boolean valuesOnly) throws InterruptedException, ExecutionException { ! return delegate.rangeQuery(tx, name, fromKey, toKey, countOnly, keysOnly, valuesOnly); } --- 116,125 ---- } ! // public void map(long tx, String name, byte[] fromKey, byte[] toKey, IMapOp op) throws InterruptedException, ExecutionException { ! // delegate.map(tx, name, fromKey, toKey, op); ! // } ! public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, byte[] toKey, int flags) throws InterruptedException, ExecutionException { ! return delegate.rangeQuery(tx, name, fromKey, toKey, flags); } *************** *** 132,137 **** } ! public void commit(long tx) { ! delegate.commit(tx); } --- 132,137 ---- } ! public long commit(long tx) { ! return delegate.commit(tx); } --- NEW FILE: package.html --- <html> <head> <title>Services</title> </head> <body> <p> This package provides implementations of services (data service, transaction manager service, metadata locator service). </p> </body> </html> Index: TransactionService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/TransactionService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TransactionService.java 15 Mar 2007 16:11:11 -0000 1.1 --- TransactionService.java 17 Mar 2007 23:14:58 -0000 1.2 *************** *** 98,102 **** * and index segments? */ ! public class TransactionService implements ITransactionManager { /** --- 98,102 ---- * and index segments? */ ! public class TransactionService implements ITransactionManager, IServiceShutdown { /** --- NEW FILE: MetadataService.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 17, 2007 */ package com.bigdata.service; import java.net.InetSocketAddress; import java.util.Properties; import com.bigdata.journal.Journal; import com.bigdata.scaleup.MasterJournal; import com.bigdata.scaleup.MetadataIndex; /** * Implementation of a metadata service for a named scale-out index. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public class MetadataService implements IMetadataService, IServiceShutdown { /** * The name of the index. */ protected final String name; /** * The name of the journal on which the metadata index is stored. * * @todo support two-tier metadata index and reconcile with * {@link MetadataIndex} and {@link MasterJournal}. */ protected final Journal journal; protected MetadataIndex mdi; public MetadataService(Properties properties) { /* * @todo setup/resolve the journal and the metadata index on * the journal. */ throw new UnsupportedOperationException(); } public static void main(String[] args) { } public InetSocketAddress getDataService(byte[] key) { // TODO Auto-generated method stub return null; } public int getEntryCount() { // TODO Auto-generated method stub return 0; } public int rangeCount(byte[] fromKey,byte[] toKey) { // TODO Auto-generated method stub return 0; } public void shutdown() { // TODO Auto-generated method stub } public void shutdownNow() { // TODO Auto-generated method stub } } Index: EmbeddedDataService.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/EmbeddedDataService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** EmbeddedDataService.java 15 Mar 2007 16:11:10 -0000 1.1 --- EmbeddedDataService.java 17 Mar 2007 23:14:58 -0000 1.2 *************** *** 69,73 **** * using delegation patterns). */ ! public class EmbeddedDataService implements IDataService { private final DataService delegate; --- 69,73 ---- * using delegation patterns). */ ! public class EmbeddedDataService implements IDataService, IServiceShutdown { private final DataService delegate; *************** *** 112,121 **** } ! public void map(long tx, String name, byte[] fromKey, byte[] toKey, IMapOp op) throws InterruptedException, ExecutionException { ! delegate.map(tx, name, fromKey, toKey, op); ! } ! public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, byte[] toKey, boolean countOnly, boolean keysOnly, boolean valuesOnly) throws InterruptedException, ExecutionException { ! return delegate.rangeQuery(tx, name, fromKey, toKey, countOnly, keysOnly, valuesOnly); } --- 112,121 ---- } ! // public void map(long tx, String name, byte[] fromKey, byte[] toKey, IMapOp op) throws InterruptedException, ExecutionException { ! // delegate.map(tx, name, fromKey, toKey, op); ! // } ! public RangeQueryResult rangeQuery(long tx, String name, byte[] fromKey, byte[] toKey, int flags) throws InterruptedException, ExecutionException { ! return delegate.rangeQuery(tx, name, fromKey, toKey, flags); } *************** *** 128,133 **** } ! public void commit(long tx) { ! delegate.commit(tx); } --- 128,133 ---- } ! public long commit(long tx) { ! return delegate.commit(tx); } Index: IMapOp.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/service/IMapOp.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** IMapOp.java 15 Mar 2007 16:11:12 -0000 1.1 --- IMapOp.java 17 Mar 2007 23:14:58 -0000 1.2 *************** *** 1,5 **** package com.bigdata.service; ! import com.bigdata.objndx.IEntryIterator; /** --- 1,5 ---- package com.bigdata.service; ! import com.bigdata.objndx.BytesUtil; /** *************** *** 12,29 **** /** ! * The name of the reducer service. */ ! public String getReducer(); /** ! * Apply the operator to the key/value stream, writing results onto the ! * reducer service. * ! * @param src ! * The key/value stream. ! * @param reducer ! * The reducer service. */ ! public void apply(IEntryIterator src,IReducer reducer); ! } \ No newline at end of file --- 12,55 ---- /** ! * The hash function used to assign map output keys to reduce tasks. This is ! * normally <code>hash(key) mod R</code>, where hash(key) is ! * {@link BytesUtil#hash(byte[])} and R is the #of reduce tasks. ! * ! * @param key ! * @return */ ! public int reduceHashCode(byte[] key); ! ! /** ! * Each map task will be presented with key-value pairs. When the source is ! * an index, the key-value pairs will be presented in key order. The map ! * operator is responsible for writting zero or more key value pairs on the ! * output sink. Those key value pairs will be assigned to N different reduce ! * tasks by applying the user-defined hash function to the output key. ! * ! * @param key ! * The input key. ! * @param val ! * The input value. ! * @param out ! * The output sink. ! */ ! public void map(byte[] key, byte[] val, IOutput out); /** ! * Each reduce task will be presented with a series of key-value pairs in ! * key order. However, the keys will be distributed across the N reduce ! * tasks by the used defined hash function, so this is NOT a total ordering ! * over the intermediate keys. * ! * @param key ! * @param val */ ! public void reduce(byte[] key, byte[] val); ! public static interface IOutput { ! ! public void append(byte[] key,byte[] val); ! ! } ! } --- NEW FILE: IServiceShutdown.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 17, 2007 */ package com.bigdata.service; /** * API for service shutdown. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ * * @todo reconcile with jini startup/shutdown. */ public interface IServiceShutdown { /** * The service will no longer accept new requests, but existing requests * will be processed (sychronous). * * @return Once the service has finished processing pending requests. */ public void shutdown(); /** * The service will no longer accept new requests and will make a best * effort attempt to terminate all existing requests and return ASAP. * * @return Once the service has shutdown. */ public void shutdownNow(); } --- NEW FILE: MapReduceService.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 17, 2007 */ package com.bigdata.service; import java.util.Properties; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import com.bigdata.util.concurrent.DaemonThreadFactory; /** * A draft implementation of a map/reduce service. Map/reduce is a functional * programming style in which a program is broken down into a <i>map</i> and a * <i>reduce</i> operation. Those operations are trivially parallelized and * distributed across one or more worker tasks on available hosts. There will be * M map tasks and N reduce tasks for each map/reduce operation. * <p> * The inputs to the map operation are key-value pairs. Logicall, each map * operation processes a key-value pair, writing a set of intermediate key-value * pairs as its output. The outputs are automatically partitioned into N local * temporary files (one per reduce task) using a user-defined hash function. * <p> * Each reduce task reads from the M distinct files (one per map operation) * having data for the intermediate key-value partition assigned to that reduce * task. The keys in those partitions are essentially random since they are * assigned to partitions by the (user-defined) hash function. Before execution, * the reduce task inputs are placed into a total order, e.g., using a sort or * bulk index load. The reduce task is then run on the total order, writing its * outputs onto a single output file. There will be one such output file per * reduce task. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ * * @todo the reduce output is written to an arbitrary sink. common uses are * probably a NOP (the N merged indices are the outputs) a 2nd stage * reduce (producing a total merge of the intermediate values) or various * kinds of local flat files. * * @todo the master needs to keep track of the state each worker task on each * host. * * @todo the master needs a queue for input jobs and should expose an HTML * monitor for job status, as well as email notification of results. * * @todo The Apache Hadoop project provides a MapReduce implementation. Explore * possible ways in which an integration could be achieved. * * @todo support "debugging" using a version that executes tasks for a single * partition of subset of the data. */ public class MapReduceService implements IServiceShutdown { /** * Queue of executing jobs. */ final protected ExecutorService jobService = Executors .newSingleThreadExecutor(DaemonThreadFactory .defaultThreadFactory()); /** * @todo define lookup of the bigdata instance against which the named * indices will be resolved. * * @param properties */ public MapReduceService(Properties properties) { } public void shutdown() { jobService.shutdown(); } public void shutdownNow() { jobService.shutdownNow(); } /** * Submit a job. * @param m * @param n * @param tx * @param name * @param fromKey * @param toKey * @param op */ public Future submit(int m, int n, long tx, String name, byte[] fromKey, byte[] toKey, IMapOp op) { return jobService.submit(new Job(m,n,tx,name,fromKey,toKey,op)); } /** * A scheduled map/reduce task. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public static class Job implements Callable<Object> { final int m; final int n; final long tx; final String name; final byte[] fromKey; final byte[] toKey; final IMapOp op; /* * @todo status for each of the M map tasks and N reduce tasks, * including where those tasks are running. */ final Object status = null; /* * @todo these of course need to be remote tasks that are tracked with * a heartbeat. */ final ExecutorService mapService; final ExecutorService reduceService; /** * A map/reduce job whose inputs are a key range of a named index. * * @param m * @param n * @param tx * @param fromKey * @param toKey * @param op * * @todo verify named index exists. * * @todo by passing in the isolation level rather than the start time * (or 0L) we can use the most recent data and do not retain old * resources (journals and index segments) however, the downside * is that you can create a multi-job transaction. by passing in * the tx time, you can create a multi-job transaction if that is * desired. * * @todo supporting unisolated reads requires traversal under concurrent * modification, e.g., cursor restart after each "batch" read. */ public Job(int m, int n, long tx, String name, byte[] fromKey, byte[] toKey, IMapOp op) { assert m > 0; assert n > 0; assert name != null; this.m = m; this.n = n; this.tx = tx; this.name = name; this.fromKey = fromKey; this.toKey = toKey; this.op = op; mapService = Executors.newFixedThreadPool(m, DaemonThreadFactory.defaultThreadFactory()); reduceService = Executors.newFixedThreadPool(n, DaemonThreadFactory.defaultThreadFactory()); } /** * Resolve the metadata service for the named index. * * @param name * The index name. * * @return The metadata service for the named index. * * @todo change the return type. */ protected IMetadataService getMetadataService(String name) { throw new UnsupportedOperationException(); } /** * @todo assuming the data is in indices, partition the input data. this * can be done with high accuracy by doing a rangeCount for the * index, and then requesting the M-1 keys at the index entry * positions that evenly divide the key space. since M can be * rather large, we can start tasks as we go. if we have to * restart a task, we can get its (approximate) key range by * issuing new queries against the index. * * @todo an alternative would assign map tasks to the hosts on which the * data resides (this can apply with index inputs or with flat * file inputs). if we are aware of the network topology, then we * can assign the map tasks to hosts "near" the hosts on which the * data resides. * * @todo start up M map tasks; there is no point starting reduce tasks * until the map tasks have completed since we need to provide a * total ordering into the reduce tasks. */ public Object call() throws Exception { IMetadataService mds = getMetadataService(name); final int nentries = mds.rangeCount(fromKey,toKey); return null; } } /** * A worker for a map task. * * @todo buffer the intermediate results for each map task on M buffers * (indexed by the user-defined hash of the intermediate key); the * buffers are btrees multiplexed on a journal; on the overflow, evict * one index segment per btree resulting in N index segments per map * task (so that the reduce task will start with each input partition * in sorted order); * * @todo the map task should be run on the data service (i.e., define a * procedure and submit it to the data service). * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public static class MapWorker implements Callable<Object> { protected final long tx; protected final String name; protected final byte[] fromKey; protected final byte[] toKey; protected final IMapOp op; protected final int taskId; protected final int numReduce; public MapWorker(long tx, String name, byte[] fromKey, byte[] toKey, IMapOp op, int taskId, int numReduce) { this.tx = tx; this.name = name; this.fromKey = fromKey; this.toKey = toKey; this.op = op; this.taskId = taskId; this.numReduce = numReduce; } public Object call() throws Exception { // TODO Auto-generated method stub return null; } } /** * A worker for a reduce task. * * @todo reduce tasks may begin running as soon as intermediate output files * become available; the input to each reduce task is M index segments * (one per map task); the data in those segments are already in * sorted order, but they need to be placed into a total sorted order * before running the reduce task. Given the tools on hand, the * easiest way to achieve a total order over the reduce task inputs is * to build a partitioned index. Since each reduce task input is * already in sorted order, we can build the total sorted order by * reading from the M input segments in parallel (an M-way merge). * Since M can be quite high and the keys are randomly distributed * across the input by the user-defined hash function, this merge * operation will need to scale up to a large fan-in (100,000+). * * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public static class ReduceWorker implements Callable<Object> { public Object call() throws Exception { // TODO Auto-generated method stub return null; } } } --- NEW FILE: IMetadataService.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 17, 2007 */ package com.bigdata.service; import java.net.InetSocketAddress; /** * A metadata service for a named index. * <p> * The metadata service maintains locator information for the data service * instances responsible for each partition in the named index. Partitions * are automatically split when they overflow (~200M) and joined when they * underflow (~50M). * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public interface IMetadataService { /** * The approximate number of entries in the index (non-transactional). */ public int getEntryCount(); /** * The approximate number of entries in the index for the specified key * range (non-transactional). * * @param fromKey * @param toKey * @return */ public int rangeCount(byte[] fromKey,byte[] toKey); /** * Return the address of the {@link IDataService} that has current primary * responsibility for the index partition that includes the specified key. * * @param key * The key. * * @return The locator for the {@link IDataService} with primary * responsibility for the index partition in which that key would be * located. * * @todo return primary and secondary data service locators with lease. * * @todo return primary and secondary data service locators with lease for * the index partition that would contain the key plus some number of * index partitions surrounding that partition. */ public InetSocketAddress getDataService(byte[] key); } |
From: Bryan T. <tho...@us...> - 2007-03-18 12:59:37
|
Update of /cvsroot/cweb/bigdata In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12438 Modified Files: .cvsignore Added Files: build.xml build.properties Log Message: A little more work setting up for the services architecture. Index: .cvsignore =================================================================== RCS file: /cvsroot/cweb/bigdata/.cvsignore,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** .cvsignore 8 Mar 2007 18:14:05 -0000 1.11 --- .cvsignore 17 Mar 2007 23:14:59 -0000 1.12 *************** *** 11,12 **** --- 11,17 ---- test_* com.bigdata.journal.StressTestConcurrent.comparison.csv + bigdata.jar + run.bat + ant-build + ant-deploy + log --- NEW FILE: build.xml --- <project name="bigdata" default="deploy" basedir="."> <property file="build.properties" /> <path id="build.classpath"> <fileset dir="${bigdata.dir}/lib"> <include name="*.jar" /> </fileset> </path> <path id="runtime.classpath"> <pathelement location="${build.dir}" /> <path refid="build.classpath" /> </path> <target name="clean"> <delete dir="${build.dir}" /> </target> <target name="prepare"> <mkdir dir="${build.dir}" /> </target> <!-- @todo drop dbcache, extser, concurrent. --> <!-- FIXME Use JARs for other packages, NOT compiled classes. This is especially important because of the licenses on some packages. --> <target name="compile" depends="prepare"> <mkdir dir="${build.dir}" /> <javac destdir="${build.dir}" classpathref="build.classpath" debug="on"> <src path="${cweb.dir}/commons/src/java" /> <src path="${cweb.dir}/concurrent/src/java" /> <src path="${cweb.dir}/dbcache/src/java" /> <src path="${cweb.dir}/extser/src/java" /> <src path="${cweb.dir}/junit-ext/src/java" /> <src path="${cweb.dir}/lgpl-utils/src/java" /> <src path="${bigdata.dir}/src/java" /> <src path="${bigdata.dir}/src/test" /> </javac> <!-- <copy toDir="${build.dir}/classes"> <fileset dir="${src.dir}"> <exclude name="**/*.java"/> </fileset> </copy> --> </target> <target name="jar" depends="compile"> <jar destfile="${jar.name}"> <fileset dir="${build.dir}" /> <manifest> <attribute name="Main-Class" value="org/CognitiveWeb/bigdata/TestServiceDiscovery" /> </manifest> </jar> </target> <!-- Prepare a bigdata deployment. you need to copy the deployment directory to an HTTP server so that downloadable code can be resolved for activatable services, e.g., assuming: codebase=http://proto.cognitiveweb.org/maven-repository/bigdata/jars/ do: scp ant-deploy/* br...@pr...:/home/groups/c/cw/cweb/maven-repository/bigdata/jars then verfify that you can see the resources in a web browser at that codebase URL (e.g., the files all have the right permissions on the server). You MUST then unarchive bigdata.jar into this directory so that the actual class files themselves are available for download (only .class files are downloaded, NOT JARs). Finally, the code that will expose services with downloadable code MUST set -Djava.rmi.server.codebase=http://proto.cognitiveweb.org/maven-repository/bigdata/jars/ in order for the correct codebase property to be communicated to clients that will then download code from that HTTP server. Note: the trailing '/' is REQUIRED in your codebase or the generated URLs will NOT resolve correctly. See http://java.sun.com/j2se/1.4.2/docs/guide/rmi/javarmiproperties.html for some guidence. Among other things, it suggests: -Djava.rmi.server.logCalls=true as an aid to debuging. Also try setting -Dcom.sun.jini.reggie.proxy.debug=1 for the client, e.g., the service browser. Also see: http://www.adtmag.com/java/articleold.aspx?id=1159 for some (very good) guidence in debugging jini services. See http://archives.java.sun.com/cgi-bin/wa?A2=ind0512&L=jini-users&P=R391&I=-3 for instructions on setting up an "download jar" (dljar) ANT task that can make life much simpler (one supposes). @todo you need to install the client and server deployments on machines that will run clients or servers respectively. --> <!-- @todo sign jars? version code --> <!-- drop unit tests from the jar (except for testing); --> <!-- @todo break into client deploy (minimum startup for clients) and server deploy (minimum startup for servers) plus a deployment for downloadedable code for activatable services (which is how the services will actually run). Note that (ICU is only required for clients). --> <!-- write a test to validate the pre- and post- conditions for deployment. --> <!-- add properties to build.properties for the http server location, failover sites, etc. --> <target name="deploy" depends="jar"> <copy toDir="${deploy.dir}"> <fileset dir="${bigdata.dir}/lib"> <!-- do not deploy the jini jars for download - the client must have them available locally, e.g., from the jini starter kit. --> <exclude name="reggie.jar" /> <exclude name="sun-util.jar" /> <exclude name="jini-core.jar" /> <exclude name="jini-ext.jar" /> <exclude name="**/*.dll" /> <exclude name="**/*.so" /> </fileset> <fileset dir="${bigdata.dir}/LEGAL"> </fileset> <fileset file="${jar.name}/"> </fileset> </copy> </target> </project> --- NEW FILE: build.properties --- cweb.dir=.. bigdata.dir=. build.dir=ant-build deploy.dir=ant-deploy codebase=http://proto.cognitiveweb.org/maven-repository/bigdata/jars/ jar.name=bigdata.jar |
From: Bryan T. <tho...@us...> - 2007-03-18 12:59:37
|
Update of /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12438/src/test/org/CognitiveWeb/bigdata/jini Modified Files: TestServiceDiscovery.java TestServer.java Log Message: A little more work setting up for the services architecture. Index: TestServiceDiscovery.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini/TestServiceDiscovery.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TestServiceDiscovery.java 26 Aug 2006 19:30:21 -0000 1.1 --- TestServiceDiscovery.java 17 Mar 2007 23:14:59 -0000 1.2 *************** *** 50,54 **** import java.io.Serializable; import java.net.InetAddress; - import java.rmi.RMISecurityManager; import junit.framework.TestCase; --- 50,53 ---- *************** *** 64,68 **** * </p> * <p> ! * jini MUST be running. * </p> * --- 63,84 ---- * </p> * <p> ! * Note: jini MUST be running. You can get the jini starter kit and install it ! * to get jini running. ! * </p> ! * <p> ! * Note: The registered service will NOT show up correctly in the Service ! * Browser (you will see "Unknown service") unless you set the codebase when ! * executing this test class and the .class files are available for download ! * from the codebase URL. I jump start the tests myself using ! * </p> ! * ! * <pre> ! * -Djava.security.policy=policy.all -Djava.rmi.server.codebase=http://proto.cognitiveweb.org/maven-repository/bigdata/jars/ ! * </pre> ! * ! * <p> ! * which presuposes that the required class files are on that server available ! * for download. The security policy is overlax, but you do need to grant some ! * privledges in order to partitipate in discovery, etc. * </p> * *************** *** 74,90 **** * client remain that minimal. Right now I am also using jini-ext.jar, * reggie.jar and sun-util.jar to run this test. jini-ext.jar is the big ! * one at over 1M. ! * ! * @todo The registered service is not showing up in the Service Browser because ! * the classes required to deserialize an instance of the service item ! * (including our MyStatus and other Entry classes) and the service proxy ! * itself are not being deployed to a directory where reggie can be used ! * to download those classes to the Service Browser. Solving this problem ! * will also solve the above configuration issue and will make it possible ! * to bundle fewer JARs with bigdata. For this workstation IIS must be ! * running and the class files (or JAR) must be copied to ! * "C:\Inetpub\wwwroot". The -Djava.rmi.server.codebase=... property must ! * be set for the JARs to be downloaded from that server. I am not sure ! * yet what needs to be done to get the Service Browser working smoothly. * * @todo Figure out how to divide the service into a proxy and a remote object. --- 90,95 ---- * client remain that minimal. Right now I am also using jini-ext.jar, * reggie.jar and sun-util.jar to run this test. jini-ext.jar is the big ! * one at over 1M. (this can be facilitated using the dljar ant task and ! * specifing jini-core as the target platform.) * * @todo Figure out how to divide the service into a proxy and a remote object. *************** *** 97,100 **** --- 102,113 ---- * e.g., there is no locking, but we can handle all of that. * + * @see http://archives.java.sun.com/cgi-bin/wa?A2=ind0311&L=jini-users&F=&S=&P=7182 + * for a description of policy files and + * http://www.dancres.org/cottage/jini-start-examples-2_1.zip for the + * policy files described.<br> + * When testing standalone with only trusted code and NO downloaded code, + * it is reasonable to consider running the test code using + * "-Djava.security.policy=policy.all" so that you can get things moving. + * * @version $Id$ * @author <a href="mailto:tho...@us...">Bryan Thompson *************** *** 114,121 **** */ ! public void test_serviceDiscover() throws IOException, ClassNotFoundException { ! // install suitable security manager ! System.setSecurityManager(new RMISecurityManager()); /* --- 127,137 ---- */ ! public void test_serviceDiscovery() throws IOException, ClassNotFoundException { ! /* ! * install suitable security manager. this is required before the ! * application can download code. ! */ ! System.setSecurityManager(new SecurityManager()); /* *************** *** 134,137 **** --- 150,154 ---- // Find the service registrar (unicast protocol). final int timeout = 4*1000; // seconds. + System.err.println("hostname: "+hostname); LookupLocator lookupLocator = new LookupLocator("jini://"+hostname); ServiceRegistrar serviceRegistrar = lookupLocator.getRegistrar( timeout ); *************** *** 201,204 **** --- 218,229 ---- { + /** + * + */ + private static final long serialVersionUID = -920558820563934297L; + + /** + * De-serialization constructor (required). + */ public TestServerImpl() { log.info("Created: "+this); *************** *** 210,213 **** --- 235,256 ---- } + + public static void main(String[] args) throws Exception { + + TestServiceDiscovery test = new TestServiceDiscovery(); + + test.setUp(); + + try { + + test.test_serviceDiscovery(); + + } finally { + + test.tearDown(); + + } + + } } Index: TestServer.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/org/CognitiveWeb/bigdata/jini/TestServer.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TestServer.java 26 Aug 2006 19:30:21 -0000 1.1 --- TestServer.java 17 Mar 2007 23:14:59 -0000 1.2 *************** *** 48,51 **** --- 48,52 ---- import java.io.IOException; + import java.rmi.RMISecurityManager; import java.rmi.RemoteException; *************** *** 108,122 **** /* ! * Generate a ServiceID ourselves. This makes it easier to register ! * the same service against multiple lookup services. * ! * @todo If you want to restart (or re-register) the same service, ! * then you need to read the serviceID from some persistent ! * location. If you are using activation, then the service can be ! * remotely started using its serviceID which takes that ! * responsibility out of your hands. When using activation, you will ! * only create a serviceID once when you install the service onto ! * some component and activity takes responsiblity for starting the ! * service on demand. */ Uuid uuid = UuidFactory.generate(); --- 109,122 ---- /* ! * Generate a ServiceID ourselves. This makes it easier to register the ! * same service against multiple lookup services. * ! * @todo If you want to restart (or re-register) the same service, then ! * you need to read the serviceID from some persistent location. If you ! * are using activation, then the service can be remotely started using ! * its serviceID which takes that responsibility out of your hands. When ! * using activation, you will only create a serviceID once when you ! * install the service onto some component and activition takes ! * responsiblity for starting the service on demand. */ Uuid uuid = UuidFactory.generate(); *************** *** 197,205 **** "locality", "stateOrProvince", "postalCode", "country"), ! new ServiceInfo("BigTable", // product or package name "SYSTAP,LLC", // manufacturer ! "CognitiveWeb", // vendor "0.1-beta", // version ! "model", // model "serial#" // serialNumber ) }); --- 197,205 ---- "locality", "stateOrProvince", "postalCode", "country"), ! new ServiceInfo("bigdata", // product or package name "SYSTAP,LLC", // manufacturer ! "SYSTAP,LLC", // vendor "0.1-beta", // version ! "bigdata", // model "serial#" // serialNumber ) }); *************** *** 305,310 **** /** ! * {@link Status} is abstract so a service basically needs to provide their own ! * concrete implementation. * * @version $Id$ --- 305,310 ---- /** ! * {@link Status} is abstract so a service basically needs to provide their ! * own concrete implementation. * * @version $Id$ *************** *** 313,316 **** --- 313,321 ---- public static class MyStatus extends Status { + /** + * + */ + private static final long serialVersionUID = 3431522046169284463L; + /* * Note: public fields are required and must be Serializable. *************** *** 330,346 **** /** ! * {@link ServiceType}is abstract so a service basically needs to ! * provide their own concrete implementation. This class does not ! * support icons (always returns null for ! * {@link ServiceType#getIcon(int)}. See {@link java.beans.BeanInfo} ! * for how to interpret and support the getIcon() method. * * @version $Id$ ! * @author <a href="mailto:tho...@us...">Bryan ! * Thompson </a> */ public static class MyServiceType extends ServiceType { public String displayName; public String shortDescription; --- 335,356 ---- /** ! * {@link ServiceType} is abstract so a service basically needs to provide ! * their own concrete implementation. This class does not support icons ! * (always returns null for {@link ServiceType#getIcon(int)}. See ! * {@link java.beans.BeanInfo} for how to interpret and support the ! * getIcon() method. * * @version $Id$ ! * @author <a href="mailto:tho...@us...">Bryan Thompson ! * </a> */ public static class MyServiceType extends ServiceType { + /** + * + */ + private static final long serialVersionUID = -2088608425852657477L; + public String displayName; public String shortDescription; |
From: Bryan T. <tho...@us...> - 2007-03-18 11:59:51
|
Update of /cvsroot/cweb/bigdata/src/resources/logging In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12438/src/resources/logging Modified Files: log4j.properties Log Message: A little more work setting up for the services architecture. Index: log4j.properties =================================================================== RCS file: /cvsroot/cweb/bigdata/src/resources/logging/log4j.properties,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** log4j.properties 15 Mar 2007 16:11:15 -0000 1.6 --- log4j.properties 17 Mar 2007 23:14:59 -0000 1.7 *************** *** 16,20 **** log4j.logger.com.bigdata.objndx.IndexSegmentBuilder=INFO log4j.logger.com.bigdata.objndx.AbstractBTreeTestCase=INFO ! log4j.logger.com.bigdata.rdf=DEBUG log4j.appender.dest1=org.apache.log4j.ConsoleAppender --- 16,20 ---- log4j.logger.com.bigdata.objndx.IndexSegmentBuilder=INFO log4j.logger.com.bigdata.objndx.AbstractBTreeTestCase=INFO ! log4j.logger.org.CognitiveWeb.bigdata.jini=DEBUG log4j.appender.dest1=org.apache.log4j.ConsoleAppender |
From: Bryan T. <tho...@us...> - 2007-03-18 11:59:48
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/scaleout In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12426/src/java/com/bigdata/scaleout Log Message: Directory /cvsroot/cweb/bigdata/src/java/com/bigdata/scaleout added to the repository |
From: Bryan T. <tho...@us...> - 2007-03-18 11:59:47
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/scaleout In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv12438/src/java/com/bigdata/scaleout Added Files: package.html Log Message: A little more work setting up for the services architecture. --- NEW FILE: package.html --- <html> <head> <title>Scale Out</title> </head> <body> <p> This package provides a distributed database architecture with partitioned indices. </p> </body> </html> |
From: Bryan T. <tho...@us...> - 2007-03-15 16:13:12
|
Update of /cvsroot/cweb/bigdata/src/architecture In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv11937/src/architecture Removed Files: BigData.emx Log Message: model file was renamed. --- BigData.emx DELETED --- |
From: Bryan T. <tho...@us...> - 2007-03-15 16:11:58
|
Update of /cvsroot/cweb/bigdata-rdf/src/test/com/bigdata/rdf/rio In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv11466/src/test/com/bigdata/rdf/rio Modified Files: TestRioIntegration.java Log Message: Refactoring to define service apis (data service, transaction manager service) and some approximate implementations of those services (not supporting service discovery, network protocol, or service robustness). Copied in the UML model so that it will actually get committed to CVS.... Index: TestRioIntegration.java =================================================================== RCS file: /cvsroot/cweb/bigdata-rdf/src/test/com/bigdata/rdf/rio/TestRioIntegration.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** TestRioIntegration.java 11 Mar 2007 11:43:33 -0000 1.17 --- TestRioIntegration.java 15 Mar 2007 16:11:54 -0000 1.18 *************** *** 54,58 **** import com.bigdata.rdf.AbstractTripleStoreTestCase; import com.bigdata.rdf.TripleStore; - import com.bigdata.scaleup.MasterJournal.Options; /** --- 54,57 ---- *************** *** 155,159 **** long total_stmts = 0; ! long begin = System.currentTimeMillis(); for ( int i = 0; i < resources.length; i++ ) { --- 154,158 ---- long total_stmts = 0; ! // long begin = System.currentTimeMillis(); for ( int i = 0; i < resources.length; i++ ) { |
From: Bryan T. <tho...@us...> - 2007-03-15 16:11:58
|
Update of /cvsroot/cweb/bigdata-rdf/src/java/com/bigdata/rdf In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv11466/src/java/com/bigdata/rdf Modified Files: TripleStore.java Log Message: Refactoring to define service apis (data service, transaction manager service) and some approximate implementations of those services (not supporting service discovery, network protocol, or service robustness). Copied in the UML model so that it will actually get committed to CVS.... Index: TripleStore.java =================================================================== RCS file: /cvsroot/cweb/bigdata-rdf/src/java/com/bigdata/rdf/TripleStore.java,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** TripleStore.java 11 Mar 2007 11:43:32 -0000 1.22 --- TripleStore.java 15 Mar 2007 16:11:54 -0000 1.23 *************** *** 1059,1063 **** public void overflow() { ! System.err.println("*** Overflow *** "); --- 1059,1063 ---- public void overflow() { ! System.err.println("*** Overflow *** "); *************** *** 1073,1076 **** --- 1073,1077 ---- this.counter = null; + // invoke the base behavior on the super class. super.overflow(); |
From: Bryan T. <tho...@us...> - 2007-03-15 16:11:58
|
Update of /cvsroot/cweb/bigdata/src/test/com/bigdata/isolation In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv10595/src/test/com/bigdata/isolation Modified Files: TestIsolatedBTree.java Log Message: Refactoring to define service apis (data service, transaction manager service) and some approximate implementations of those services (not supporting service discovery, network protocol, or service robustness). Copied in the UML model so that it will actually get committed to CVS.... Index: TestIsolatedBTree.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/test/com/bigdata/isolation/TestIsolatedBTree.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TestIsolatedBTree.java 12 Mar 2007 18:06:12 -0000 1.4 --- TestIsolatedBTree.java 15 Mar 2007 16:11:14 -0000 1.5 *************** *** 50,54 **** import com.bigdata.journal.TestTx; import com.bigdata.objndx.AbstractBTreeTestCase; - import com.bigdata.objndx.BTree; import com.bigdata.objndx.BTreeMetadata; import com.bigdata.objndx.IBatchOp; --- 50,53 ---- |
From: Bryan T. <tho...@us...> - 2007-03-15 16:11:52
|
Update of /cvsroot/cweb/bigdata/src/resources/logging In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv10595/src/resources/logging Modified Files: log4j.properties Log Message: Refactoring to define service apis (data service, transaction manager service) and some approximate implementations of those services (not supporting service discovery, network protocol, or service robustness). Copied in the UML model so that it will actually get committed to CVS.... Index: log4j.properties =================================================================== RCS file: /cvsroot/cweb/bigdata/src/resources/logging/log4j.properties,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** log4j.properties 17 Feb 2007 03:08:00 -0000 1.5 --- log4j.properties 15 Mar 2007 16:11:15 -0000 1.6 *************** *** 9,13 **** # Loggers. ! log4j.logger.com.bigdata=INFO log4j.logger.com.bigdata.objndx=WARN #log4j.logger.com.bigdata.objndx.AbstractBTree=INFO --- 9,15 ---- # Loggers. ! log4j.logger.com.bigdata=WARN ! # Note: logging here can significantly impact transaction throughput! ! #log4j.logger.com.bigdata.journal.ResourceManager=INFO log4j.logger.com.bigdata.objndx=WARN #log4j.logger.com.bigdata.objndx.AbstractBTree=INFO |
From: Bryan T. <tho...@us...> - 2007-03-15 16:11:47
|
Update of /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv10595/src/java/com/bigdata/objndx Modified Files: IndexSegmentBuilder.java BTree.java IndexSegmentFileStore.java AbstractBTree.java BatchContains.java NodeSerializer.java BTreeMetadata.java ISimpleBTree.java BatchLookup.java IndexSegment.java Added Files: IReadOnlyBatchOp.java Log Message: Refactoring to define service apis (data service, transaction manager service) and some approximate implementations of those services (not supporting service discovery, network protocol, or service robustness). Copied in the UML model so that it will actually get committed to CVS.... Index: IndexSegmentFileStore.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegmentFileStore.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** IndexSegmentFileStore.java 8 Mar 2007 18:14:05 -0000 1.10 --- IndexSegmentFileStore.java 15 Mar 2007 16:11:08 -0000 1.11 *************** *** 41,45 **** * of the queue does not require any IOs. */ ! protected final ByteBuffer buf_nodes; /** --- 41,45 ---- * of the queue does not require any IOs. */ ! private ByteBuffer buf_nodes; /** *************** *** 51,65 **** * The random access file used to read the index segment. */ ! protected final RandomAccessFile raf; /** * A read-only view of the metadata record for the index segment. */ ! protected final IndexSegmentMetadata metadata; /** * A read-only view of the extension metadata record for the index segment. */ ! protected final IndexSegmentExtensionMetadata extensionMetadata; /** --- 51,65 ---- * The random access file used to read the index segment. */ ! private RandomAccessFile raf; /** * A read-only view of the metadata record for the index segment. */ ! protected IndexSegmentMetadata metadata; /** * A read-only view of the extension metadata record for the index segment. */ ! protected IndexSegmentExtensionMetadata extensionMetadata; /** *************** *** 87,90 **** --- 87,108 ---- this.file = file; + reopen(); + + } + + /** + * Re-open a closed store. This operation should succeed if the backing file + * is still accessible. + * + * @exception IllegalStateException + * if the store is not closed. + * + * @see #close() + */ + public void reopen() { + + if (open) + throw new IllegalStateException("Already open."); + if (!file.exists()) { *************** *** 132,136 **** } ! /** * Load the {@link IndexSegment} or derived class from the store. The --- 150,154 ---- } ! /** * Load the {@link IndexSegment} or derived class from the store. The *************** *** 196,199 **** --- 214,222 ---- } + /** + * Closes the file and releases the internal buffers and metadata records. + * This operation may be reversed by {@link #reopen()} as long as the + * backing file remains available. + */ public void close() { *************** *** 204,207 **** --- 227,240 ---- raf.close(); + + raf = null; + + buf_nodes = null; + + metadata = null; + + extensionMetadata = null; + + open = false; } catch (IOException ex) { *************** *** 211,216 **** } - open = false; - } --- 244,247 ---- --- NEW FILE: IReadOnlyBatchOp.java --- /** The Notice below must appear in each file of the Source Code of any copy you distribute of the Licensed Product. Contributors to any Modifications may add their own copyright notices to identify their own contributions. License: The contents of this file are subject to the CognitiveWeb Open Source License Version 1.1 (the License). You may not copy or use this file, in either source code or executable form, except in compliance with the License. You may obtain a copy of the License from http://www.CognitiveWeb.org/legal/license/ Software distributed under the License is distributed on an AS IS basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyrights: Portions created by or assigned to CognitiveWeb are Copyright (c) 2003-2003 CognitiveWeb. All Rights Reserved. Contact information for CognitiveWeb is available at http://www.CognitiveWeb.org Portions Copyright (c) 2002-2003 Bryan Thompson. Acknowledgements: Special thanks to the developers of the Jabber Open Source License 1.0 (JOSL), from which this License was derived. This License contains terms that differ from JOSL. Special thanks to the CognitiveWeb Open Source Contributors for their suggestions and support of the Cognitive Web. Modifications: */ /* * Created on Mar 14, 2007 */ package com.bigdata.objndx; /** * A batch operation that does not allow mutation operations. * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public interface IReadOnlyBatchOp extends IBatchOp { } Index: IndexSegmentBuilder.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegmentBuilder.java,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** IndexSegmentBuilder.java 8 Mar 2007 18:14:05 -0000 1.27 --- IndexSegmentBuilder.java 15 Mar 2007 16:11:08 -0000 1.28 *************** *** 67,70 **** --- 67,71 ---- import com.bigdata.isolation.Value; import com.bigdata.journal.Journal; + import com.bigdata.journal.ResourceManager; import com.bigdata.journal.TemporaryRawStore; import com.bigdata.objndx.IndexSegment.CustomAddressSerializer; *************** *** 789,792 **** --- 790,796 ---- + "MB"+", rate="+fpf.format(mbPerSec)+"MB/sec"); + // report event + ResourceManager.buildIndexSegment(null/* name */, + outFile.toString(), plan.nentries, elapsed, md.length); } catch (Throwable ex) { Index: ISimpleBTree.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/ISimpleBTree.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ISimpleBTree.java 15 Feb 2007 01:34:22 -0000 1.2 --- ISimpleBTree.java 15 Mar 2007 16:11:08 -0000 1.3 *************** *** 57,65 **** * @version $Id$ * ! * FIXME re-define this interface for byte[] keys ! * ! * @todo implement a strongly typed subclass of BTree using a default ! * {@link KeyBuilder} and use that to run the various test suites that ! * have a dependency on int keys. * * @see KeyBuilder, which may be used to encode one or more primitive data type --- 57,61 ---- * @version $Id$ * ! * @todo re-define this interface for byte[] keys * * @see KeyBuilder, which may be used to encode one or more primitive data type Index: BTreeMetadata.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/BTreeMetadata.java,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** BTreeMetadata.java 11 Mar 2007 11:41:44 -0000 1.13 --- BTreeMetadata.java 15 Mar 2007 16:11:08 -0000 1.14 *************** *** 88,91 **** --- 88,93 ---- protected BTreeMetadata(BTree btree) { + assert btree.isOpen(); + this.addrRoot = btree.root.getIdentity(); Index: BatchContains.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/BatchContains.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** BatchContains.java 15 Feb 2007 01:34:22 -0000 1.2 --- BatchContains.java 15 Mar 2007 16:11:08 -0000 1.3 *************** *** 57,61 **** * @version $Id$ */ ! public class BatchContains implements IBatchOp { /** --- 57,61 ---- * @version $Id$ */ ! public class BatchContains implements IReadOnlyBatchOp { /** Index: BatchLookup.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/BatchLookup.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** BatchLookup.java 15 Feb 2007 01:34:22 -0000 1.3 --- BatchLookup.java 15 Mar 2007 16:11:08 -0000 1.4 *************** *** 54,58 **** * @version $Id$ */ ! public class BatchLookup implements IBatchOp { /** --- 54,58 ---- * @version $Id$ */ ! public class BatchLookup implements IReadOnlyBatchOp { /** Index: IndexSegment.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/IndexSegment.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** IndexSegment.java 8 Mar 2007 18:14:05 -0000 1.17 --- IndexSegment.java 15 Mar 2007 16:11:08 -0000 1.18 *************** *** 8,11 **** --- 8,12 ---- import com.bigdata.cache.HardReferenceQueue; + import com.bigdata.journal.ResourceManager; import com.bigdata.rawstore.Addr; import com.bigdata.rawstore.Bytes; *************** *** 36,41 **** * Type safe reference to the backing store. */ ! final protected IndexSegmentFileStore fileStore; ! /** * An optional bloom filter that will be used to filter point tests. Since --- 37,42 ---- * Type safe reference to the backing store. */ ! protected final IndexSegmentFileStore fileStore; ! /** * An optional bloom filter that will be used to filter point tests. Since *************** *** 44,94 **** * structures. */ ! final it.unimi.dsi.mg4j.util.BloomFilter bloomFilter; ! /** ! * Text of a message used in exceptions for mutation operations on the ! * index segment. */ ! final protected static String MSG_READ_ONLY = "Read-only index"; public int getBranchingFactor() { ! return fileStore.metadata.branchingFactor; ! } public int getHeight() { ! return fileStore.metadata.height; ! } public int getLeafCount() { ! return fileStore.metadata.nleaves; ! } public int getNodeCount() { ! return fileStore.metadata.nnodes; ! } public int getEntryCount() { return fileStore.metadata.nentries; ! } ! public IndexSegment(IndexSegmentFileStore fileStore ) { ! this(fileStore, new HardReferenceQueue<PO>( new DefaultEvictionListener(), BTree.DEFAULT_HARD_REF_QUEUE_CAPACITY, BTree.DEFAULT_HARD_REF_QUEUE_SCAN)); ! } ! /** * Open a read-only index segment. --- 45,109 ---- * structures. */ ! it.unimi.dsi.mg4j.util.BloomFilter bloomFilter; ! /** ! * Text of a message used in exceptions for mutation operations on the index ! * segment. */ ! final protected transient static String MSG_READ_ONLY = "Read-only index"; public int getBranchingFactor() { ! ! reopen(); ! return fileStore.metadata.branchingFactor; ! } public int getHeight() { ! ! reopen(); ! return fileStore.metadata.height; ! } public int getLeafCount() { ! ! reopen(); ! return fileStore.metadata.nleaves; ! } public int getNodeCount() { ! ! reopen(); ! return fileStore.metadata.nnodes; ! } public int getEntryCount() { + reopen(); + return fileStore.metadata.nentries; ! } ! public IndexSegment(IndexSegmentFileStore fileStore) { ! this(fileStore, new HardReferenceQueue<PO>( new DefaultEvictionListener(), BTree.DEFAULT_HARD_REF_QUEUE_CAPACITY, BTree.DEFAULT_HARD_REF_QUEUE_SCAN)); ! ! // report on the event. ! ResourceManager.openIndexSegment(null/* name */, fileStore.getFile() ! .toString(), fileStore.size()); ! } ! /** * Open a read-only index segment. *************** *** 124,139 **** // Type-safe reference to the backing store. this.fileStore = (IndexSegmentFileStore) fileStore; ! // Read the root node. this.root = readNodeOrLeaf(fileStore.metadata.addrRoot); ! if( fileStore.metadata.addrBloom == 0L ) { ! /* * No bloom filter. */ ! this.bloomFilter = null; ! } else { --- 139,201 ---- // Type-safe reference to the backing store. this.fileStore = (IndexSegmentFileStore) fileStore; ! ! _open(); ! ! } ! ! /** ! * Extended to also close the backing file. ! */ ! public void close() { ! ! if (root == null) { ! ! throw new IllegalStateException("Already closed."); ! ! } ! ! // close the backing file. ! fileStore.close(); ! ! // release the optional bloom filter. ! bloomFilter = null; ! ! // release buffers and hard reference to the root node. ! super.close(); ! ! // report event. ! ResourceManager.closeIndexSegment(fileStore.getFile().toString()); ! ! } ! ! /** ! * Re-opens the backing file. ! */ ! protected void reopen() { ! ! if (root == null) { ! ! // reopen the file. ! fileStore.reopen(); ! ! _open(); ! ! } ! ! } ! ! private void _open() { ! // Read the root node. this.root = readNodeOrLeaf(fileStore.metadata.addrRoot); ! if (fileStore.metadata.addrBloom == 0L) { ! /* * No bloom filter. */ ! this.bloomFilter = null; ! } else { *************** *** 151,270 **** } - - } - - } ! public void close() { ! ! fileStore.close(); ! ! } ! ! // /** ! // * Overrides the base class to use the optional bloom filter when present. ! // * ! // * @todo Verify that the bloom filter is safe for concurrent readers ! // * ! // * FIXME restore use of the bloom filter once I update the api to byte[]s. ! // * ! // * FIXME use the bloom filter for the batch lookup api as well. ! // */ ! // public Object lookup(Object key) { ! // ! // if (key == null) { ! // ! // throw new IllegalArgumentException(); ! // ! // } ! // ! // Object key2; ! // if(stride > 1) { ! // /* ! // * When the stride is greater than one the application needs to ! // * provide an array parameter anyway so you do not need to copy ! // * anything. ! // */ ! // key2 = key; ! // } else { ! // /* ! // * unautobox the key. When unboxing a key, we need to allocate a new ! // * buffer each time in order to support concurrent readers. ! // */ ! // key2 = ArrayType.alloc(keyType, 1, stride); ! // unbox(key,key2); ! // } ! // ! // if( bloomFilter != null && ! containsKey(key2)) { ! // ! // /* ! // * If the bloom filter reports that the key does not exist then we ! // * always believe it. ! // */ ! // ! // counters.nbloomRejects++; ! // ! // return null; ! // ! // } ! // ! // /* ! // * Either there is no bloom filter or the bloom filter believes that the ! // * key exists. Either way we now lookup the entry in the btree. Again, ! // * we allocate temporary arrays in order to support concurrent readers. ! // */ ! // ! // final Object[] values = new Object[1]; ! // ! // /* ! // * use the super class implementation since we already tested the bloom ! // * filter. ! // */ ! // super.lookup(1,key2,values); ! // ! // return values[0]; ! // ! // } ! ! /** ! * Operation is not supported. ! */ ! public void insert(int ntuples, Object keys, Object[] values) { - throw new UnsupportedOperationException(); - } ! /** ! * Operation is not supported. */ - public void remove(int ntuples, Object keys, Object[] values) { - - throw new UnsupportedOperationException(); - - } - - // /** - // * Used to unbox an application key into a supplied buffer. - // * - // * @param src - // * The application key (Integer, Long, etc). - // * @param dst - // * A polymorphic array with room for a single key. - // */ - // private void unbox(Object src,Object dst) { - // assert stride == 1; - // switch(keyType) { - // case BYTE: ((byte[])dst)[0] = ((Byte)src).byteValue(); break; - // case SHORT: ((short[])dst)[0] = ((Short)src).shortValue(); break; - // case CHAR: ((char[])dst)[0] = ((Character)src).charValue(); break; - // case INT: ((int[])dst)[0] = ((Integer)src).intValue(); break; - // case LONG: ((long[])dst)[0] = ((Long)src).longValue(); break; - // case FLOAT: ((float[])dst)[0] = ((Float)src).floatValue(); break; - // case DOUBLE: ((double[])dst)[0] = ((Double)src).doubleValue(); break; - // case OBJECT: ((Object[])dst)[0] = src; break; - // default: throw new UnsupportedOperationException(); - // } - // } /** --- 213,224 ---- } ! } } ! /* ! * bloom filter support. */ /** *************** *** 275,280 **** * * @return True if the bloom filter believes that the key is present in the ! * index. When true, you must still test the key to verify that it ! * is, in fact, present in the index. When false, you do NOT need to * test the index. * --- 229,234 ---- * * @return True if the bloom filter believes that the key is present in the ! * index. When true, you MUST still test the key to verify that it ! * is, in fact, present in the index. When false, you SHOULD NOT * test the index. * *************** *** 284,293 **** final protected boolean containsKey(byte[] key) { assert bloomFilter != null; ! return bloomFilter.contains(key); ! } /** * Operation is disallowed. --- 238,254 ---- final protected boolean containsKey(byte[] key) { + reopen(); + assert bloomFilter != null; ! return bloomFilter.contains(key); ! } + /* + * ISimpleBTree (disallows mutation operations, applies the optional bloom + * filter when present). + */ + /** * Operation is disallowed. *************** *** 307,311 **** } ! /** * Factory for immutable nodes and leaves used by the {@link NodeSerializer}. --- 268,401 ---- } ! ! /** ! * Applies the optional bloom filter if it exists. If the bloom filter ! * reports true, then verifies that the key does in fact exist in the index. ! */ ! public boolean contains(byte[] key) { ! ! if (bloomFilter != null) { ! ! if (!containsKey(key)) { ! ! // rejected by the bloom filter. ! return false; ! ! } ! ! // test the index. ! return super.contains(key); ! ! } ! ! // test the index. ! return super.contains(key); ! ! } ! ! /** ! * Applies the optional bloom filter if it exists. If the bloom filter ! * exists and reports true, then looks up the value for the key in the index ! * (note that the key might not exist in the index since a bloom filter ! * allows false positives). ! */ ! public Object lookup(Object key) { ! ! if (bloomFilter != null) { ! ! byte[] _key; ! ! if (key instanceof byte[]) { ! ! _key = (byte[]) key; ! ! } else { ! _key = unbox(key); ! ! } ! ! if (!containsKey(_key)) { ! ! // rejected by the bloom filter. ! return null; ! ! } ! ! /* ! * Test the index (may be a false positive and we need the value ! * paired to the key in any case). ! */ ! return super.lookup(_key); ! ! } ! ! // test the index. ! return super.lookup(key); ! ! } ! ! /* ! * IBatchBTree (disallows mutation operations, applies optional bloom filter ! * for batch operations). ! */ ! ! /** ! * Disallowed. ! */ ! public void insert(BatchInsert op) { ! ! throw new UnsupportedOperationException(MSG_READ_ONLY); ! ! } ! ! /** ! * Disallowed. ! */ ! public void remove(BatchRemove op) { ! ! throw new UnsupportedOperationException(MSG_READ_ONLY); ! ! } ! ! /** ! * Apply a batch lookup operation. The bloom filter is used iff it is ! * defined. ! */ ! public void lookup(BatchLookup op) { ! ! if( bloomFilter != null ) { ! ! op.apply(this); ! ! } else { ! ! super.lookup(op); ! ! } ! ! } ! ! /** ! * Apply a batch existence test operation. The bloom filter is used iff it ! * is defined. ! */ ! public void contains(BatchContains op) { ! ! if( bloomFilter != null ) { ! ! op.apply(this); ! ! } else { ! ! super.contains(op); ! ! } ! ! } ! ! /* ! * INodeFactory ! */ ! /** * Factory for immutable nodes and leaves used by the {@link NodeSerializer}. *************** *** 314,320 **** public static final INodeFactory INSTANCE = new ImmutableNodeFactory(); ! ! private ImmutableNodeFactory() {} ! public ILeafData allocLeaf(IIndex btree, long addr, int branchingFactor, IKeyBuffer keys, Object[] values) { --- 404,411 ---- public static final INodeFactory INSTANCE = new ImmutableNodeFactory(); ! ! private ImmutableNodeFactory() { ! } ! public ILeafData allocLeaf(IIndex btree, long addr, int branchingFactor, IKeyBuffer keys, Object[] values) { *************** *** 357,362 **** long[] childKeys, int[] childEntryCount) { ! super(btree, addr, branchingFactor, nentries, keys, ! childKeys, childEntryCount); } --- 448,453 ---- long[] childKeys, int[] childEntryCount) { ! super(btree, addr, branchingFactor, nentries, keys, childKeys, ! childEntryCount); } *************** *** 365,385 **** throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object insert(Object key,Object val) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object remove(Object key) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! } ! /** * Immutable leaf throws {@link UnsupportedOperationException} for the --- 456,476 ---- throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object insert(Object key, Object val) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object remove(Object key) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! } ! /** * Immutable leaf throws {@link UnsupportedOperationException} for the *************** *** 402,430 **** protected ImmutableLeaf(AbstractBTree btree, long addr, int branchingFactor, IKeyBuffer keys, Object[] values) { ! super(btree, addr, branchingFactor, keys, values); ! } ! public void delete() { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object insert(Object key,Object val) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object remove(Object key) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } } ! } --- 493,521 ---- protected ImmutableLeaf(AbstractBTree btree, long addr, int branchingFactor, IKeyBuffer keys, Object[] values) { ! super(btree, addr, branchingFactor, keys, values); ! } ! public void delete() { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object insert(Object key, Object val) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } ! public Object remove(Object key) { throw new UnsupportedOperationException(MSG_READ_ONLY); ! } } ! } *************** *** 471,477 **** */ public CustomAddressSerializer() { ! this.offsetNodes = 0; ! } --- 562,568 ---- */ public CustomAddressSerializer() { ! this.offsetNodes = 0; ! } *************** *** 491,511 **** */ public CustomAddressSerializer(long offsetNodes) { ! /* * Note: trim to int (we restrict the maximum size of the segment). */ this.offsetNodes = (int) offsetNodes; ! ! // System.err.println("offsetNodes="+offsetNodes); ! } ! /** ! * This over-estimates the space requirements. */ public int getSize(int n) { ! return Bytes.SIZEOF_LONG * n; ! } --- 582,602 ---- */ public CustomAddressSerializer(long offsetNodes) { ! /* * Note: trim to int (we restrict the maximum size of the segment). */ this.offsetNodes = (int) offsetNodes; ! ! // System.err.println("offsetNodes="+offsetNodes); ! } ! /** ! * This over-estimates the space requirements. */ public int getSize(int n) { ! return Bytes.SIZEOF_LONG * n; ! } *************** *** 514,519 **** * to the conventions of this class. */ ! public void putChildAddresses(DataOutputStream os, long[] childAddr, int nchildren) throws IOException { ! for (int i = 0; i < nchildren; i++) { --- 605,611 ---- * to the conventions of this class. */ ! public void putChildAddresses(DataOutputStream os, long[] childAddr, ! int nchildren) throws IOException { ! for (int i = 0; i < nchildren; i++) { *************** *** 525,549 **** if (addr == 0L) { ! throw new RuntimeException("Child is not persistent: index=" ! + i); } ! // test the low bit. when set this is a node; otherwise a leaf. final boolean isLeaf = (addr & 1) == 0; ! // strip off the low bit. addr >>= 1; ! final int offset = Addr.getOffset(addr); ! final int nbytes = Addr.getByteCount(addr); ! final int adjustedOffset = (isLeaf ? (offset << 1) : ((offset << 1) | 1)); ! // write the adjusted offset (requires decoding). LongPacker.packLong(os, adjustedOffset); ! // write the #of bytes (does not require decoding). LongPacker.packLong(os, nbytes); --- 617,641 ---- if (addr == 0L) { ! throw new RuntimeException( ! "Child is not persistent: index=" + i); } ! // test the low bit. when set this is a node; otherwise a leaf. final boolean isLeaf = (addr & 1) == 0; ! // strip off the low bit. addr >>= 1; ! final int offset = Addr.getOffset(addr); ! final int nbytes = Addr.getByteCount(addr); ! final int adjustedOffset = (isLeaf ? (offset << 1) : ((offset << 1) | 1)); ! // write the adjusted offset (requires decoding). LongPacker.packLong(os, adjustedOffset); ! // write the #of bytes (does not require decoding). LongPacker.packLong(os, nbytes); *************** *** 561,565 **** // check that we know the offset for deserialization. assert offsetNodes > 0; ! for (int i = 0; i < nchildren; i++) { --- 653,657 ---- // check that we know the offset for deserialization. assert offsetNodes > 0; ! for (int i = 0; i < nchildren; i++) { *************** *** 570,582 **** * whether the referent is a node (1) or a leaf (0). */ ! /* * offset (this field must be decoded). */ long v = LongPacker.unpackLong(is); ! assert v <= Integer.MAX_VALUE; ! ! // test the low bit. when set this is a node; otherwise a leaf. final boolean isLeaf = (v & 1) == 0; --- 662,674 ---- * whether the referent is a node (1) or a leaf (0). */ ! /* * offset (this field must be decoded). */ long v = LongPacker.unpackLong(is); ! assert v <= Integer.MAX_VALUE; ! ! // test the low bit. when set this is a node; otherwise a leaf. final boolean isLeaf = (v & 1) == 0; *************** *** 585,598 **** // compute the real offset into the file. ! final int offset = isLeaf? (int)v : (int)v + offsetNodes; ! /* * nbytes (this field does not need any further interpretation). */ ! v = LongPacker.unpackLong(is); ! assert v <= Integer.MAX_VALUE; ! final int nbytes = (int) v; --- 677,690 ---- // compute the real offset into the file. ! final int offset = isLeaf ? (int) v : (int) v + offsetNodes; ! /* * nbytes (this field does not need any further interpretation). */ ! v = LongPacker.unpackLong(is); ! assert v <= Integer.MAX_VALUE; ! final int nbytes = (int) v; *************** *** 601,609 **** */ final long addr = Addr.toLong(nbytes, offset); ! if (addr == 0L) { throw new RuntimeException( ! "Child does not have persistent address: index=" + i); } --- 693,702 ---- */ final long addr = Addr.toLong(nbytes, offset); ! if (addr == 0L) { throw new RuntimeException( ! "Child does not have persistent address: index=" ! + i); } *************** *** 630,650 **** * @return The encoded address. */ ! static public long encode(int nbytes,int offset,boolean isLeaf) { ! long addr = Addr.toLong(nbytes, (int) offset); ! addr <<= 1; // (addr << 1) ! if (!isLeaf) { ! addr |= 1; // addr++; ! } ! return addr; ! } } ! } --- 723,743 ---- * @return The encoded address. */ ! static public long encode(int nbytes, int offset, boolean isLeaf) { ! long addr = Addr.toLong(nbytes, (int) offset); ! addr <<= 1; // (addr << 1) ! if (!isLeaf) { ! addr |= 1; // addr++; ! } ! return addr; ! } } ! } Index: BTree.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/BTree.java,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** BTree.java 12 Mar 2007 18:06:12 -0000 1.38 --- BTree.java 15 Mar 2007 16:11:08 -0000 1.39 *************** *** 482,486 **** * Read the root node of the btree. */ ! this.root = readNodeOrLeaf( metadata.addrRoot ); } --- 482,487 ---- * Read the root node of the btree. */ ! // this.root = readNodeOrLeaf( metadata.addrRoot ); ! reopen(); } *************** *** 503,506 **** --- 504,550 ---- } + + /** + * Uses {@link #handleCommit()} to flush any dirty nodes to the store and + * update the metadata so we can clear the hard reference queue and release + * the hard reference to the root node. {@link #reopen()} is responsible for + * reloading the root node. + */ + public void close() { + + /* + * flush any dirty records, noting the address of the metadata record + * so that we can reload the store. + */ + handleCommit(); + + /* + * this will clear the hard reference cache, release the node serializer + * buffers, and release the hard reference to the root node. + */ + super.close(); + + } + + /** + * Reloads the root node iff it is <code>null</code> (indicating a closed + * index). + * + * @see #close() + */ + protected void reopen() { + + if (root == null) { + + /* + * reload the root node. + */ + + root = readNodeOrLeaf(metadata.addrRoot); + + } + + } + /** * Writes dirty nodes using a post-order traversal that first writes any *************** *** 519,522 **** --- 563,568 ---- */ public long write() { + + assert root != null; // i.e., isOpen(). if (root.dirty) { *************** *** 563,569 **** /** ! * Method returns the metadata record persisted by {@link #write()}. You ! * MUST override this method to return a subclass of {@link BTreeMetadata} ! * in order to persist additional metadata with the btree. * * @return A new metadata object that can be used to restore the btree. --- 609,616 ---- /** ! * Method returns the metadata record persisted by {@link #write()}. ! * <p> ! * Note: In order to persist additional metadata with the btree you MUST ! * override this method to return a subclass of {@link BTreeMetadata}. * * @return A new metadata object that can be used to restore the btree. *************** *** 571,574 **** --- 618,623 ---- protected BTreeMetadata newMetadata() { + assert root != null; // i.e., isOpen(). + return new BTreeMetadata(this); *************** *** 578,591 **** * Handle request for a commit by {@link #write()}ing dirty nodes and * leaves onto the store, writing a new metadata record, and returning the ! * address of that metadata record.< * <p> * Note: In order to avoid needless writes the existing metadata record is ! * always returned iff all of the folowing are true: * <ol> ! * <li> it metadata record is defined (it is not defined when a btree is ! * first created).</li> ! * <li> the root of the btree is NOT dirty </li> ! * <li> the persistent address of the root of the btree is the same as the ! * address record in the metadata record.</li> * </ol> * --- 627,644 ---- * Handle request for a commit by {@link #write()}ing dirty nodes and * leaves onto the store, writing a new metadata record, and returning the ! * address of that metadata record. * <p> * Note: In order to avoid needless writes the existing metadata record is ! * always returned if: * <ol> ! * <li> the metadata record is defined (it is not defined when a btree is ! * first created) -AND- </li> ! * <li> the root of the btree is NOT dirty and the persistent address of the ! * root of the btree is the same as the address record in the metadata ! * record -OR- </li> ! * <li> the root is <code>null</code>, indicating that the index is ! * closed (flushing the index to disk and updating the metadata record is ! * part of the close protocol so we know that the metadata address is ! * current in this case).</li> * </ol> * *************** *** 595,600 **** public long handleCommit() { ! if (metadata != null && !root.isDirty() ! && metadata.addrRoot == root.getIdentity()) { /* --- 648,654 ---- public long handleCommit() { ! if (metadata != null ! && (root == null || !root.dirty ! && metadata.addrRoot == root.getIdentity())) { /* Index: AbstractBTree.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/AbstractBTree.java,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** AbstractBTree.java 12 Mar 2007 18:06:12 -0000 1.19 --- AbstractBTree.java 15 Mar 2007 16:11:08 -0000 1.20 *************** *** 152,158 **** * at which point it is replaced by a node. The root is also replaced each * time copy-on-write triggers a cascade of updates. */ protected AbstractNode root; ! /** * Used to serialize and de-serialize the nodes and leaves of the tree. --- 152,168 ---- * at which point it is replaced by a node. The root is also replaced each * time copy-on-write triggers a cascade of updates. + * <p> + * This hard reference is cleared to <code>null</code> if an index is + * {@link #close() closed}. {@link #getRoot()} automatically uses + * {@link #reopen()} to reload the root so that closed indices may be + * transparently made ready for further use (indices are closed to reduce + * their resource burden, not to make their references invalid). The + * {@link AbstractNode} and derived classes <em>assume</em> that the root + * is non-null. This assumption is valid if {@link #close()} is invoked by + * the application in a manner consistent with the single-threaded contract + * for the {@link AbstractBTree}. */ protected AbstractNode root; ! /** * Used to serialize and de-serialize the nodes and leaves of the tree. *************** *** 161,164 **** --- 171,187 ---- /** + * Count of the #of times that a reference to this {@link AbstractBTree} + * occurs on a {@link HardReferenceQueue}. This field will remain zero(0) + * unless the {@link AbstractBTree} is placed onto a + * {@link HardReferenceQueue} maintained by the application. + * <p> + * Note: <em>DO NOT MODIFY THIS FIELD DIRECTLY</em> -- The journal is + * responsible for setting up the {@link HardReferenceQueue}, updating this + * field, and {@link #close() closing} {@link AbstractBTree}s that are not + * in use. + */ + public int referenceCount = 0; + + /** * Leaves (and nodes) are added to a hard reference queue when they are * created or read from the store. On eviction from the queue a dirty leaf *************** *** 314,318 **** /** ! * The persistence store. */ public IRawStore getStore() { --- 337,431 ---- /** ! * The contract for close is to reduce the resource burden of the index (by ! * discarding buffers) while not rendering the index inoperative. An index ! * that has been {@link #close() closed} MAY be {@link #reopen() reopened} ! * at any time (conditional on the continued availability of the backing ! * store). The index reference remains valid after a {@link #close()}. A ! * closed index is transparently restored by either {@link #getRoot()} or ! * {@link #reopen()}. ! * <p> ! * This implementation clears the hard reference queue (releasing all node ! * references), releases the hard reference to the root node, and releases ! * the buffers on the {@link NodeSerializer} (they will be naturally ! * reallocated on reuse). ! * <p> ! * Note: {@link AbstractBTree} is NOT thread-safe and {@link #close()} MUST ! * be invoked in a context in which there will not be concurrent threads -- ! * the natural choice being the single-threaded commit service on the ! * journal. ! * ! * @exception IllegalStateException ! * if the root is <code>null</code>, indicating that the ! * index is already closed. ! * ! * @exception IllegalStateException ! * if the root is dirty (this implies that this is a mutable ! * btree and there are mutations that have not been written ! * through to the store) ! */ ! public void close() { ! ! if(root==null) { ! ! throw new IllegalStateException("Already closed"); ! ! } ! ! if (root.dirty) { ! ! throw new IllegalStateException("Root node is dirty"); ! ! } ! ! /* ! * Release buffers. ! */ ! nodeSer.close(); ! ! /* ! * Clear the hard reference queue (this will not trigger any writes ! * since we know as a pre-condition that the root node is clean). ! */ ! leafQueue.evictAll(true); ! ! /* ! * Clear the reference to the root node (permits GC). ! */ ! root = null; ! ! } ! ! /** ! * This is part of a {@link #close()}/{@link #reopen()} protocol that may ! * be used to reduce the resource burden of an {@link AbstractBTree}. The ! * implementation must reload the root node of the tree iff {@link #root} is ! * <code>null</code> (indicating that the index has been closed). This ! * method is automatically invoked by a variety of methods that need to ! * ensure that the index is available for use. ! * ! * @see #close() ! * @see #isOpen() ! * @see #getRoot() ! */ ! abstract protected void reopen(); ! ! /** ! * An "open" index has its buffers and root node in place rather than having ! * to reallocate buffers or reload the root node from the store. ! * ! * @return If the index is "open". ! * ! * @see #close() ! * @see #reopen() ! * @see #getRoot() ! */ ! final public boolean isOpen() { ! ! return root != null; ! ! } ! ! /** ! * The backing store. */ public IRawStore getStore() { *************** *** 374,380 **** --- 487,500 ---- * at which point it is replaced by a node. The root is also replaced each * time copy-on-write triggers a cascade of updates. + * <p> + * The hard reference to the root node is cleared if the index is + * {@link #close() closed}. This method automatically {@link #reopen()}s + * the index if it is closed, making it available for use. */ final public AbstractNode getRoot() { + // make sure that the root is defined. + if(root == null) reopen(); + return root; *************** *** 421,425 **** * Each call MAY process more than one tuple. */ ! int nused = root.batchInsert(op); assert nused > 0; --- 541,545 ---- * Each call MAY process more than one tuple. */ ! int nused = getRoot().batchInsert(op); assert nused > 0; *************** *** 469,473 **** * Each call MAY process more than one tuple. */ ! int nused = root.batchLookup(op); assert nused > 0; --- 589,593 ---- * Each call MAY process more than one tuple. */ ! int nused = getRoot().batchLookup(op); assert nused > 0; *************** *** 499,503 **** * Each call MAY process more than one tuple. */ ! int nused = root.batchContains(op); assert nused > 0; --- 619,623 ---- * Each call MAY process more than one tuple. */ ! int nused = getRoot().batchContains(op); assert nused > 0; *************** *** 520,524 **** * Each call MAY process more than one tuple. */ ! int nused = root.batchRemove(op); assert nused > 0; --- 640,644 ---- * Each call MAY process more than one tuple. */ ! int nused = getRoot().batchRemove(op); assert nused > 0; *************** *** 552,556 **** * as soon as I update the test suites. */ ! final private byte[] unbox(Object key) { return keyBuilder.reset().append(((Integer) key).intValue()).getKey(); --- 672,676 ---- * as soon as I update the test suites. */ ! final protected byte[] unbox(Object key) { return keyBuilder.reset().append(((Integer) key).intValue()).getKey(); *************** *** 567,575 **** if (key instanceof byte[]) { ! return root.insert((byte[]) key,value); } else { ! return root.insert( unbox(key), value ); } --- 687,695 ---- if (key instanceof byte[]) { ! return getRoot().insert((byte[]) key,value); } else { ! return getRoot().insert( unbox(key), value ); } *************** *** 586,594 **** if (key instanceof byte[]) { ! return root.lookup((byte[])key); } else { ! return root.lookup(unbox(key)); } --- 706,714 ---- if (key instanceof byte[]) { ! return getRoot().lookup((byte[])key); } else { ! return getRoot().lookup(unbox(key)); } *************** *** 603,607 **** counters.nfinds++; ! return root.contains((byte[])key); } --- 723,727 ---- counters.nfinds++; ! return getRoot().contains((byte[])key); } *************** *** 616,624 **** if (key instanceof byte[]) { ! return root.remove((byte[])key); } else { ! return root.remove(unbox(key)); } --- 736,744 ---- if (key instanceof byte[]) { ! return getRoot().remove((byte[])key); } else { ! return getRoot().remove(unbox(key)); } *************** *** 633,637 **** counters.nindexOf++; ! int index = root.indexOf(key); return index; --- 753,757 ---- counters.nindexOf++; ! int index = getRoot().indexOf(key); return index; *************** *** 649,653 **** counters.ngetKey++; ! return root.keyAt(index); } --- 769,773 ---- counters.ngetKey++; ! return getRoot().keyAt(index); } *************** *** 663,667 **** counters.ngetKey++; ! return root.valueAt(index); } --- 783,787 ---- counters.ngetKey++; ! return getRoot().valueAt(index); } *************** *** 675,679 **** * are non-null) before calling rangeIterator on the root node. */ ! return root.rangeIterator(fromKey, toKey); } --- 795,799 ---- * are non-null) before calling rangeIterator on the root node. */ ! return getRoot().rangeIterator(fromKey, toKey); } *************** *** 681,684 **** --- 801,806 ---- public int rangeCount(byte[] fromKey, byte[] toKey) { + AbstractNode root = getRoot(); + int fromIndex = (fromKey == null ? 0 : root.indexOf(fromKey)); *************** *** 712,716 **** public IEntryIterator entryIterator() { ! return root.entryIterator(); } --- 834,838 ---- public IEntryIterator entryIterator() { ! return getRoot().entryIterator(); } *************** *** 726,730 **** protected Iterator leafIterator() { ! return new Striterator(root.postOrderIterator()) .addFilter(new Filter() { --- 848,852 ---- protected Iterator leafIterator() { ! return new Striterator(getRoot().postOrderIterator()) .addFilter(new Filter() { *************** *** 823,827 **** } ! return root.dump(level, out, 0, true); } --- 945,953 ---- } ! if (root != null) { ! ! return root.dump(level, out, 0, true); ! ! } else return true; } *************** *** 923,926 **** --- 1049,1053 ---- protected void writeNodeRecursive(AbstractNode node) { + assert root != null; // i.e., isOpen(). assert node != null; assert node.dirty; *************** *** 998,1001 **** --- 1125,1129 ---- protected long writeNodeOrLeaf(AbstractNode node) { + assert root != null; // i.e., isOpen(). assert node != null; assert node.btree == this; Index: NodeSerializer.java =================================================================== RCS file: /cvsroot/cweb/bigdata/src/java/com/bigdata/objndx/NodeSerializer.java,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** NodeSerializer.java 6 Mar 2007 20:38:05 -0000 1.33 --- NodeSerializer.java 15 Mar 2007 16:11:08 -0000 1.34 *************** *** 315,318 **** --- 315,320 ---- */ private final ChecksumUtility chk; + + private final int initialBufferCapacity; public IValueSerializer getValueSerializer() { *************** *** 416,419 **** --- 418,423 ---- } + this.initialBufferCapacity = initialBufferCapacity; + this._buf = alloc(initialBufferCapacity); *************** *** 440,443 **** --- 444,465 ---- /** + * Releases any buffers. They will be automatically reallocated if the + * {@link NodeSerializer} is used again. + * + * @todo write tests of this feature, including random closes during the + * {@link NodeSerializer} stress test and with and without record + * compression (the {@link #cbuf} field is not being automatically + * (re-)allocated right now so that will break if we clear the + * buffer). + */ + public void close() { + + _buf = null; + + cbuf = null; + + } + + /** * Allocate a buffer of the stated capacity. * *************** *** 600,604 **** */ public ByteBuffer putNodeOrLeaf(IAbstractNodeData node) { ! if(node instanceof INodeData) { --- 622,626 ---- */ public ByteBuffer putNodeOrLeaf(IAbstractNodeData node) { ! if(node instanceof INodeData) { *************** *** 626,629 **** --- 648,658 ---- public ByteBuffer putNode(INodeData node) { + if( _buf == null ) { + + // the buffer was released so we reallocate it. + _buf = alloc(initialBufferCapacity); + + } + while (true) { *************** *** 643,647 **** private ByteBuffer putNode(ByteBuffer buf, INodeData node) { ! assert buf != null; assert node != null; --- 672,676 ---- private ByteBuffer putNode(ByteBuffer buf, INodeData node) { ! assert buf != null; assert node != null; *************** *** 935,938 **** --- 964,974 ---- public ByteBuffer putLeaf(ILeafData leaf) { + if( _buf == null ) { + + // the buffer was released so we reallocate it. + _buf = alloc(initialBufferCapacity); + + } + while (true) { *************** *** 1362,1366 **** * Buffer for compressed records. */ ! final private ByteBuffer cbuf; /** --- 1398,1402 ---- * Buffer for compressed records. */ ! private ByteBuffer cbuf; /** |