using System; using System.Collections.Generic; using ln.types.btree; using System.Linq; using System.IO; using ln.logging; using ln.objects.catalog; namespace ln.types.odb.ng.index { public class SimpleIndex : Index { BTreeValueList valueIndex = new BTreeValueList(); BTreeValueList reverseIndex = new BTreeValueList(); public SimpleIndex(Path path) : base(path) { } public override IEnumerable GetDocumentIDs(Predicate predicate) { HashSet matchedIDs = new HashSet(); foreach (ODBEntity value in valueIndex.Keys) { if (predicate(value)) foreach (Guid id in valueIndex[value]) matchedIDs.Add(id); } return matchedIDs; } public override void Add(Guid documentID, ODBEntity value) { valueIndex.Add(value, documentID); reverseIndex.Add(documentID, value); } public override void Remove(Guid documentID) { if (reverseIndex.ContainsKey(documentID)) { foreach (ODBEntity value in reverseIndex[documentID].ToArray()) { valueIndex.Remove(value, documentID); } reverseIndex.Remove(documentID); } } public override bool LoadIndex(string basePath, long lastCloseTimestamp) { if (File.Exists(System.IO.Path.Combine(basePath, String.Format("{0}.idx", IndexName)))) using (FileStream fileStream = new FileStream(System.IO.Path.Combine(basePath, String.Format("{0}.idx", IndexName)), FileMode.Open)) { byte[] indexBytes = fileStream.ReadBytes((int)fileStream.Length); Document indexDocument = new Document(indexBytes, 0, indexBytes.Length); long idxLastCloseTimestamp = indexDocument["LastCloseTimestamp"].As(); if (idxLastCloseTimestamp != lastCloseTimestamp) { Logging.Log(LogLevel.WARNING, "Index timestamp {0} is not matching ( {1} != {2} )", IndexName, idxLastCloseTimestamp, lastCloseTimestamp); return false; } else { foreach (ODBEntity key in indexDocument.Keys) { if (key is ODBGuid) { Guid documentID = key.As(); ODBList valueList = indexDocument[key] as ODBList; foreach (ODBEntity value in valueList) { Add(documentID, value); } } } return true; } } return false; } public override bool SaveIndex(string basePath, long lastCloseTimestamp) { Document indexDocument = new Document(); indexDocument["LastCloseTimestamp"] = new ODBLong(lastCloseTimestamp); foreach (Guid documentID in reverseIndex.Keys) { ODBList valueList = new ODBList(); valueList.AddRange(reverseIndex[documentID]); indexDocument[new ODBGuid(documentID)] = valueList; } byte[] indexBytes = indexDocument.GetStorageBytes(); using (FileStream fileStream = new FileStream(System.IO.Path.Combine(basePath, String.Format("{0}.idx", IndexName)), FileMode.Create)) { fileStream.WriteBytes(indexBytes); fileStream.Close(); } return true; } } }