
src.it.unimi.dsi.mg4j.index.remote.RemotePrefixMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mg4j Show documentation
Show all versions of mg4j Show documentation
MG4J (Managing Gigabytes for Java) is a free full-text search engine for large document collections written in Java.
The newest version!
package it.unimi.dsi.mg4j.index.remote;
/*
* MG4J: Managing Gigabytes for Java
*
* Copyright (C) 2006-2011 Sebastiano Vigna
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see .
*
*/
import it.unimi.dsi.Util;
import it.unimi.dsi.fastutil.objects.AbstractObject2ObjectFunction;
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction;
import it.unimi.dsi.lang.MutableString;
import it.unimi.dsi.util.Interval;
import it.unimi.dsi.util.Intervals;
import it.unimi.dsi.util.PrefixMap;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.net.SocketAddress;
import org.apache.log4j.Logger;
/** A remote prefix map.
*
* @author Alessandro Arrabito
* @author Sebastiano Vigna
*/
public class RemotePrefixMap extends RemoteTermMap implements PrefixMap, Serializable {
public final static byte GET_INTERVAL = 3;
public final static byte GET_PREFIX = 4;
public final static byte HAS_PREFIXES = 5;
static final long serialVersionUID = 1;
/** Whether the remote map implements {@link PrefixMap#prefixMap()}. */
private Boolean hasPrefixes;
private AbstractObject2ObjectFunction prefixMap;
private Object2ObjectFunction rangeMap;
public RemotePrefixMap( final SocketAddress address, final int size ) {
super( address, size );
}
private void ensureConnection() throws IOException {
if ( remoteConnection == null ) remoteConnection = new RemoteIndexServerConnection( address, IndexServer.GET_PREFIX_MAP );
}
private boolean hasPrefixes() {
if (hasPrefixes == null) {
try {
ensureConnection();
remoteConnection.outputStream.writeByte( RemotePrefixMap.HAS_PREFIXES );
remoteConnection.outputStream.flush();
hasPrefixes = Boolean.valueOf( remoteConnection.inputStream.readBoolean() );
}
catch ( Exception e ) {
throw new RuntimeException( e );
}
}
return hasPrefixes.booleanValue();
}
public static class ServerThread extends it.unimi.dsi.mg4j.index.remote.ServerThread {
private static final boolean DEBUG = false;
private final static Logger LOGGER = Util.getLogger( ServerThread.class );
/** The remoted term map. */
private final PrefixMap extends CharSequence> prefixMap;
public ServerThread( final Socket socket, final PrefixMap extends CharSequence> prefixMap ) throws IOException {
super( socket );
this.prefixMap = prefixMap;
}
public void run() {
try {
final MutableString s = new MutableString();
int command;
Interval interval;
for ( ;; ) {
command = inputStream.readByte();
if ( DEBUG ) LOGGER.debug( "Received remote command: " + command );
switch ( command ) {
case RemoteTermMap.GET_NUMBER:
outputStream.writeLong( prefixMap.getLong( s.readSelfDelimUTF8( (InputStream)inputStream ) ) );
outputStream.flush();
break;
case RemoteTermMap.GET_TERM:
new MutableString( prefixMap.list().get( inputStream.readInt() ) ).writeSelfDelimUTF8( (OutputStream)outputStream );
outputStream.flush();
break;
case RemoteTermMap.HAS_TERMS:
outputStream.writeBoolean( prefixMap.list() != null );
outputStream.flush();
break;
case RemotePrefixMap.GET_INTERVAL:
interval = prefixMap.rangeMap().get( s.readSelfDelimUTF8( (InputStream)inputStream ) );
outputStream.writeInt( interval.left );
outputStream.writeInt( interval.right );
outputStream.flush();
break;
case RemotePrefixMap.GET_PREFIX:
new MutableString( prefixMap.prefixMap().get( Interval.valueOf( inputStream.readInt(), inputStream.readInt() ) ) ).writeSelfDelimUTF8( (OutputStream)outputStream );
outputStream.flush();
break;
case RemotePrefixMap.HAS_PREFIXES:
outputStream.writeBoolean( prefixMap.prefixMap() != null );
outputStream.flush();
break;
default:
LOGGER.error( "Unknown remote command: " + command );
}
}
}
catch ( EOFException e ) {
LOGGER.warn( "The socket has been closed" );
}
catch ( Exception e ) {
LOGGER.fatal( e, e );
}
}
}
public Object2ObjectFunction prefixMap() {
if ( hasPrefixes() && prefixMap == null ) prefixMap = new AbstractObject2ObjectFunction() {
private static final long serialVersionUID = 1L;
public boolean containsKey( Object o ) {
Interval interval = (Interval)o;
return interval != Intervals.EMPTY_INTERVAL && interval.left >= 0 && interval.right < RemotePrefixMap.this.size();
}
public MutableString get( Object o ) {
final Interval interval = (Interval)o;
try {
ensureConnection();
remoteConnection.outputStream.writeByte( RemotePrefixMap.GET_PREFIX );
remoteConnection.outputStream.writeInt( interval.left );
remoteConnection.outputStream.writeInt( interval.right );
remoteConnection.outputStream.flush();
return new MutableString().readSelfDelimUTF8( (InputStream)remoteConnection.inputStream );
}
catch ( Exception e ) {
throw new RuntimeException( e );
}
}
public int size() {
return -1;
}
};
return prefixMap;
}
public Object2ObjectFunction rangeMap() {
if ( rangeMap == null ) rangeMap = new AbstractObject2ObjectFunction() {
private static final long serialVersionUID = 1L;
public boolean containsKey( Object o ) {
return get( o ) != Intervals.EMPTY_INTERVAL;
}
public Interval get( Object o ) {
CharSequence prefix = (CharSequence)o;
try {
ensureConnection();
remoteConnection.outputStream.writeByte( RemotePrefixMap.GET_INTERVAL );
new MutableString( prefix ).writeSelfDelimUTF8( (OutputStream)remoteConnection.outputStream );
remoteConnection.outputStream.flush();
return Interval.valueOf( remoteConnection.inputStream.readInt(), remoteConnection.inputStream.readInt() );
}
catch ( Exception e ) {
throw new RuntimeException( e );
}
}
public int size() {
return -1;
}
};
return rangeMap;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy