view lucene/src/luan/modules/lucene/LuceneWriter.java @ 544:c5a93767cc5c

lucene overhaul, untested
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 12 Jun 2015 19:11:44 -0600
parents d9df6d6cb927
children ddcd4296107a
line wrap: on
line source

package luan.modules.lucene;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;
import luan.Luan;
import luan.LuanState;
import luan.LuanTable;
import luan.LuanJavaFunction;
import luan.LuanException;


public final class LuceneWriter {
	private final LuceneIndex index;

	LuceneWriter(LuceneIndex index) {
		index.writeLock.lock();
		this.index = index;
	}

	// call in finally block
	void close() {
		index.writeLock.unlock();
	}

	void commit() throws IOException {
		index.writer.commit();
	}

	private Term term(String key,int value) {
		BytesRef br = new BytesRef();
		NumericUtils.intToPrefixCoded(value,0,br);
		return new Term(key,br);
	}

	private Term term(String key,long value) {
		BytesRef br = new BytesRef();
		NumericUtils.longToPrefixCoded(value,0,br);
		return new Term(key,br);
	}

	private Term term(LuanState luan,String key,Object value) throws LuanException {
		if( value instanceof String )
			return new Term( key, (String)value );
		if( value instanceof Integer )
			return term( key, (Integer)value );
		if( value instanceof Long )
			return term( key, (Long)value );
		if( value instanceof Float )
			return term( key, NumericUtils.floatToSortableInt((Float)value) );
		if( value instanceof Double )
			return term( key, NumericUtils.doubleToSortableLong((Double)value) );
		throw luan.exception("invalid value type '"+value.getClass().getSimpleName()+"' for key '"+key+"'");
	}

	public void delete_documents(LuanState luan,LuanTable tblTerms) throws LuanException, IOException {
		List<Term> list = new ArrayList<Term>();
		for( Map.Entry<Object,Object> entry : tblTerms.iterable(luan) ) {
			Object key = entry.getKey();
			Object value = entry.getValue();
			if( !(key instanceof String) )
				throw luan.exception("key must be a string but got "+key.getClass().getSimpleName());
			list.add( term( luan, (String)key, value ) );
		}
		index.writer.deleteDocuments(list.toArray(new Term[list.size()]));
	}

	public void save_document(LuanState luan,LuanTable doc) throws LuanException, IOException {
		if( doc.get(luan,"type")==null )
			throw luan.exception("missing 'type' field");
		Long id = (Long)doc.get(luan,"id");
		if( id == null ) {
			id = index.nextId(luan);
			doc.put(luan,"id",id);
			index.writer.addDocument(index.toLucene(luan,doc));
		} else {
			index.writer.updateDocument( term("id",id), index.toLucene(luan,doc) );
		}
	}

	// luan

	private void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException {
		t.rawPut( method, new LuanJavaFunction(LuceneWriter.class.getMethod(method,parameterTypes),this) );
	}

	LuanTable table() {
		LuanTable tbl = new LuanTable();
		try {
			add( tbl, "save_document", LuanState.class, LuanTable.class );
			add( tbl, "delete_documents", LuanState.class, LuanTable.class );
		} catch(NoSuchMethodException e) {
			throw new RuntimeException(e);
		}
		return tbl;
	}

}