/* * Copyright Aduna (http://www.aduna-software.com/) (c) 2008. * * Licensed under the Aduna BSD-style license. */ package org.openrdf.sail.rdbms.schema; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.List; import java.util.Map; /** * * @author James Leigh */ public class HashTable { private static final int CHUNK_SIZE = 15; private ValueTable table; private PreparedStatement select; private int removedStatementsSinceExpunge; public HashTable(ValueTable table) { super(); this.table = table; } public String getName() { return table.getName(); } public int getBatchSize() { return table.getBatchSize(); } public int getSelectChunkSize() { return CHUNK_SIZE; } public void init() throws SQLException { } public void close() throws SQLException { if (select != null) { select.close(); } table.close(); } public List<Long> maxIds(int shift, int mod) throws SQLException { return table.maxIds(shift, mod); } public void insert(Number id, long hash) throws SQLException, InterruptedException { synchronized (table) { HashBatch batch = (HashBatch)table.getValueBatch(); if (table.isExpired(batch)) { batch = newHashBatch(); table.initBatch(batch); } batch.addBatch(id, hash); table.queue(batch); } } public boolean expungeRemovedStatements(int count, String condition) throws SQLException { removedStatementsSinceExpunge += count; if (condition != null && timeToExpunge()) { boolean removed = table.expunge(condition); removedStatementsSinceExpunge = 0; return removed; } return false; } protected boolean timeToExpunge() { return removedStatementsSinceExpunge > table.size() / 4; } public void optimize() throws SQLException { table.optimize(); } public String toString() { return table.toString(); } public Map<Long, Number> load(Map<Long, Number> hashes) throws SQLException { assert !hashes.isEmpty(); assert hashes.size() <= getSelectChunkSize(); if (select == null) { StringBuilder sb = new StringBuilder(); sb.append("SELECT id, value\nFROM ").append(getName()); sb.append("\nWHERE value IN ("); for (int i = 0, n = getSelectChunkSize(); i < n; i++) { sb.append("?,"); } sb.setCharAt(sb.length() - 1, ')'); select = prepareSelect(sb.toString()); } int p = 0; for (Long hash : hashes.keySet()) { select.setLong(++p, hash); } while (p < getSelectChunkSize()) { select.setNull(++p, Types.BIGINT); } ResultSet rs = select.executeQuery(); try { while (rs.next()) { long id = rs.getLong(1); long hash = rs.getLong(2); hashes.put(hash, id); } } finally { rs.close(); } return hashes; } protected HashBatch newHashBatch() { return new HashBatch(); } protected PreparedStatement prepareSelect(String sql) throws SQLException { return table.getRdbmsTable().prepareStatement(sql); } }