update.
[chise/concord.git] / concord.c
index 83bb97f..4e220e9 100644 (file)
--- a/concord.c
+++ b/concord.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003,2004,2005,2006,2011 MORIOKA Tomohiko
+/* Copyright (C) 2003, 2004, 2005, 2006, 2011, 2013 MORIOKA Tomohiko
    This file is part of the CONCORD Library.
 
    The CONCORD Library is free software; you can redistribute it and/or
 #include "concord.h"
 #include "cos-i.h"
 #include "concord-name.h"
+#include "cos-hash.h"
 #include "concord-bdb.h"
 
+COS_Feature concord_opened_feature_list = NULL;
+COS_Feature concord_opened_feature_list_last = NULL;
+size_t concord_opened_feature_list_length = 0;
+size_t concord_opened_feature_list_limit = 96;
+
+COS_Feature_INDEX concord_opened_index_list = NULL;
+COS_Feature_INDEX concord_opened_index_list_last = NULL;
+size_t concord_opened_index_list_length = 0;
+size_t concord_opened_index_list_limit = 32;
+
 
 int
 CONCORD_String_size (const CONCORD_String s)
@@ -69,7 +80,6 @@ struct COS_DS_ent
 
   CONCORD_Object object_nil;
   CONCORD_Object (*read_object) (const unsigned char* str, size_t length);
-  CONCORD_NAME_TABLE* symbol_names;
 };
 
 CONCORD_Object
@@ -88,22 +98,11 @@ CONCORD_DS
 concord_open_ds (CONCORD_Backend_Type type, const char* location,
                 int subtype, int modemask)
 {
-#if 0
-  CONCORD_DS ds = (CONCORD_DS)malloc (sizeof (CONCORD_DS_ent));
-  size_t len = strlen (location);
-
-  if (ds == NULL)
-    return NULL;
-
-  ds->header.prefix = 0xff;
-  ds->header.type = CONCORD_Object_Type_DS;
-#else
   CONCORD_DS ds = COS_ALLOCATE_OBJECT (DS);
   size_t len = strlen (location);
 
   if (ds == NULL)
     return NULL;
-#endif
 
   ds->type = type;
   ds->subtype = ( (subtype != 0) ? subtype : DB_HASH );
@@ -123,15 +122,6 @@ concord_open_ds (CONCORD_Backend_Type type, const char* location,
       return NULL;
     }
 
-  ds->symbol_names = concord_make_name_table ();
-  if (ds->symbol_names == NULL)
-    {
-      concord_destroy_name_table (ds->genre_names);
-      free (ds->location);
-      free (ds);
-      return NULL;
-    }
-
   ds->object_nil = NULL;
   ds->read_object = &concord_default_read_object;
 
@@ -145,8 +135,6 @@ concord_close_ds (CONCORD_DS ds)
     free (ds->location);
   if (ds->genre_names != NULL)
     concord_destroy_name_table (ds->genre_names);
-  if (ds->symbol_names != NULL)
-    concord_destroy_name_table (ds->symbol_names);
   free (ds);
   return 0;
 }
@@ -303,18 +291,9 @@ concord_ds_open_genre (CONCORD_DS ds, const char* name)
   if (ds == NULL)
     return NULL;
 
-#if 0
-  genre = (CONCORD_Genre)malloc (sizeof (CONCORD_Genre_ent));
-  if (genre == NULL)
-    return NULL;
-
-  genre->header.prefix = 0xff;
-  genre->header.type = CONCORD_Object_Type_Genre;
-#else
   genre = COS_ALLOCATE_OBJECT (Genre);
   if (genre == NULL)
     return NULL;
-#endif
 
   genre->ds = ds;
   genre->name = (char*)malloc (len + 1);
@@ -553,15 +532,6 @@ concord_genre_get_index (CONCORD_Genre genre, const char* name)
 }
 
 
-struct COS_Feature_ent
-{
-  COS_Object_Header header;
-  CONCORD_Genre genre;
-  char* name;
-  DB* db;
-  u_int32_t access;
-};
-
 CONCORD_Feature
 concord_genre_open_feature (CONCORD_Genre genre, const char* feature)
 {
@@ -571,18 +541,9 @@ concord_genre_open_feature (CONCORD_Genre genre, const char* feature)
   if (genre == NULL)
     return NULL;
 
-#if 0
-  table = (CONCORD_Feature)malloc (sizeof (CONCORD_Feature_ent));
-  if (table == NULL)
-    return NULL;
-
-  table->header.prefix = 0xff;
-  table->header.type = CONCORD_Object_Type_Feature;
-#else
   table = COS_ALLOCATE_OBJECT (Feature);
   if (table == NULL)
     return NULL;
-#endif
 
   table->genre = genre;
   table->db = NULL;
@@ -594,6 +555,8 @@ concord_genre_open_feature (CONCORD_Genre genre, const char* feature)
       return NULL;
     }
   strcpy (table->name, feature);
+  table->value_table = NULL;
+  table->next = NULL;
   return table;
 }
 
@@ -661,6 +624,17 @@ concord_feature_setup_db (CONCORD_Feature feature, int writable)
     {
       CONCORD_Genre genre = feature->genre;
 
+      if ( concord_opened_feature_list_length
+          >= concord_opened_feature_list_limit )
+       {
+         CONCORD_Feature top_feature = concord_opened_feature_list;
+
+         CONCORD_BDB_close (top_feature->db);
+         top_feature->db = NULL;
+         concord_opened_feature_list = top_feature->next;
+         top_feature->next = NULL;
+         concord_opened_feature_list_length--;
+       }
       feature->db
        = CONCORD_BDB_open (genre->ds->location, genre->name,
                            "feature", feature->name,
@@ -669,6 +643,17 @@ concord_feature_setup_db (CONCORD_Feature feature, int writable)
       if (feature->db == NULL)
        return -1;
       feature->access = access;
+      if ( concord_opened_feature_list == NULL )
+       {
+         concord_opened_feature_list = feature;
+         concord_opened_feature_list_last = feature;
+       }
+      else
+       {
+         concord_opened_feature_list_last->next = feature;
+         concord_opened_feature_list_last = feature;
+       }
+      concord_opened_feature_list_length++;
     }
   return 0;
 }
@@ -777,15 +762,6 @@ concord_feature_foreach_obj_string (CONCORD_Feature feature,
 }
 
 
-struct COS_Feature_INDEX_ent
-{
-  COS_Object_Header header;
-  CONCORD_Genre genre;
-  char *name;
-  DB* db;
-  u_int32_t access;
-};
-
 CONCORD_INDEX
 concord_genre_open_index (CONCORD_Genre genre, const char* index)
 {
@@ -795,18 +771,9 @@ concord_genre_open_index (CONCORD_Genre genre, const char* index)
   if (genre == NULL)
     return NULL;
 
-#if 0
-  table = (CONCORD_INDEX)malloc (sizeof (CONCORD_INDEX_ent));
-  if (table == NULL)
-    return NULL;
-
-  table->header.prefix = 0xff;
-  table->header.type = CONCORD_Object_Type_INDEX;
-#else
   table = COS_ALLOCATE_OBJECT (Feature_INDEX);
   if (table == NULL)
     return NULL;
-#endif
 
   table->genre = genre;
   table->db = NULL;
@@ -818,6 +785,8 @@ concord_genre_open_index (CONCORD_Genre genre, const char* index)
       return NULL;
     }
   strcpy (table->name, index);
+  table->decoding_table = NULL;
+  table->next = NULL;
   return table;
 }
 
@@ -885,6 +854,17 @@ concord_index_setup_db (CONCORD_INDEX index, int writable)
     {
       CONCORD_Genre genre = index->genre;
 
+      if ( concord_opened_index_list_length
+          >= concord_opened_index_list_limit )
+       {
+         CONCORD_INDEX top_index = concord_opened_index_list;
+
+         CONCORD_BDB_close (top_index->db);
+         top_index->db = NULL;
+         concord_opened_index_list = top_index->next;
+         top_index->next = NULL;
+         concord_opened_index_list_length--;
+       }
       index->db
        = CONCORD_BDB_open (genre->ds->location, genre->name,
                            "index", index->name,
@@ -893,6 +873,17 @@ concord_index_setup_db (CONCORD_INDEX index, int writable)
       if (index->db == NULL)
        return -1;
       index->access = access;
+      if ( concord_opened_index_list == NULL )
+       {
+         concord_opened_index_list = index;
+         concord_opened_index_list_last = index;
+       }
+      else
+       {
+         concord_opened_index_list_last->next = index;
+         concord_opened_index_list_last = index;
+       }
+      concord_opened_index_list_length++;
     }
   return 0;
 }