tv_db.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,268 行 · 第 1/3 页

ERL
1,268
字号
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%%%*********************************************************************%%% %%%   Description:      Module handling the internal database in the table tool.%%%%%%*********************************************************************-module(tv_db).-export([dbs/2]).-include("tv_int_def.hrl").-include("tv_int_msg.hrl").-include("tv_db_int_def.hrl").%%%*********************************************************************%%% EXTERNAL FUNCTIONS%%%*********************************************************************dbs(Master, ErrMsgMode) ->    process_flag(trap_exit, true),    put(error_msg_mode, ErrMsgMode),    ProcVars = #process_variables{master_pid = Master},    blocked(ProcVars).%%%********************************************************************%%% INTERNAL FUNCTIONS%%%********************************************************************blocked(ProcVars) ->    receive        Msg ->            case Msg of                 #dbs_deblock{} ->                    deblock(Msg, ProcVars, false);		{error_msg_mode, Mode} ->		    put(error_msg_mode, Mode),		    blocked(ProcVars);                {'EXIT', Pid, Reason} ->                    MasterPid = ProcVars#process_variables.master_pid,                    exit_signals({Pid, Reason}, MasterPid),                    blocked(ProcVars);                _Other ->                    blocked(ProcVars)            end    end.deblock(Msg, ProcVars, SearchWinCreated) ->    #dbs_deblock{sender         = Sender,		 etsread_pid    = EtsreadPid,		 type           = Type,		 keypos         = KeyPos,		 sublist_length = SublistLength} = Msg,    NewDbData = #db_data{subset_size = SublistLength,			 subset_pos  = 1,			 key_no      = KeyPos,			 ets_type    = Type			},    NewProcVars = ProcVars#process_variables{db_data     = NewDbData,					     etsread_pid = EtsreadPid},    Sender ! #dbs_deblock_cfm{sender = self()},    deblocked_loop(NewProcVars, SearchWinCreated, [], undefined).    deblocked_loop(ProcVars, SearchWinCreated, SearchData, RegExp) ->    receive	Msg ->	    case Msg of				{gs,entry,keypress,_Data,['Return' | _T]} ->		    NewSearchData = search_object(ProcVars, RegExp),		    deblocked_loop(ProcVars, SearchWinCreated, NewSearchData, RegExp);		{gs,entry,keypress,_Data,['Tab' | _T]} ->		    gs:config(entry, [{select, {0,1000}}]),		    deblocked_loop(ProcVars, SearchWinCreated, SearchData, RegExp);				{gs,entry,keypress,_Data,_Args} ->		    deblocked_loop(ProcVars, SearchWinCreated, SearchData, RegExp);		{gs,expr_term,click,_Data,_Args} ->		    deblocked_loop(ProcVars, SearchWinCreated, SearchData, false);		{gs,expr_regexp,click,_Data,_Args} ->		    deblocked_loop(ProcVars, SearchWinCreated, SearchData, true);		{gs,search,click,_Data,_Args} ->		    NewSearchData = search_object(ProcVars, RegExp),		    deblocked_loop(ProcVars, SearchWinCreated, NewSearchData, RegExp);				{gs,cancel,click,cancel,_Args} ->		    tv_db_search:destroy_window(SearchWinCreated),		    deblocked_loop(ProcVars, false, [], RegExp);				{gs,listbox,click,_LbData,[Idx | _T]} when SearchData =/= [] ->		    tv_db_search:mark_busy(SearchWinCreated),		    {Row,_Obj} = lists:nth(Idx+1, SearchData),		    DbData     = ProcVars#process_variables.db_data,		       %% Never allow 'subset_pos' to have zero as value! 		       %% No list can begin with the 0:th element!!! 		       %% Has to be at least 1!		    NewDbData  = DbData#db_data{subset_pos=?COMM_FUNC_FILE:max(1,									       Row),						subset_size=?ITEMS_TO_DISPLAY},		    NewProcVars = ProcVars#process_variables{db_data=NewDbData},		    send_subset(NewProcVars, undefined, undefined),		    tv_db_search:mark_nonbusy(SearchWinCreated),		    deblocked_loop(NewProcVars, SearchWinCreated, SearchData, RegExp);		{gs,win,configure,_Data,_Args} ->		    tv_db_search:resize_window(SearchWinCreated),		    deblocked_loop(ProcVars, SearchWinCreated, SearchData, RegExp);		{gs,win,destroy,_Data,_Args} ->		    deblocked_loop(ProcVars, false, [], RegExp);		#dbs_new_data{data = NewData, keys = ListOfKeys, 			      time_to_read_table = ElapsedTimeEtsread} ->		    tv_db_search:reset_window(SearchWinCreated),		    T1 = time(),		    NewProcVars = update_db(NewData, ListOfKeys, ProcVars),		    T2 = time(),		    ElapsedTimeDbs = compute_elapsed_seconds(T1, T2),		    send_subset(NewProcVars, ElapsedTimeEtsread, ElapsedTimeDbs),		    deblocked_loop(NewProcVars, SearchWinCreated, [], RegExp);		#dbs_subset_req{subset_pos = Pos,subset_length = Length} ->		    DbData    = ProcVars#process_variables.db_data,		       %% Never allow 'subset_pos' to have zero as value! 		       %% No list can begin with the 0:th element!!! 		       %% Has to be at least 1!		    NewDbData = DbData#db_data{subset_pos=?COMM_FUNC_FILE:max(1, 									      Pos),					       subset_size=Length},		    NewProcVars = ProcVars#process_variables{db_data = NewDbData},		    send_subset(NewProcVars, undefined, undefined),		    deblocked_loop(NewProcVars, SearchWinCreated, SearchData, RegExp);		#dbs_marked_row{row_no = RowNo} ->		    DbData      = ProcVars#process_variables.db_data,		    NewDbData   = DbData#db_data{requested_row = RowNo},		    NewProcVars = ProcVars#process_variables{db_data = NewDbData},		    deblocked_loop(NewProcVars, SearchWinCreated, SearchData, RegExp);		    		#dbs_search_req{} ->		    tv_db_search:create_window(SearchWinCreated),		    deblocked_loop(ProcVars, true, SearchData, false);		#dbs_sorting_mode{} ->		    {NewProcVars, NewSearchData} = 			update_sorting_mode(Msg, ProcVars, 					    SearchWinCreated, SearchData, RegExp),		    deblocked_loop(NewProcVars, SearchWinCreated, NewSearchData, RegExp);		#dbs_deblock{} ->		    tv_db_search:reset_window(SearchWinCreated),		    deblock(Msg, ProcVars, SearchWinCreated);		#dbs_updated_object{object=Obj,old_object=OldObj,old_color=Color,obj_no=ObjNo} ->		    {Success, NewProcVars} = update_object(Obj, OldObj, Color, ObjNo, ProcVars),		    case Success of			true ->			    tv_db_search:reset_window(SearchWinCreated),			    send_subset(NewProcVars, undefined, undefined);			false ->			    done		    end,		    deblocked_loop(NewProcVars, SearchWinCreated, SearchData, RegExp);		#dbs_new_object{object=Obj} ->		    {Success, NewProcVars} = new_object(Obj, ProcVars),		    case Success of			true ->			    tv_db_search:reset_window(SearchWinCreated),			    send_subset(NewProcVars, undefined, undefined);			false ->			    done		    end,		    deblocked_loop(NewProcVars, SearchWinCreated, SearchData, RegExp);		#dbs_delete_object{object=Obj, color=Color, obj_no=ObjNo} ->		    {Success, NewProcVars} = delete_object(Obj, Color, ObjNo, ProcVars),		    case Success of			true ->			    tv_db_search:reset_window(SearchWinCreated), 			    send_subset(NewProcVars, undefined, undefined);			false ->			    done		    end,		    deblocked_loop(NewProcVars, SearchWinCreated, SearchData, RegExp);		#pc_list_info{lists_as_strings=ListAsStr} ->		    NewProcVars = ProcVars#process_variables{lists_as_strings=ListAsStr},		    deblocked_loop(NewProcVars, SearchWinCreated, SearchData, RegExp);		{error_msg_mode, Mode} ->		    put(error_msg_mode, Mode),		    deblocked_loop(ProcVars, SearchWinCreated, SearchData, RegExp);                {'EXIT', Pid, Reason} ->                    MasterPid = ProcVars#process_variables.master_pid,                    exit_signals({Pid, Reason}, MasterPid),                    deblocked_loop(ProcVars, SearchWinCreated, SearchData, RegExp);                _Other ->                       %% io:format("Received message: ~w ~n", [_Other]),                    deblocked_loop(ProcVars, SearchWinCreated, SearchData, RegExp)	    end    end.search_object(ProcVars, RegExp) ->    DbData    = ProcVars#process_variables.db_data,    DbList    = dblist2list(DbData#db_data.db),    ListAsStr = ProcVars#process_variables.lists_as_strings,    case catch tv_db_search:get_input_and_search(DbList, RegExp, ListAsStr) of	{'EXIT', _Reason} ->	    tv_db_search:reset_window(true),	    [];	List ->	    List    end.update_sorting_mode(Msg, ProcVars, SearchWinCreated, OldSearchData, RegExp) ->    #dbs_sorting_mode{sorting     = Sorting,		      reverse     = Reverse,		      sort_key_no = SortKeyNo} = Msg,    DbData = ProcVars#process_variables.db_data,    #db_data{db          = DbList,	     sorting     = OldSorting,	     rev_sorting = OldReverse,	     sort_key_no = OldSortKeyNo} = DbData,        NewDbList = sort_db_list(DbList, Sorting, OldSorting, Reverse, OldReverse, 			     SortKeyNo, OldSortKeyNo),        NewDbData = DbData#db_data{db          = NewDbList,			       sorting     = Sorting,			       rev_sorting = Reverse,			       sort_key_no = SortKeyNo			      },    NewProcVars = ProcVars#process_variables{db_data = NewDbData},    send_subset(NewProcVars, undefined, undefined),    SearchData = 	case Sorting of	    false ->		OldSearchData;	    OldSorting when Reverse =:= OldReverse,			    SortKeyNo =:= OldSortKeyNo ->		[];	    OldSorting when Reverse =:= OldReverse,			    OldSortKeyNo =:= undefined->		[];	    _Other ->		ListAsStr = ProcVars#process_variables.lists_as_strings,		case catch tv_db_search:update_search(SearchWinCreated, 						      NewDbList, RegExp,						      ListAsStr) of		    {'EXIT', _Reason} ->			tv_db_search:reset_window(true),			[];		    List ->			List		end	end,    {NewProcVars, SearchData}.sort_db_list(DbList, Sort, Sort, Rev, Rev, KeyNo, KeyNo) ->       % Already sorted!    DbList;sort_db_list(DbList, false, _OldSort, _Rev, _OldRev, _KeyNo, _OldKeyNo) ->       % No sorting, i.e., the old list order suffices!    DbList;sort_db_list(DbList, _Sort, _OldSort, Rev, _OldRev, KeyNo, _OldKeyNo) ->    tv_db_sort:mergesort(KeyNo, DbList, Rev).    send_subset(ProcVars, EtsreadTime, DbsTime) ->    #process_variables{master_pid    = MasterPid,		       db_data       = DbData,		       list_of_keys  = ListOfKeys}   = ProcVars,        #db_data{subset_size   = SubsetSize,	     subset_pos    = SubsetPos,	     requested_row = RowNo,	     db_size       = DbSize,	     db            = DbList,	     max_elem_size = MaxElemSize}  = DbData,        RowData = get_requested_row_data(RowNo, DbList),    if 	DbSize > 0 ->	    Pos = ?COMM_FUNC_FILE:min(SubsetPos, DbSize),	       % Requested_data may be shorter than requested, but that's OK,               % pd handles that correctly!	    Subset = lists:sublist(DbList, Pos, SubsetSize),	    MasterPid ! #dbs_subset{sender                = self(),				    data                  = Subset,				    subset_pos            = Pos,				    db_length             = DbSize,				    list_of_keys          = ListOfKeys,				    max_elem_size         = MaxElemSize,				    requested_row         = RowData,				    required_time_etsread = EtsreadTime,				    required_time_dbs     = DbsTime				   };	true ->	    MasterPid ! #dbs_subset{sender                = self(),				    data                  = [],				    subset_pos            = 1,				    db_length             = 0,				    list_of_keys          = ListOfKeys,				    max_elem_size         = MaxElemSize,				    requested_row         = RowData,				    required_time_etsread = EtsreadTime,				    required_time_dbs     = DbsTime				   }    end.        get_requested_row_data(undefined, _DbList) ->    [];get_requested_row_data(_RowNo, []) ->    [];get_requested_row_data(RowNo, DbList) ->    case catch lists:nth(RowNo, DbList) of	{'EXIT', _Reason} ->	    [];	RowData ->	    [RowData]    end.exit_signals(ExitInfo, MasterPid) ->

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?