/*
* Copyright (C) 2014 Indeed Inc.
*
* 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.indeed.imhotep.local;
import com.indeed.imhotep.MemoryReservationContext;
import com.indeed.imhotep.api.ImhotepOutOfMemoryException;
public class GroupLookupFactory {
public static GroupLookup create(int maxGroup,
int size,
ImhotepLocalSession session,
MemoryReservationContext memory) throws ImhotepOutOfMemoryException {
final GroupLookup newLookup;
if (maxGroup < 2) { // 8L * ((size + 64) >> 6)
if (!memory.claimMemory(BitSetGroupLookup.calcMemUsageForSize(size))) {
throw new ImhotepOutOfMemoryException();
}
newLookup = new BitSetGroupLookup(session, size);
} else if (maxGroup < 256) {
if (!memory.claimMemory(ByteGroupLookup.calcMemUsageForSize(size))) {
throw new ImhotepOutOfMemoryException();
}
newLookup = new ByteGroupLookup(session, size);
} else if (maxGroup < 65536) {
if (!memory.claimMemory(CharGroupLookup.calcMemUsageForSize(size))) {
throw new ImhotepOutOfMemoryException();
}
newLookup = new CharGroupLookup(session, size);
} else {
if (!memory.claimMemory(IntGroupLookup.calcMemUsageForSize(size))) {
throw new ImhotepOutOfMemoryException();
}
newLookup = new IntGroupLookup(session, size);
}
return newLookup;
}
public static GroupLookup resize(GroupLookup existingGL,
int maxGroup,
MemoryReservationContext memory) throws ImhotepOutOfMemoryException {
final GroupLookup newGL;
if (maxGroup > existingGL.maxGroup()) {
/* need a bigger group */
newGL = create(maxGroup, existingGL.size(), existingGL.getSession(), memory);
} else {
/* maybe the group lookup can be shrunk */
int newMaxgroup = Math.max(maxGroup, existingGL.getNumGroups());
if ((float) newMaxgroup > 0.7f * existingGL.maxGroup()) {
return existingGL;
}
/* try to shrink the GroupLookup */
try {
newGL = create(newMaxgroup, existingGL.size(), existingGL.getSession(), memory);
} catch (ImhotepOutOfMemoryException e) {
return existingGL;
}
}
existingGL.copyInto(newGL);
memory.releaseMemory(existingGL.memoryUsed());
return newGL;
}
}