Update project structure to org.onap.aaf
[aaf/authz.git] / authz-core / src / main / java / org / onap / aaf / authz / local / TextIndex.java
diff --git a/authz-core/src/main/java/org/onap/aaf/authz/local/TextIndex.java b/authz-core/src/main/java/org/onap/aaf/authz/local/TextIndex.java
new file mode 100644 (file)
index 0000000..cb339a4
--- /dev/null
@@ -0,0 +1,253 @@
+/*******************************************************************************\r
+ * ============LICENSE_START====================================================\r
+ * * org.onap.aaf\r
+ * * ===========================================================================\r
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
+ * * ===========================================================================\r
+ * * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * * you may not use this file except in compliance with the License.\r
+ * * You may obtain a copy of the License at\r
+ * * \r
+ *  *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * * \r
+ *  * Unless required by applicable law or agreed to in writing, software\r
+ * * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * * See the License for the specific language governing permissions and\r
+ * * limitations under the License.\r
+ * * ============LICENSE_END====================================================\r
+ * *\r
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * *\r
+ ******************************************************************************/\r
+package org.onap.aaf.authz.local;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.RandomAccessFile;\r
+import java.nio.ByteBuffer;\r
+import java.nio.IntBuffer;\r
+import java.nio.channels.FileChannel;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.LinkedList;\r
+import java.util.List;\r
+\r
+import org.onap.aaf.authz.local.DataFile.Token;\r
+import org.onap.aaf.authz.local.DataFile.Token.Field;\r
+\r
+import org.onap.aaf.inno.env.Env;\r
+import org.onap.aaf.inno.env.TimeTaken;\r
+import org.onap.aaf.inno.env.Trans;\r
+\r
+public class TextIndex {\r
+       private static final int REC_SIZE=8;\r
+       \r
+       private File file;\r
+       private DataFile dataFile=null;\r
+       \r
+       public TextIndex(File theFile) {\r
+               file = theFile;\r
+       }\r
+       \r
+       public void open() throws IOException {\r
+               dataFile = new DataFile(file,"r");\r
+               dataFile.open();\r
+       }\r
+       \r
+       public void close() throws IOException {\r
+               if(dataFile!=null) {dataFile.close();}\r
+       }\r
+\r
+       public int find(Object key, AbsData.Reuse reuse, int offset) throws IOException {\r
+               return find(key,reuse.getTokenData(),reuse.getFieldData(),offset);\r
+       }\r
+       \r
+       public int find(Object key, DataFile.Token dtok, Field df, int offset) throws IOException {\r
+               if(dataFile==null) {throw new IOException("File not opened");}\r
+               long hash = hashToLong(key.hashCode());\r
+               int min=0, max = (int)(dataFile.size()/REC_SIZE);\r
+               Token ttok = dataFile.new Token(REC_SIZE);\r
+               IntBuffer tib = ttok.getIntBuffer();\r
+               long lhash;\r
+               int curr;\r
+               while((max-min)>100) {\r
+                       ttok.pos((curr=(min+(max-min)/2))*REC_SIZE);\r
+                       tib.rewind();\r
+                       lhash = hashToLong(tib.get());\r
+                       if(lhash<hash) {\r
+                               min=curr+1;\r
+                       } else if(lhash>hash) {\r
+                               max=curr-1;\r
+                       } else {\r
+                               min=curr-40;\r
+                               max=curr+40;\r
+                               break;\r
+                       }\r
+               }\r
+               \r
+               List<Integer> entries = new ArrayList<Integer>();\r
+               for(int i=min;i<=max;++i) {\r
+                       ttok.pos(i*REC_SIZE);\r
+                       tib.rewind();\r
+                       lhash = hashToLong(tib.get());\r
+                       if(lhash==hash) {\r
+                               entries.add(tib.get());\r
+                       } else if(lhash>hash) {\r
+                               break;\r
+                       }\r
+               }\r
+               \r
+               for(Integer i : entries) {\r
+                       dtok.pos(i);\r
+                       if(df.at(offset).equals(key)) {\r
+                               return i;\r
+                       }\r
+               }\r
+               return -1;\r
+       }\r
+       \r
+\r
+       /*\r
+        * Have to change Bytes into a Long, to avoid the inevitable signs in the Hash\r
+        */\r
+       private static long hashToLong(int hash) {\r
+               long rv;\r
+               if(hash<0) {\r
+                       rv = 0xFFFFFFFFL & hash;\r
+               } else {\r
+                       rv = hash;\r
+               }\r
+               return rv;\r
+       }\r
+       \r
+       public void create(final Trans trans,final DataFile data, int maxLine, char delim, int fieldOffset, int skipLines) throws IOException {\r
+               RandomAccessFile raf;\r
+               FileChannel fos;\r
+               \r
+               List<Idx> list = new LinkedList<Idx>(); // Some hashcodes will double... DO NOT make a set\r
+               TimeTaken tt2 = trans.start("Open Files", Env.SUB);\r
+               try {\r
+                       raf = new RandomAccessFile(file,"rw");\r
+                       raf.setLength(0L);\r
+                       fos = raf.getChannel();\r
+               } finally {\r
+                       tt2.done();\r
+               }\r
+               \r
+               try {\r
+                       \r
+                       Token t = data.new Token(maxLine);  \r
+                       Field f = t.new Field(delim);\r
+                       \r
+                       int count = 0;\r
+                       if(skipLines>0) {\r
+                               trans.info().log("Skipping",skipLines,"line"+(skipLines==1?" in":"s in"),data.file().getName());\r
+                       }\r
+                       for(int i=0;i<skipLines;++i) {\r
+                               t.nextLine();\r
+                       }\r
+                       tt2 = trans.start("Read", Env.SUB);\r
+                       try {\r
+                               while(t.nextLine()) {\r
+                                       list.add(new Idx(f.at(fieldOffset),t.pos()));\r
+                                       ++count;\r
+                               }\r
+                       } finally {\r
+                               tt2.done();\r
+                       }\r
+                       trans.checkpoint("    Read " + count + " records");\r
+                       tt2 = trans.start("Sort List", Env.SUB);\r
+                       Collections.sort(list);\r
+                       tt2.done();\r
+                       tt2 = trans.start("Write Idx", Env.SUB);\r
+                       try {\r
+                               ByteBuffer bb = ByteBuffer.allocate(8*1024);\r
+                               IntBuffer ib = bb.asIntBuffer();\r
+                               for(Idx idx : list) {\r
+                                       if(!ib.hasRemaining()) {\r
+                                               fos.write(bb);\r
+                                               ib.clear();\r
+                                               bb.rewind();\r
+                                       }\r
+                                       ib.put(idx.hash);\r
+                                       ib.put(idx.pos);\r
+                               }\r
+                               bb.limit(4*ib.position());\r
+                               fos.write(bb);\r
+                       } finally {\r
+                               tt2.done();\r
+                       }\r
+               } finally {\r
+                       fos.close();\r
+                       raf.close();\r
+               }\r
+       }\r
+       \r
+       public class Iter {\r
+               private int idx;\r
+               private Token t;\r
+               private long end;\r
+               private IntBuffer ib;\r
+\r
+\r
+               public Iter() {\r
+                       try {\r
+                               idx = 0;\r
+                               end = dataFile.size();\r
+                               t  = dataFile.new Token(REC_SIZE);\r
+                               ib = t.getIntBuffer();\r
+\r
+                       } catch (IOException e) {\r
+                               end = -1L;\r
+                       }\r
+               }\r
+               \r
+               public int next() {\r
+                       t.pos(idx);\r
+                       ib.clear();\r
+                       ib.get();\r
+                       int rec = ib.get();\r
+                       idx += REC_SIZE;\r
+                       return rec;\r
+               }\r
+\r
+               public boolean hasNext() {\r
+                       return idx<end;\r
+               }\r
+       }\r
+       \r
+       private static class Idx implements Comparable<Idx> {\r
+               public int hash, pos;\r
+               public Idx(Object obj, int pos) {\r
+                       hash = obj.hashCode();\r
+                       this.pos = pos;\r
+               }\r
+               \r
+               @Override\r
+               public int compareTo(Idx ib) {\r
+                       long a = hashToLong(hash);\r
+                       long b = hashToLong(ib.hash);\r
+                       return a>b?1:a<b?-1:0;\r
+               }\r
+\r
+               /* (non-Javadoc)\r
+                * @see java.lang.Object#equals(java.lang.Object)\r
+                */\r
+               @Override\r
+               public boolean equals(Object o) {\r
+                       if(o!=null && o instanceof Idx) {\r
+                               return hash == ((Idx)o).hash;\r
+                       }\r
+                       return false;\r
+               }\r
+\r
+               /* (non-Javadoc)\r
+                * @see java.lang.Object#hashCode()\r
+                */\r
+               @Override\r
+               public int hashCode() {\r
+                       return hash;\r
+               }\r
+       }\r
+}\r