package dmg.util.cdb ; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; public class CdbFileRecord extends CdbGLock implements CdbElementable { private CdbLockable _superLock; private File _dataSource; private Hashtable<String, Object> _table = new Hashtable<>() ; private boolean _exists = true ; private boolean _dataValid; public CdbFileRecord( CdbLockable superLock , File source , boolean create ) throws IOException { super( superLock ) ; _superLock = superLock ; _dataSource = source ; if( create && _dataSource.exists() ) { throw new IllegalArgumentException("DataSource already exists(2)"); } if( ( ! create ) && ( ! _dataSource.exists() ) ) { throw new IllegalArgumentException("DataSource not found"); } if( create ){ FileOutputStream out = new FileOutputStream( _dataSource ) ; out.close() ; } } @Override public synchronized void open( int mode ) throws CdbLockException, InterruptedException { if( ! _exists ) { throw new CdbLockException("Object removed"); } super.open( mode ) ; } public synchronized void addListItem( String attributeName , String itemName ){ addListItem( attributeName , itemName , false ) ; } public synchronized void addListItem( String attributeName , String itemName , boolean unique ){ Object o = _table.get( attributeName ) ; String [] list; if( o == null ){ list = new String[1] ; list[0] = itemName ; _table.put( attributeName , list ) ; }else if( ! ( o instanceof Object [] ) ){ throw new IllegalArgumentException( "Not a list : "+attributeName ) ; }else{ list = (String [])o ; String [] tmp = new String[list.length+1] ; if( unique ){ int i ; for( i = 0 ; ( i < list.length ) && ( ! list[i].equals(itemName) ) ; i++ ) { tmp[i] = list[i]; } if( i < list.length ) { throw new IllegalArgumentException("duplicated entry"); } }else{ System.arraycopy(list, 0, tmp, 0, list.length); } tmp[list.length] = itemName ; _table.put( attributeName , tmp ) ; } } public synchronized void removeListItem( String attributeName , String itemName ){ Object o = _table.get( attributeName ) ; String [] list; if( o == null ){ return ; }else if( ! ( o instanceof Object [] ) ){ throw new IllegalArgumentException( "Not a list : "+attributeName ) ; }else{ list = (String [])o ; if( list.length == 0 ) { return; } int i = 0 ; for( ; ( i < list.length ) && ( ! list[i].equals( itemName ) ) ; i++ ) { } if( i == list.length ) { return; } String [] tmp = new String[list.length-1] ; int l = 0 ; for( int j = 0 ; j < i ; j ++ ) { tmp[l++] = list[j]; } for( int j = (i+1) ; j < list.length ; j++ ) { tmp[l++] = list[j]; } list = tmp ; } _table.put( attributeName , list ) ; } public synchronized void setAttribute( String name , String attribute ){ _table.put( name , attribute ) ; } public synchronized void setAttribute( String name , String [] attribute ){ _table.put( name , attribute ) ; } public void setAttibute( String name , int value ){ _table.put(name , String.valueOf(value)) ; } public synchronized Object getAttribute( String name ){ return _table.get(name) ; } public int getIntAttribute( String key ){ String str = (String)getAttribute( key ) ; if( str == null ) { return 0; } try{ return Integer.parseInt( str ) ; }catch( NumberFormatException eee ){ return 0 ; } } @Override public synchronized void remove(){ _exists = false ; _dataSource.delete() ; } public synchronized String [] getAttributeNames() { int size = _table.size() ; String [] names = new String[size] ; Iterator<String> iterator = _table.keySet().iterator(); for( int i = 0 ; ( i < size ) && (iterator.hasNext()) ; i++ ) { names[i] = iterator.next(); } return names ; } public String toLine(){ StringBuilder sb = new StringBuilder() ; Iterator<String> iterator = _table.keySet().iterator(); for( int i = 0 ; iterator.hasNext(); i++ ){ String key = iterator.next(); Object value = _table.get( key ) ; if( value instanceof String ){ sb.append(key).append('=').append((String)value) ; }else if( value instanceof String [] ){ sb.append(key).append('=') ; String [] values = (String[])value ; for( int j = 0 ; j < values.length ; j++ ){ if( j > 0 ) { sb.append(','); } sb.append(values[j]); } } sb.append(';') ; } return sb.toString() ; } public String toString(){ StringBuilder sb = new StringBuilder() ; Iterator<String> iterator = _table.keySet().iterator(); for( int i = 0 ; iterator.hasNext(); i++ ){ //if( i > 0 )sb.append( ";" ) ; String key = iterator.next(); Object value = _table.get( key ) ; if( value instanceof String ){ sb.append(key).append('=').append((String)value).append('\n') ; }else if( value instanceof String [] ){ sb.append(key).append("=List\n") ; for (String s : (String[])value) { sb.append(s).append('\n'); } } } return sb.toString() ; } public synchronized Enumeration<String> getAttributes(){ return _table.keys() ; } public synchronized void read() throws IOException { BufferedReader reader = new BufferedReader( new FileReader( _dataSource ) ) ; try{ int state = 0 ; String line, name = null , value; Vector<String> vec = null ; while( ( line = reader.readLine() ) != null ){ if( state == 0 ){ int pos = line.indexOf('=') ; if( pos < 0 ) { continue; } name = line.substring(0,pos) ; value = pos == (line.length()-1) ? "" : line.substring(pos+1) ; if( value.equals( "***LIST***" ) ){ state = 1 ; vec = new Vector<>() ; }else{ _table.put( name , value ) ; } }else if( state == 1 ){ if( line.equals( "***LIST***" ) ){ String [] a = new String[vec.size()] ; vec.copyInto( a ) ; _table.put( name , a ) ; state = 0 ; }else{ vec.addElement( line ) ; } } } } finally{ try{ reader.close() ; }catch(Exception ee){} } } public synchronized void write() throws IOException { PrintWriter pw = new PrintWriter( new FileWriter( _dataSource ) ) ; for (Object o1 : _table.keySet()) { String name = (String) o1; Object o = _table.get(name); if (o == null) { } else if (o instanceof String[]) { pw.println(name + "=***LIST***"); for (String s : (String[]) o) { pw.println(s); } pw.println("***LIST***"); } else if (o instanceof String) { pw.println(name + '=' + o); } } pw.close() ; } @Override public void readLockGranted() { // System.out.println( "readLockGranted "+_dataSource ) ; if( ! _dataValid ){ try{ read() ; }catch(Exception eee ){} _dataValid = true ; } } @Override public void writeLockGranted(){ // System.out.println( "writeLockGranted "+_dataSource ) ; if( ! _dataValid ){ try{ read() ; }catch(Exception eee ){} _dataValid = true ; } } @Override public void readLockReleased(){ // System.out.println( "readLockReleased "+_dataSource ) ; } @Override public void writeLockReleased(){ // System.out.println( "writeLockReleased "+_dataSource ) ; if( _exists ) { try { write(); } catch (Exception eee) { } } } @Override public void writeLockAborted(){ // System.out.println( "writeLockAborted "+_dataSource ) ; try{ read() ; }catch(Exception eee ){} } // public String toString(){ // return super.toString() ; // } public static void main( String [] args ) throws Exception { if( args.length < 2 ){ System.out.println( "... read/write <filename>" ) ; System.exit(4) ; } switch (args[0]) { case "read": { CdbFileRecord rec = new CdbFileRecord(null, new File(args[1]), false); long start, opened, fetched, finished; Enumeration<String> e; for (int l = 0; l < 2; l++) { start = System.currentTimeMillis(); rec.open(CdbLockable.WRITE); opened = System.currentTimeMillis(); e = rec.getAttributes(); while (e.hasMoreElements()) { String name = e.nextElement(); Object o = rec.getAttribute(name); if (o == null) { } else if (o instanceof String[]) { // System.out.println( name+"=***LIST***" ) ; // String [] str = (String [] )o ; // for( int i = 0 ; i < str.length ; i++ ) // System.out.println( str[i] ) ; // System.out.println("***LIST***" ) ; } else if (o instanceof String) { // System.out.println( name+"="+o) ; } } fetched = System.currentTimeMillis(); rec.close(CdbLockable.COMMIT); finished = System.currentTimeMillis(); System.out.println("Open : " + (opened - start)); System.out.println("Read : " + (fetched - opened)); System.out.println("Close : " + (finished - fetched)); } break; } case "test": break; case "write": { CdbFileRecord rec = new CdbFileRecord(null, new File(args[1]), true); rec.open(CdbLockable.WRITE); rec.setAttribute("storageGroup", "dst-98"); String[] bfids = new String[2000]; String str; StringBuffer sb; for (int i = 0; i < bfids.length; i++) { sb = new StringBuffer(); str = String.valueOf(i); sb.append('U'); for (int j = 5; j >= str.length(); j--) { sb.append('0'); } sb.append(str); bfids[i] = sb.toString(); } rec.setAttribute("bfids", bfids); rec.close(CdbLockable.COMMIT); break; } } } }