/* * $Id: ChimeraCacheInfo.java,v 1.1 2007-06-19 10:06:33 tigran Exp $ */ package org.dcache.chimera.namespace; import java.io.BufferedReader; import java.io.CharArrayReader; import java.io.CharArrayWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import diskCacheV111.vehicles.CacheStatistics; import org.dcache.chimera.ChimeraFsException; import org.dcache.chimera.FileNotFoundHimeraFsException; import org.dcache.chimera.FsInode; import org.dcache.chimera.posix.Stat; public class ChimeraCacheInfo implements Serializable { /** * */ private static final long serialVersionUID = -2625909340883039244L; private CacheStatistics _cacheStatistics; private final List<String> _cacheLocations = new ArrayList<>(); private CacheFlags _cacheFlags; public static class CacheFlags implements Serializable { private static final long serialVersionUID = -5709322056371005585L; private final Map<String,String> _hash = new HashMap<>(); private final StringBuilder _inputLine = new StringBuilder(); private void addLine(String line) { _inputLine.append(line); } private void commit() { StringTokenizer st = new StringTokenizer(_inputLine.toString(), ";"); while (st.hasMoreTokens()) { String t = st.nextToken(); int l = t.length(); if (l == 0) { continue; } int i = t.indexOf('='); if (i < 0) { _hash.put(t, ""); } else if (i == (l - 1)) { _hash.put(t.substring(0, i), ""); } else if (i > 0) { _hash.put(t.substring(0, i), t.substring(i + 1)); } } } public String get(String key) { return _hash.get(key); } public String remove(String key) { return _hash.remove(key); } public void put(String key, String value) { _hash.put(key, value); } public Set<Map.Entry<String, String>> entrySet() { return _hash.entrySet(); } private String toPnfsString() { StringBuilder sb = new StringBuilder(); int l = 0; sb.append(":"); for (Map.Entry<String, String> entry: _hash.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()) .append(";"); if ((sb.length() - l) > 70) { l = sb.length(); sb.append("\n:"); } } return sb.toString(); } public String toString() { return toPnfsString(); } } public CacheFlags getFlags() { return _cacheFlags; } private void readCacheInfo(BufferedReader file) throws IOException { // // First line is cache statistics // _cacheFlags = new CacheFlags(); String line = file.readLine(); if (line == null) { _cacheStatistics = new CacheStatistics(); return; } _cacheStatistics = new CacheStatistics(line); while ((line = file.readLine()) != null) { if (line.length() == 0) { continue; } if (line.charAt(0) == ':') { if (line.length() > 1) { _cacheFlags.addLine(line.substring(1)); } } else { _cacheLocations.add(line); } } _cacheFlags.commit(); } public void writeCacheInfo(FsInode inode) throws ChimeraFsException { // // currently we accept 1 and 2 but we only write 2. // _cacheStatistics.setVersion(2); CharArrayWriter cw = new CharArrayWriter(); try (PrintWriter pw = new PrintWriter(cw)) { pw.println(_cacheStatistics.toPnfsString()); pw.println(_cacheFlags.toPnfsString()); for (String location : _cacheLocations) { pw.println(location); } } byte[] buff = cw.toString().getBytes(); inode.write(0, buff, 0, buff.length); } public void addCacheLocation(String location) { _cacheLocations.add(location); } public boolean clearCacheLocation(String location) { //Returns true if location was actually in the list return _cacheLocations.remove(location); } public List<String> getCacheLocations() { return _cacheLocations; } public CacheStatistics getCacheStatistics() { return _cacheStatistics; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append(_cacheStatistics.toString()); for (String location: _cacheLocations) { sb.append(" ").append(location); } return sb.toString(); } //XXX should the update method move from CacheStatistics to here? public void setCacheStatistics(CacheStatistics cs) { _cacheStatistics = cs; } public ChimeraCacheInfo(FsInode inode) throws ChimeraFsException, IOException { byte[] buff; int len = 0; try { Stat stat = inode.stat(); buff = new byte[(int)stat.getSize()]; len = inode.read(0, buff, 0, buff.length); }catch(FileNotFoundHimeraFsException fnf) { buff = new byte[0]; } CharArrayReader ca = new CharArrayReader(new String(buff, 0, len).toCharArray()); try (BufferedReader br = new BufferedReader(ca)) { readCacheInfo(br); } } }