Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Major revision. Using Berkeley DB to store concept and concept
relationship information. No more sorting of vocab files + dedicated Athena file reader. Allowing names of source concepts to be used when searching. Showing number of parents and children per concept. Flexible divider in main UI.
- Loading branch information
Showing
31 changed files
with
950 additions
and
636 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package org.ohdsi.usagi; | ||
|
||
import java.io.File; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.ohdsi.utilities.DirectoryUtilities; | ||
|
||
import com.sleepycat.je.DatabaseException; | ||
import com.sleepycat.je.Environment; | ||
import com.sleepycat.je.EnvironmentConfig; | ||
import com.sleepycat.persist.EntityCursor; | ||
import com.sleepycat.persist.EntityIndex; | ||
import com.sleepycat.persist.EntityStore; | ||
import com.sleepycat.persist.PrimaryIndex; | ||
import com.sleepycat.persist.SecondaryIndex; | ||
import com.sleepycat.persist.StoreConfig; | ||
|
||
public class BerkeleyDbEngine { | ||
public static String DATABASE_FOLDER = "sleepyCat"; | ||
private Environment dbEnvironment; | ||
private EntityStore store; | ||
private ConceptDataAccessor conceptDataAccessor; | ||
private MapsToRelationshipDataAccessor mapsToRelationshipDataAccessor; | ||
private SubsumesRelationshipDataAccessor subsumesRelationshipDataAccessor; | ||
private String databaseFolder; | ||
private boolean isOpenForReading = false; | ||
private boolean isOpenForWriting = false; | ||
|
||
public BerkeleyDbEngine(String folder) { | ||
this.databaseFolder = folder + "/" + DATABASE_FOLDER; | ||
} | ||
|
||
public void createDatabase() { | ||
File folder = new File(databaseFolder); | ||
if (folder.exists()) | ||
DirectoryUtilities.deleteDir(folder); | ||
new File(databaseFolder).mkdir(); | ||
open(true); | ||
isOpenForWriting = true; | ||
} | ||
|
||
public void openForReading() { | ||
if (!isOpenForReading) { | ||
open(false); | ||
isOpenForReading = true; | ||
} | ||
} | ||
|
||
private void open(boolean create) { | ||
try { | ||
EnvironmentConfig envConfig = new EnvironmentConfig(); | ||
envConfig.setAllowCreate(create); | ||
envConfig.setReadOnly(!create); | ||
dbEnvironment = new Environment(new File(databaseFolder), envConfig); | ||
|
||
StoreConfig storeConfig = new StoreConfig(); | ||
storeConfig.setAllowCreate(create); | ||
storeConfig.setReadOnly(!create); | ||
store = new EntityStore(dbEnvironment, "EntityStore", storeConfig); | ||
conceptDataAccessor = new ConceptDataAccessor(); | ||
mapsToRelationshipDataAccessor = new MapsToRelationshipDataAccessor(); | ||
subsumesRelationshipDataAccessor = new SubsumesRelationshipDataAccessor(); | ||
} catch (DatabaseException dbe) { | ||
throw new RuntimeException(dbe); | ||
} | ||
} | ||
|
||
public void put(Concept concept) { | ||
conceptDataAccessor.primaryIndex.put(concept); | ||
} | ||
|
||
public void put(MapsToRelationship mapsToRelationship) { | ||
mapsToRelationshipDataAccessor.primaryIndex.put(mapsToRelationship); | ||
} | ||
|
||
public void put(SubsumesRelationship subsumesRelationship) { | ||
subsumesRelationshipDataAccessor.primaryIndex.put(subsumesRelationship); | ||
} | ||
|
||
public EntityCursor<Concept> getConceptCursor() { | ||
return conceptDataAccessor.primaryIndex.entities(); | ||
} | ||
|
||
public MapsToRelationship getMapsToRelationship(int conceptId) { | ||
return mapsToRelationshipDataAccessor.primaryIndex.get(conceptId); | ||
} | ||
|
||
public List<MapsToRelationship> getMapsToRelationshipsByConceptId2(int conceptId) { | ||
EntityIndex<Integer, MapsToRelationship> subIndex = mapsToRelationshipDataAccessor.secondaryIndex.subIndex(conceptId); | ||
EntityCursor<MapsToRelationship> cursor = subIndex.entities(); | ||
List<MapsToRelationship> relationships = new ArrayList<MapsToRelationship>(); | ||
try { | ||
for (MapsToRelationship relationship : cursor) | ||
relationships.add(relationship); | ||
} finally { | ||
cursor.close(); | ||
} | ||
return relationships; | ||
} | ||
|
||
public List<SubsumesRelationship> getSubsumesRelationshipsByParentConceptId(int conceptId) { | ||
EntityIndex<Integer, SubsumesRelationship> subIndex = subsumesRelationshipDataAccessor.secondaryIndexParent.subIndex(conceptId); | ||
EntityCursor<SubsumesRelationship> cursor = subIndex.entities(); | ||
List<SubsumesRelationship> relationships = new ArrayList<SubsumesRelationship>(); | ||
try { | ||
for (SubsumesRelationship relationship : cursor) | ||
relationships.add(relationship); | ||
} finally { | ||
cursor.close(); | ||
} | ||
return relationships; | ||
} | ||
|
||
public List<SubsumesRelationship> getSubsumesRelationshipsByChildConceptId(int conceptId) { | ||
EntityIndex<Integer, SubsumesRelationship> subIndex = subsumesRelationshipDataAccessor.secondaryIndexChild.subIndex(conceptId); | ||
EntityCursor<SubsumesRelationship> cursor = subIndex.entities(); | ||
List<SubsumesRelationship> relationships = new ArrayList<SubsumesRelationship>(); | ||
try { | ||
for (SubsumesRelationship relationship : cursor) | ||
relationships.add(relationship); | ||
} finally { | ||
cursor.close(); | ||
} | ||
return relationships; | ||
} | ||
|
||
public Concept getConcept(int conceptId) { | ||
return conceptDataAccessor.primaryIndex.get(conceptId); | ||
} | ||
|
||
public void shutdown() throws DatabaseException { | ||
try { | ||
if (isOpenForReading || isOpenForWriting) { | ||
store.close(); | ||
dbEnvironment.close(); | ||
} | ||
} catch (DatabaseException dbe) { | ||
throw new RuntimeException(dbe); | ||
} | ||
} | ||
|
||
private class ConceptDataAccessor { | ||
public PrimaryIndex<Integer, Concept> primaryIndex; | ||
|
||
public ConceptDataAccessor() throws DatabaseException { | ||
primaryIndex = store.getPrimaryIndex(Integer.class, Concept.class); | ||
} | ||
|
||
} | ||
|
||
private class MapsToRelationshipDataAccessor { | ||
public PrimaryIndex<Integer, MapsToRelationship> primaryIndex; | ||
public SecondaryIndex<Integer, Integer, MapsToRelationship> secondaryIndex; | ||
|
||
public MapsToRelationshipDataAccessor() throws DatabaseException { | ||
primaryIndex = store.getPrimaryIndex(Integer.class, MapsToRelationship.class); | ||
secondaryIndex = store.getSecondaryIndex(primaryIndex, Integer.class, "conceptId2"); | ||
} | ||
} | ||
|
||
private class SubsumesRelationshipDataAccessor { | ||
public PrimaryIndex<Integer, SubsumesRelationship> primaryIndex; | ||
public SecondaryIndex<Integer, Integer, SubsumesRelationship> secondaryIndexParent; | ||
public SecondaryIndex<Integer, Integer, SubsumesRelationship> secondaryIndexChild; | ||
|
||
public SubsumesRelationshipDataAccessor() throws DatabaseException { | ||
primaryIndex = store.getPrimaryIndex(Integer.class, SubsumesRelationship.class); | ||
secondaryIndexParent = store.getSecondaryIndex(primaryIndex, Integer.class, "parentConceptId"); | ||
secondaryIndexChild = store.getSecondaryIndex(primaryIndex, Integer.class, "childConceptId"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/******************************************************************************* | ||
* Copyright 2017 Observational Health Data Sciences and Informatics | ||
* | ||
* 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 org.ohdsi.usagi; | ||
|
||
import org.ohdsi.utilities.files.Row; | ||
|
||
import com.sleepycat.persist.model.Entity; | ||
import com.sleepycat.persist.model.PrimaryKey; | ||
|
||
/** | ||
* Class for holding information about a single (target) concept in the Vocabulary | ||
*/ | ||
@Entity | ||
public class Concept { | ||
public static Concept EMPTY_CONCEPT = createEmptyConcept(); | ||
|
||
@PrimaryKey | ||
public int conceptId; | ||
public String conceptName; | ||
public String domainId; | ||
public String vocabularyId; | ||
public String conceptClassId; | ||
public String standardConcept; | ||
public String conceptCode; | ||
public String validStartDate; | ||
public String validEndDate; | ||
public String invalidReason; | ||
public int parentCount; | ||
public int childCount; | ||
|
||
public String additionalInformation; | ||
|
||
public Concept(Row row) { | ||
conceptId = row.getInt("concept_id"); | ||
conceptName = row.get("concept_name"); | ||
domainId = row.get("domain_id"); | ||
vocabularyId = row.get("vocabulary_id"); | ||
conceptClassId = row.get("concept_class_id"); | ||
standardConcept = row.get("standard_concept"); | ||
conceptCode = row.get("concept_code"); | ||
validStartDate = row.get("valid_start_date"); | ||
validEndDate = row.get("valid_end_date"); | ||
invalidReason = row.get("invalid_reason"); | ||
additionalInformation = ""; | ||
} | ||
|
||
public static Concept createEmptyConcept() { | ||
Concept concept = new Concept(); | ||
concept.conceptId = 0; | ||
concept.conceptName = ""; | ||
concept.conceptClassId = ""; | ||
concept.vocabularyId = ""; | ||
concept.conceptCode = ""; | ||
concept.validStartDate = ""; | ||
concept.validEndDate = ""; | ||
concept.invalidReason = ""; | ||
concept.standardConcept = ""; | ||
concept.additionalInformation = ""; | ||
concept.parentCount = 0; | ||
concept.childCount = 0; | ||
return concept; | ||
} | ||
|
||
public Concept() { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.ohdsi.usagi; | ||
|
||
import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE; | ||
|
||
import org.ohdsi.utilities.files.Row; | ||
|
||
import com.sleepycat.persist.model.Entity; | ||
import com.sleepycat.persist.model.PrimaryKey; | ||
import com.sleepycat.persist.model.SecondaryKey; | ||
|
||
@Entity | ||
public class MapsToRelationship { | ||
@PrimaryKey | ||
public int conceptId1; | ||
@SecondaryKey(relate=MANY_TO_ONE) | ||
public int conceptId2; | ||
|
||
public MapsToRelationship() {} | ||
|
||
public MapsToRelationship(Row row) { | ||
conceptId1 = row.getInt("concept_id_1"); | ||
conceptId2 = row.getInt("concept_id_2"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.ohdsi.usagi; | ||
|
||
import org.ohdsi.utilities.files.Row; | ||
|
||
import com.sleepycat.persist.model.Entity; | ||
import com.sleepycat.persist.model.PrimaryKey; | ||
import com.sleepycat.persist.model.SecondaryKey; | ||
|
||
import static com.sleepycat.persist.model.Relationship.*; | ||
|
||
@Entity | ||
public class SubsumesRelationship { | ||
@PrimaryKey(sequence="Sequence_Namespace") | ||
public int id; | ||
|
||
@SecondaryKey(relate=MANY_TO_ONE) | ||
public int parentConceptId; | ||
@SecondaryKey(relate=MANY_TO_ONE) | ||
public int childConceptId; | ||
|
||
public SubsumesRelationship() {} | ||
|
||
public SubsumesRelationship(Row row) { | ||
parentConceptId = row.getInt("concept_id_1"); | ||
childConceptId = row.getInt("concept_id_2"); | ||
} | ||
} |
Oops, something went wrong.