Skip to content

Commit

Permalink
chckpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mukunda- committed Aug 31, 2014
1 parent 5046eb1 commit d2a8bc9
Show file tree
Hide file tree
Showing 10 changed files with 658 additions and 171 deletions.
194 changes: 96 additions & 98 deletions src/main/java/com/mukunda/shortid/IDDatabase.java
Expand Up @@ -26,15 +26,15 @@

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.util.ArrayDeque;
import java.sql.ResultSet;
import java.sql.SQLRecoverableException;
import java.sql.SQLTransientException;
import java.util.ArrayList;
import java.util.UUID;

import org.bukkit.Bukkit;


public class IDDatabase extends SQL implements Runnable {

import org.bukkit.scheduler.BukkitRunnable;

public class IDDatabase extends SQL {

private static class Job {
public Object id;
Expand All @@ -58,21 +58,93 @@ public boolean equals( Object other ) {
}
}

private class Resolver extends BukkitRunnable {

private final Job job;

private static final int RETRY_DELAY = 20;

public Resolver( Job job ) {
this.job = job;
}

public void run() {

synchronized( jobProcessingLock ) {

try {

if( job.id instanceof UUID ) {

connect();
byte[] uuidBytes = mashUUID( (UUID)job.id );

insertStatement.setBytes( 1, uuidBytes );
insertStatement.executeUpdate();
selectStatement.setBytes( 1, uuidBytes );
ResultSet result = selectStatement.executeQuery();
result.next();

SID id = new SID( result.getInt(1) );
storage.map( (UUID)job.id, id );

finishedJob(job);

} else if( job.id instanceof SID ) {

rqueryStatement.setInt( 1, ((SID)job.id).getInt() );
ResultSet result = rqueryStatement.executeQuery();

UUID id;
if( result.next() ) {
id = unmashUUID( result.getBytes(1) );
} else {
id = new UUID(0,0);
}
storage.map( id, (SID)job.id );

finishedJob(job);

}
} catch ( SQLTransientException e ) {
// retry in one second
context.getLogger().warning( "SQL query failed. retrying... reason = " + e.getMessage() );
runTaskLaterAsynchronously( context, RETRY_DELAY );
} catch ( SQLRecoverableException e ) {

context.getLogger().warning( "SQL query failed. retrying... reason = " + e.getMessage() );
disconnect();
runTaskLaterAsynchronously( context, RETRY_DELAY );

} catch ( SQLException e ) {
disconnect();
context.getLogger().severe( "SQL encountered a non-recoverable problem: " + e.getMessage() );
context.Crash();
return;
}
}

finishedJob(job);
}
}

private final ShortID context;

private final IDMap storage;
private final ArrayList<Job> jobs;
private final Object jobProcessingLock;

private String table;
private final String table;

private PreparedStatement insertStatement;
private PreparedStatement selectStatement;
private PreparedStatement rqueryStatement;

private boolean stopped = true;


public IDDatabase( IDMap storage, SQLInfo info, String table ) {

public IDDatabase( ShortID context, IDMap storage, SQLInfo info, String table ) {
super(info);

jobProcessingLock = new Object();
this.context = context;
jobs = new ArrayList<Job>();
this.storage = storage;
this.table = table;
Expand All @@ -90,15 +162,7 @@ protected void onConnected() throws SQLException {
rqueryStatement = getConnection().prepareStatement(
"SELECT `uuid` FROM " + table + "WHERE `sid` = ? LIMIT 1" );
}


private synchronized Job waitForWork() throws InterruptedException {
while( jobs.isEmpty() ) {
wait();
}
return jobs.getFirst();
}


private synchronized void finishedJob( Job j ) {
jobs.remove(j);
}
Expand Down Expand Up @@ -126,86 +190,20 @@ private UUID unmashUUID( byte[] bytes ) {
dataH |= ((long)bytes[i])<<(i<<3);
return new UUID( dataH, dataL );
}

private void executeJob( Job job ) throws SQLException {
if( job.id instanceof UUID ) {

connect();
byte[] uuidBytes = mashUUID( (UUID)job.id );

insertStatement.setBytes( 1, uuidBytes );
insertStatement.executeUpdate();
selectStatement.setBytes( 1, uuidBytes );
ResultSet result = selectStatement.executeQuery();
result.next();

SID id = new SID( result.getInt(1) );
storage.map( (UUID)job.id, id );

finishedJob(job);

} else if( job.id instanceof SID ) {

rqueryStatement.setInt( 1, ((SID)job.id).getInt() );
ResultSet result = rqueryStatement.executeQuery();

UUID id;
if( result.next() ) {
id = unmashUUID( result.getBytes(1) );
} else {
id = new UUID(0,0);
}
storage.map( id, (SID)job.id );

finishedJob(job);

} else {
// what do i do
}
}

public void run() {

try {
while( !stop ) {
Job job = waitForWork();

executeJob( job );

}
} catch( InterruptedException e ) {

// we were interrupted..?


}
}

private static class Resolver extends BukkitRunnable {

}


public synchronized void resolve( UUID uuid ) {
if( jobs.contains( uuid ) ) return;
Job job = new Job( uuid );
if( jobs.contains( job ) ) return;
jobs.add( job );

Bukkit.getScheduler()
jobs.add( new Job( uuid ) );
notifyAll();
new Resolver( job ).runTaskAsynchronously( context );
}

public synchronized void resolve( SID sid ) {
if( jobs.contains( sid ) ) return;
jobs.add( new Job( sid ) );
notifyAll();
}

public synchronized void start() {
if( !stopped ) return;
Job job = new Job( sid );
if( jobs.contains( job ) ) return;
jobs.add( new Job( sid ) );

Thread thread = new Thread(this);
}

public synchronized void start() {

}
new Resolver( job ).runTaskAsynchronously( context );
}
}
54 changes: 53 additions & 1 deletion src/main/java/com/mukunda/shortid/IDMap.java
Expand Up @@ -25,27 +25,59 @@
package com.mukunda.shortid;

import java.util.HashMap;
import java.util.HashSet;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

/**
* concurrent mapping between UUIDs and SIDs
*
* @author mukunda
*
*/
public final class IDMap {

private static class EventRunner extends BukkitRunnable {

private final UUID uuid;
private final SID sid;

public EventRunner( UUID uuid, SID sid ) {
this.uuid = uuid;
this.sid = sid;
}

public void run() {
Player player = Bukkit.getPlayer( uuid );
if( player == null ) return; // player is no longer available.

Bukkit.getServer().getPluginManager().callEvent(
new SIDResolvedEvent( player, sid ) );
}
}

private final HashMap<UUID,SID> toSID;
private final HashMap<SID,UUID> toUUID;

private final HashSet<UUID> postEvent;

public IDMap() {
toSID = new HashMap<UUID,SID>();
toUUID = new HashMap<SID,UUID>();
postEvent = new HashSet<UUID>();
}

public synchronized void map( UUID uuid, SID sid ) {
toSID.put( uuid, sid );
toUUID.put( sid, uuid );

if( postEvent.contains( uuid ) ) {
postEvent.remove(uuid);

}
notifyAll();
}

Expand Down Expand Up @@ -74,6 +106,26 @@ public synchronized UUID getWait( SID sid ) throws InterruptedException {
wait();
id = toUUID.get( sid );
}
return toUUID.get( sid );

// catch invalid query result:
if( id.getMostSignificantBits() == 0 &&
id.getLeastSignificantBits() == 0 ) return null;

return id;
}

public synchronized SID postEventWhenResolved( UUID id ) {
// if the table has an SID for a UUID, this returns that SID
//
// otherwise, it sets a flag that will cause an event to be
// generated when this UUID is resolved, and this will return null.
//
SID sid = toSID.get( id );
if( id != null ) {
return sid;
}

postEvent.add( id );
return null;
}
}
39 changes: 0 additions & 39 deletions src/main/java/com/mukunda/shortid/PlayerListener.java

This file was deleted.

18 changes: 17 additions & 1 deletion src/main/java/com/mukunda/shortid/SID.java
Expand Up @@ -25,12 +25,24 @@
package com.mukunda.shortid;

public class SID {
private int id;
private final int id;

public SID( int id ) {
this.id = id;
}

public SID( byte[] bytes ) {
if( bytes.length != 4 ) throw new IllegalArgumentException( "Input must be 4 bytes." );
id = (((int)(bytes[0]))&0xFF) |
((((int)(bytes[1]))&0xFF)<<8) |
((((int)(bytes[2]))&0xFF)<<16) |
((((int)(bytes[3]))&0xFF)<<24);
}

public boolean valid() {
return id != 0;
}

public int getInt() {
return id;
}
Expand All @@ -43,4 +55,8 @@ public boolean equals( Object other ) {
return (other instanceof SID) &&
(id == ((SID)other).id);
}

public String toString() {
return String.format( "%08X", id );
}
}

0 comments on commit d2a8bc9

Please sign in to comment.