| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.psi.impl.cache.impl.id; |
| |
| import com.intellij.openapi.fileTypes.FileType; |
| import com.intellij.openapi.fileTypes.FileTypeRegistry; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.ThreadLocalCachedIntArray; |
| import com.intellij.util.indexing.CustomInputsIndexFileBasedIndexExtension; |
| import com.intellij.util.io.DataExternalizer; |
| import com.intellij.util.io.DataInputOutputUtil; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.io.DataInput; |
| import java.io.DataOutput; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Comparator; |
| |
| public class IdIndexImpl extends IdIndex implements CustomInputsIndexFileBasedIndexExtension<IdIndexEntry> { |
| private static final ThreadLocalCachedIntArray spareBufferLocal = new ThreadLocalCachedIntArray(); |
| private final FileTypeRegistry myFileTypeManager; |
| |
| public IdIndexImpl(FileTypeRegistry manager) { |
| myFileTypeManager = manager; |
| } |
| |
| @Override |
| public int getVersion() { |
| FileType[] types = myFileTypeManager.getRegisteredFileTypes(); |
| Arrays.sort(types, new Comparator<FileType>() { |
| @Override |
| public int compare(FileType o1, FileType o2) { |
| return Comparing.compare(o1.getName(), o2.getName()); |
| } |
| }); |
| |
| int version = super.getVersion(); |
| for(FileType fileType:types) { |
| if (!isIndexable(fileType)) continue; |
| FileTypeIdIndexer indexer = IdIndexers.INSTANCE.forFileType(fileType); |
| if (indexer == null) continue; |
| version = version * 31 + (indexer.getVersion() ^ indexer.getClass().getName().hashCode()); |
| } |
| return version; |
| } |
| |
| @NotNull |
| @Override |
| public DataExternalizer<Collection<IdIndexEntry>> createExternalizer() { |
| return new DataExternalizer<Collection<IdIndexEntry>>() { |
| @Override |
| public void save(@NotNull DataOutput out, @NotNull Collection<IdIndexEntry> value) throws IOException { |
| int size = value.size(); |
| final int[] values = spareBufferLocal.getBuffer(size); |
| int ptr = 0; |
| for(IdIndexEntry ie:value) { |
| values[ptr++] = ie.getWordHashCode(); |
| } |
| Arrays.sort(values, 0, size); |
| DataInputOutputUtil.writeINT(out, size); |
| int prev = 0; |
| for(int i = 0; i < size; ++i) { |
| DataInputOutputUtil.writeLONG(out, (long)values[i] - prev); |
| prev = values[i]; |
| } |
| } |
| |
| @Override |
| public Collection<IdIndexEntry> read(@NotNull DataInput in) throws IOException { |
| int length = DataInputOutputUtil.readINT(in); |
| ArrayList<IdIndexEntry> entries = new ArrayList<IdIndexEntry>(length); |
| int prev = 0; |
| while(length-- > 0) { |
| final int l = (int)(DataInputOutputUtil.readLONG(in) + prev); |
| entries.add(new IdIndexEntry(l)); |
| prev = l; |
| } |
| return entries; |
| } |
| }; |
| } |
| } |