Commits

Anonymous committed 639a125

reading tablename made it better: reads tablename without converting intermediately to list. from atom to binary, directly by term_to_binary.

  • Participants
  • Parent commits 3747252
  • Branches dev

Comments (0)

Files changed (3)

File c_src/ytcadb.c

   ErlNifEnv * env;
 };
 
-static int my_enif_get_string(ErlNifEnv *env, ERL_NIF_TERM list, char* buf){ //thx to vostok92
-  ERL_NIF_TERM head, tail;
-  int val;
-  
-  while (enif_get_list_cell(env, list, &head, &tail)) {
-    if (!enif_get_int(env, head, &val)) {
-      return 0;
-    }
-    *buf = (char)val;
-    buf++;
-    list = tail; 
+static char * get_string_from_atom_binary(ErlNifEnv * env, ERL_NIF_TERM atom_binary ){
+  ErlNifBinary strbin;
+  char * ret;
+  if( enif_inspect_binary(env, atom_binary, &strbin) ){
+    if( strbin.size < 5 || strbin.data[0] != 131 || strbin.data[1] != 100 || strbin.data[2] != 0 ){
+      PRINT_BIN( strbin.data, strbin.size );
+      return NULL;
+    } 
+    unsigned int s = strbin.data[3];  //string length
+    ret = (char*)enif_alloc(env, (s+1) * sizeof(unsigned char) );
+    memcpy(ret, strbin.data+4, s);
+    ret[s] = '\0';
+    //    enif_release_binary(env, &strbin); need this?
+    //    printf("tablename: %s\n", ret);
+    return ret;
   }
-  *buf = '\0';
-  
-  return 1;
+  return NULL;
 }
 
-static ERL_NIF_TERM ytcadb_open(ErlNifEnv * env, ERL_NIF_TERM string_tablename, ERL_NIF_TERM string_openfilename){
-  char tablename[1024];
-  char filename[1024];
+static char * get_string_from_string_binary(ErlNifEnv * env, ERL_NIF_TERM string_binary ){
+  ErlNifBinary strbin;
+  char * ret;
+  if( enif_inspect_binary(env, string_binary, &strbin) ){
+    ret = (char*)enif_alloc(env, (strbin.size+1) * sizeof(unsigned char) );
+    memcpy(ret, strbin.data, strbin.size);
+    ret[strbin.size] = '\0';
+    //    enif_release_binary(env, &strbin); need this?
+    //    printf("filename: %s\n", ret);
+    return ret;
+  }
+  return NULL;
+}
+
+static ERL_NIF_TERM ytcadb_open(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin, ERL_NIF_TERM string_openfilename){
+  char *tablename_s, *filename_s;
   TCADB * tcadb = tcadbnew();
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
   
-  my_enif_get_string(env, string_tablename, tablename);
-  my_enif_get_string(env, string_openfilename, filename);
-  
-  if( tcadbopen( tcadb, filename ) ){
-    if( push_hash_map( map, tablename, (void*)tcadb ) ){
-      return enif_make_atom(env, "ok");
-    }else{
-      tcadbclose(tcadb);
+  if( (tablename_s = get_string_from_atom_binary(env, tablename_atombin) ) != NULL ){
+    if( (filename_s = get_string_from_string_binary(env, string_openfilename ) ) != NULL ){
+      if( tcadbopen( tcadb, filename_s ) ){
+	if( push_hash_map( map, tablename_s, (void*)tcadb ) ){
+	  enif_free(env, filename_s);
+	  enif_free(env, tablename_s);
+	  return enif_make_atom(env, "ok");
+	}else{
+	  tcadbclose(tcadb);
+	}
+      }
+      enif_free(env, filename_s);
     }
+    enif_free(env, tablename_s);
   }
   tcadbdel(tcadb);
   return enif_make_atom(env, "failed");
 }
-static ERL_NIF_TERM ytcadb_close(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_close(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
   TCADB * tcadb = NULL;
   
-  my_enif_get_string(env, string_tablename, tablename);
-  tcadb = pop_hash_map(map, tablename, NULL, NULL);
-
-  if( tcadb != NULL ){
-    tcadbclose( tcadb );
-    tcadbdel(tcadb);  
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+    tcadb = pop_hash_map(map, tablename, NULL, NULL);
+    
+    if( tcadb != NULL ){
+      tcadbclose( tcadb );
+      tcadbdel(tcadb);  
+    }
+    enif_free(env, tablename);
   }
   return enif_make_atom(env, "ok");
 }
   }
   return NULL;
 }
-static ERL_NIF_TERM ytcadb_put(ErlNifEnv * env, ERL_NIF_TERM string_tablename, ERL_NIF_TERM key, ERL_NIF_TERM value){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_put(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin, ERL_NIF_TERM key, ERL_NIF_TERM value){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
   struct kv_pair pair = {key, value, env};
-  
-  my_enif_get_string(env, string_tablename, tablename);
-  void * ret = operate_on_hash_entry(map, tablename, put_operation_, &pair );
-  
-  if( ret != NULL ){
-    return enif_make_atom(env, "ok");
+
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+    void * ret = operate_on_hash_entry(map, tablename, put_operation_, &pair );
+    
+    if( ret != NULL ){
+      return enif_make_atom(env, "ok");
+    }
+    enif_free(env,tablename);
   }
   return enif_make_atom(env, "error");
 }
   }
   return NULL;
 }
-static ERL_NIF_TERM ytcadb_putkeep(ErlNifEnv * env, ERL_NIF_TERM string_tablename, ERL_NIF_TERM key, ERL_NIF_TERM value){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_putkeep(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin, ERL_NIF_TERM key, ERL_NIF_TERM value){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
   struct kv_pair pair = {key, value, env};
   
-  my_enif_get_string(env, string_tablename, tablename);
-  void * ret = operate_on_hash_entry(map, tablename, putkeep_operation_, &pair );
-  
-  if( ret != NULL ){
-    return enif_make_atom(env, "ok");
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+    void * ret = operate_on_hash_entry(map, tablename, putkeep_operation_, &pair );
+    
+    if( ret != NULL ){
+      return enif_make_atom(env, "ok");
+    }
+    enif_free(env, tablename);
   }
   return enif_make_atom(env, "error");
 }
   }
   return NULL;
 }
-static ERL_NIF_TERM ytcadb_out(ErlNifEnv * env, ERL_NIF_TERM string_tablename, ERL_NIF_TERM key){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_out(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin, ERL_NIF_TERM key){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
   struct kv_pair pair = {key, 0, env};
   
-  my_enif_get_string(env, string_tablename, tablename);
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
   
-  if( operate_on_hash_entry(map, tablename, out_operation_, &pair ) ){
-    return enif_make_atom(env, "ok");
+    if( operate_on_hash_entry(map, tablename, out_operation_, &pair ) ){
+      enif_free(env,tablename);
+      return enif_make_atom(env, "ok");
+    }else{
+      enif_free(env,tablename);
+    }
   }
   return enif_make_atom(env, "error");
 }
   return NULL;
 }
 
-static ERL_NIF_TERM ytcadb_get(ErlNifEnv * env, ERL_NIF_TERM string_tablename, ERL_NIF_TERM key){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_get(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin, ERL_NIF_TERM key){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
   struct kv_pair pair = {key, 0, env};
   
-  my_enif_get_string(env, string_tablename, tablename);
-  ErlNifBinary * ret = operate_on_hash_entry(map, tablename, get_operation_, &pair );
-  
-  if( ret != NULL ){
-    return enif_make_tuple(env, 2, enif_make_atom(env, "ok"), enif_make_binary(env, ret));
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+    ErlNifBinary * ret = operate_on_hash_entry(map, tablename, get_operation_, &pair );
+    enif_free(env, tablename);
+    
+    if( ret != NULL ){
+      return enif_make_tuple(env, 2, enif_make_atom(env, "ok"), enif_make_binary(env, ret));
+    }
   }
   return enif_make_atom(env, "error");
 }
   TCADB * tcadb = (TCADB*)value;
   return (( tcadbiterinit( tcadb ) )? value :  NULL );
 }
-static ERL_NIF_TERM ytcadb_iterinit(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_iterinit(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
-  my_enif_get_string(env, string_tablename, tablename);
-  void * ret = operate_on_hash_entry(map, tablename, iterinit_operation_, NULL );
-  if( ret != NULL ){
-    return enif_make_atom(env, "ok");
+
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+
+    void * ret = operate_on_hash_entry(map, tablename, iterinit_operation_, NULL );
+    enif_free(env, tablename);
+    if( ret != NULL ){
+      return enif_make_atom(env, "ok");
+    }
   }
+
   return enif_make_atom(env, "error");
 }
 
   }
   return NULL;
 }
-static ERL_NIF_TERM ytcadb_iternext(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_iternext(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
   struct kv_pair pair = {0, 0, env};
   
-  my_enif_get_string(env, string_tablename, tablename);
-  ErlNifBinary * ret = operate_on_hash_entry(map, tablename, iternext_operation_, &pair );
-  
-  if( ret != NULL ){
-    return enif_make_tuple(env, 2, enif_make_atom(env, "ok"), enif_make_binary(env, ret));
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+    ErlNifBinary * ret = operate_on_hash_entry(map, tablename, iternext_operation_, &pair );
+    enif_free(env, tablename);
+    
+    if( ret != NULL ){
+      return enif_make_tuple(env, 2, enif_make_atom(env, "ok"), enif_make_binary(env, ret));
+    }
   }
   return enif_make_atom(env, "end_of_data");
 }
   TCADB * tcadb = (TCADB*)value;
   return (( tcadbsync( tcadb ) )? value :  NULL );
 }
-static ERL_NIF_TERM ytcadb_sync(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_sync(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
-  my_enif_get_string(env, string_tablename, tablename);
-  void * ret = operate_on_hash_entry(map, tablename, sync_operation_, NULL );
-  if( ret != NULL ){
-    return enif_make_atom(env, "ok");
+
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+
+    void * ret = operate_on_hash_entry(map, tablename, sync_operation_, NULL );
+    enif_free(env, tablename);
+    if( ret != NULL ){
+      return enif_make_atom(env, "ok");
+    }
   }
   return enif_make_atom(env, "error");
 }
   TCADB * tcadb = (TCADB*)value;
   return (( tcadbvanish( tcadb ) )? value :NULL);
 }
-static ERL_NIF_TERM ytcadb_vanish(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_vanish(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
-  my_enif_get_string(env, string_tablename, tablename);
-  void * ret = operate_on_hash_entry(map, tablename, vanish_operation_, NULL );
-  if( ret != NULL ){
-    return enif_make_atom(env, "ok");
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+
+    void * ret = operate_on_hash_entry(map, tablename, vanish_operation_, NULL );
+    enif_free(env,tablename);
+    if( ret != NULL ){
+      return enif_make_atom(env, "ok");
+    }
   }
   return enif_make_atom(env, "error");
 }
 
-static ERL_NIF_TERM ytcadb_copy(ErlNifEnv * env, ERL_NIF_TERM string_tablename, ERL_NIF_TERM string_filename){
+static ERL_NIF_TERM ytcadb_copy(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin, ERL_NIF_TERM string_filename){
   return enif_make_atom(env, "not_yet_implemented");}
 
 void * path_operation_(void * arg, const char * key, void * value ){
   TCADB * tcadb = (TCADB*)value;
   return (void*)tcadbpath(tcadb); 
 }
-static ERL_NIF_TERM ytcadb_path(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_path(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
-  my_enif_get_string(env, string_tablename, tablename);
-  const char * ret = (const char*)operate_on_hash_entry(map, tablename, path_operation_, NULL );
-  if( ret != NULL ){
-    return enif_make_tuple(env, 2, enif_make_atom(env, "ok"), enif_make_string(env, ret) );
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+
+    const char * ret = (const char*)operate_on_hash_entry(map, tablename, path_operation_, NULL );
+    enif_free(env,tablename);
+    if( ret != NULL ){
+      return enif_make_tuple(env, 2, enif_make_atom(env, "ok"), enif_make_string(env, ret) );
+    }
   }
   return enif_make_atom(env, "error");
 }
   *rnum = tcadbrnum(tcadb); 
   return NULL;
 }
-static ERL_NIF_TERM ytcadb_rnum(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_rnum(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
-  my_enif_get_string(env, string_tablename, tablename);
   uint64_t rnum = 0xffff;
-  operate_on_hash_entry(map, tablename, rnum_operation_, (void*)&rnum );
+  
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+    operate_on_hash_entry(map, tablename, rnum_operation_, (void*)&rnum );
+    enif_free(env,tablename);
+  }
   return enif_make_int(env, rnum);
 }
 void * size_operation_(void * arg, const char * key, void * value ){
   *size = tcadbsize(tcadb); 
   return NULL;
 }
-static ERL_NIF_TERM ytcadb_size(ErlNifEnv * env, ERL_NIF_TERM string_tablename){
-  char tablename[1024];
+static ERL_NIF_TERM ytcadb_size(ErlNifEnv * env, ERL_NIF_TERM tablename_atombin){
+  char * tablename;
   hash_map_t * map = (hash_map_t*) enif_get_data(env);
-  my_enif_get_string(env, string_tablename, tablename);
   uint64_t size = 0xffff;
-  operate_on_hash_entry(map, tablename, size_operation_, (void*)&size );
+    
+  if( (tablename = get_string_from_atom_binary(env, tablename_atombin) )!=NULL ){
+
+    operate_on_hash_entry(map, tablename, size_operation_, (void*)&size );
+    enif_free(env,tablename);
+  }
   return enif_make_int(env, size);
 }
 

File c_src/ytcadb.h

 //ERL_NIF_INIT(test_nif,nif_funcs,NULL,NULL,NULL,NULL)
 ERL_NIF_INIT(tcadb,ytcadb_funcs,load_,reload_,upgrade_,unload_);
 
+
+#define PRINT_BIN( bin, len )  \
+  unsigned char * p = (bin);	       \
+  while( p - (bin) < (len) ){			\
+    printf( "%d ", *p++ );			\
+  } \
+  putchar( '\n' ); 
+
+
 #endif
 

File src/tcadb.erl

 % @type key() = term()
 % @type value() = term()
 -include("tokyocabinet.hrl").
-% -on_load(init/0).
+
+%-on_load(init/0). on_load should return 'ok' in R13B04, 'true' in R13B03
 
 -export([          
 	 init/0,
 %% @spec open( tablename(), proplist() ) -> ok | not_loaded | {error, reason()}
 -spec open( tablename(), list() ) -> ok | {error, tcadbopen_failure} | not_loaded.
 open('*', Options) ->
-    open_("*", generate_open_argv("*", Options));
+    open_(make_table_identifier('*'), list_to_binary(generate_open_argv("*", Options)));
 open('+', Options) ->
-    open_("+", generate_open_argv("+", Options));
+    open_(make_table_identifier('+'), list_to_binary(generate_open_argv("+", Options)));
 open(TableName,Options) when is_atom(TableName) -> 
     TableIdentifier = make_table_identifier(TableName),
     case proplists:get_value(path, Options) of 
 	undefined ->
 	    TableFilename = filename:join(["/tmp", generate_open_argv(TableName, Options)]),
-	    open_(TableIdentifier, TableFilename);
+	    open_(TableIdentifier, list_to_binary(TableFilename));
 	Path when is_list(Path)-> 
 	    TableFilename = filename:join([Path, generate_open_argv(TableName, Options)]),
-	    open_(TableIdentifier, TableFilename);
+	    open_(TableIdentifier, list_to_binary(TableFilename));
 	_ ->
 	    {error,invalid_filename}
     end.
 	    
 open_( _, _ )-> not_loaded.
 
-make_table_identifier(TableName) when is_atom(TableName)->  atom_to_list(TableName).
+%% @private some helper function
+-spec make_table_identifier( tablename() ) -> binary().
+make_table_identifier(TableName) when is_atom(TableName)->  term_to_binary(TableName).
 
 -type option_key() :: bnum | capnum | capsiz | mode | bnum | apow | fpow | opts | rcnum | xmsiz | dfunit .
 -type option_value() :: pos_integer() | list() .
 -type open_option() :: { option_key(), option_value() }.
--spec generate_open_argv( atom() | list() , [ open_option() ] )-> atom().
+-spec generate_open_argv( atom() | list() , [ open_option() ] )-> list().
 generate_open_argv(TableName, []) when is_atom( TableName ) ->
     atom_to_list(TableName);
 generate_open_argv(TableName, Options) when is_atom( TableName ) ->