当前位置: 首页>>代码示例>>Java>>正文


Java HRegionLocation.getServerName方法代码示例

本文整理汇总了Java中org.apache.hadoop.hbase.HRegionLocation.getServerName方法的典型用法代码示例。如果您正苦于以下问题:Java HRegionLocation.getServerName方法的具体用法?Java HRegionLocation.getServerName怎么用?Java HRegionLocation.getServerName使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在org.apache.hadoop.hbase.HRegionLocation的用法示例。


在下文中一共展示了HRegionLocation.getServerName方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Java代码示例。

示例1: regionLocationFromHBase

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
public static THRegionLocation regionLocationFromHBase(HRegionLocation hrl) {
  HRegionInfo hri = hrl.getRegionInfo();
  ServerName serverName = hrl.getServerName();

  THRegionInfo thRegionInfo = new THRegionInfo();
  THRegionLocation thRegionLocation = new THRegionLocation();
  TServerName tServerName = new TServerName();

  tServerName.setHostName(serverName.getHostname());
  tServerName.setPort(serverName.getPort());
  tServerName.setStartCode(serverName.getStartcode());

  thRegionInfo.setTableName(hri.getTable().getName());
  thRegionInfo.setEndKey(hri.getEndKey());
  thRegionInfo.setStartKey(hri.getStartKey());
  thRegionInfo.setOffline(hri.isOffline());
  thRegionInfo.setSplit(hri.isSplit());
  thRegionInfo.setReplicaId(hri.getReplicaId());

  thRegionLocation.setRegionInfo(thRegionInfo);
  thRegionLocation.setServerName(tServerName);

  return thRegionLocation;
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:25,代码来源:ThriftUtilities.java

示例2: getRegionServer

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
/**
 * Returns the {@link ServerName} from catalog table {@link Result}
 * where the region is transitioning. It should be the same as
 * {@link HRegionInfo#getServerName(Result)} if the server is at OPEN state.
 * @param r Result to pull the transitioning server name from
 * @return A ServerName instance or {@link HRegionInfo#getServerName(Result)}
 * if necessary fields not found or empty.
 */
static ServerName getRegionServer(final Result r, int replicaId) {
  Cell cell = r.getColumnLatestCell(HConstants.CATALOG_FAMILY, getServerNameColumn(replicaId));
  if (cell == null || cell.getValueLength() == 0) {
    RegionLocations locations = MetaTableAccessor.getRegionLocations(r);
    if (locations != null) {
      HRegionLocation location = locations.getRegionLocation(replicaId);
      if (location != null) {
        return location.getServerName();
      }
    }
    return null;
  }
  return ServerName.parseServerName(Bytes.toString(cell.getValueArray(),
    cell.getValueOffset(), cell.getValueLength()));
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:24,代码来源:RegionStateStore.java

示例3: testMove

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
@Test (timeout=180000)
public void testMove() throws Exception {
  List<HRegionLocation> regions;
  try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) {
    regions = locator.getAllRegionLocations();
  }
  HRegionLocation location = regions.get(0);
  final HRegionInfo hri = location.getRegionInfo();
  final ServerName server = location.getServerName();
  AccessTestAction action = new AccessTestAction() {
    @Override
    public Object run() throws Exception {
      ACCESS_CONTROLLER.preMove(ObserverContext.createAndPrepare(CP_ENV, null),
          hri, server, server);
      return null;
    }
  };

  verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN);
  verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ,
    USER_GROUP_WRITE, USER_GROUP_CREATE);
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:23,代码来源:TestAccessController.java

示例4: testShutdownOfReplicaHolder

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
@Test
public void testShutdownOfReplicaHolder() throws Exception {
  // checks that the when the server holding meta replica is shut down, the meta replica
  // can be recovered
  RegionLocations rl = ConnectionManager.getConnectionInternal(TEST_UTIL.getConfiguration()).
      locateRegion(TableName.META_TABLE_NAME, Bytes.toBytes(""), false, true);
  HRegionLocation hrl = rl.getRegionLocation(1);
  ServerName oldServer = hrl.getServerName();
  TEST_UTIL.getHBaseClusterInterface().killRegionServer(oldServer);
  int i = 0;
  do {
    LOG.debug("Waiting for the replica " + hrl.getRegionInfo() + " to come up");
    Thread.sleep(30000); //wait for the detection/recovery
    rl = ConnectionManager.getConnectionInternal(TEST_UTIL.getConfiguration()).
        locateRegion(TableName.META_TABLE_NAME, Bytes.toBytes(""), false, true);
    hrl = rl.getRegionLocation(1);
    i++;
  } while ((hrl == null || hrl.getServerName().equals(oldServer)) && i < 3);
  assertTrue(i != 3);
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:21,代码来源:TestMetaWithReplicas.java

示例5: getReplicaLocationOrFail

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
private HRegionLocation getReplicaLocationOrFail(Action<Row> action) {
  // We are going to try get location once again. For each action, we'll do it once
  // from cache, because the previous calls in the loop might populate it.
  int replicaId = action.getReplicaId();
  RegionLocations locs = findAllLocationsOrFail(action, true);
  if (locs == null) return null; // manageError already called
  HRegionLocation loc = locs.getRegionLocation(replicaId);
  if (loc == null || loc.getServerName() == null) {
    locs = findAllLocationsOrFail(action, false);
    if (locs == null) return null; // manageError already called
    loc = locs.getRegionLocation(replicaId);
  }
  if (loc == null || loc.getServerName() == null) {
    manageLocationError(action, null);
    return null;
  }
  return loc;
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:19,代码来源:AsyncProcess.java

示例6: recordMetaRegion

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
/**
 * Record the location of the hbase:meta region as found in ZooKeeper.
 */
private boolean recordMetaRegion() throws IOException {
  RegionLocations rl = ((ClusterConnection)connection).locateRegion(TableName.META_TABLE_NAME,
      HConstants.EMPTY_START_ROW, false, false);
  if (rl == null) {
    errors.reportError(ERROR_CODE.NULL_META_REGION,
        "META region or some of its attributes are null.");
    return false;
  }
  for (HRegionLocation metaLocation : rl.getRegionLocations()) {
    // Check if Meta region is valid and existing
    if (metaLocation == null || metaLocation.getRegionInfo() == null ||
        metaLocation.getHostname() == null) {
      errors.reportError(ERROR_CODE.NULL_META_REGION,
          "META region or some of its attributes are null.");
      return false;
    }
    ServerName sn = metaLocation.getServerName();
    MetaEntry m = new MetaEntry(metaLocation.getRegionInfo(), sn, EnvironmentEdgeManager.currentTime());
    HbckInfo hbckInfo = regionInfoMap.get(metaLocation.getRegionInfo().getEncodedName());
    if (hbckInfo == null) {
      regionInfoMap.put(metaLocation.getRegionInfo().getEncodedName(), new HbckInfo(m));
    } else {
      hbckInfo.metaEntry = m;
    }
  }
  return true;
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:31,代码来源:HBaseFsck.java

示例7: countMetaRegions

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
private static int countMetaRegions(final HMaster master, final TableName tableName)
    throws IOException {
  final AtomicInteger actualRegCount = new AtomicInteger(0);
  final MetaScannerVisitor visitor = new MetaScannerVisitorBase() {
    @Override
    public boolean processRow(Result rowResult) throws IOException {
      RegionLocations list = MetaTableAccessor.getRegionLocations(rowResult);
      if (list == null) {
        LOG.warn("No serialized HRegionInfo in " + rowResult);
        return true;
      }
      HRegionLocation l = list.getRegionLocation();
      if (l == null) {
        return true;
      }
      if (!l.getRegionInfo().getTable().equals(tableName)) {
        return false;
      }
      if (l.getRegionInfo().isOffline() || l.getRegionInfo().isSplit()) return true;
      HRegionLocation[] locations = list.getRegionLocations();
      for (HRegionLocation location : locations) {
        if (location == null) continue;
        ServerName serverName = location.getServerName();
        // Make sure that regions are assigned to server
        if (serverName != null && serverName.getHostAndPort() != null) {
          actualRegCount.incrementAndGet();
        }
      }
      return true;
    }
  };
  MetaScanner.metaScan(master.getConnection(), visitor, tableName);
  return actualRegCount.get();
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:35,代码来源:MasterProcedureTestingUtility.java

示例8: getRegion

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
/**
 * @param regionName Name of a region.
 * @return a pair of HRegionInfo and ServerName if <code>regionName</code> is
 *  a verified region name (we call {@link
 *  MetaTableAccessor#getRegion(HConnection, byte[])}
 *  else null.
 * Throw IllegalArgumentException if <code>regionName</code> is null.
 * @throws IOException
 */
Pair<HRegionInfo, ServerName> getRegion(final byte[] regionName) throws IOException {
  if (regionName == null) {
    throw new IllegalArgumentException("Pass a table name or region name");
  }
  Pair<HRegionInfo, ServerName> pair =
    MetaTableAccessor.getRegion(connection, regionName);
  if (pair == null) {
    final AtomicReference<Pair<HRegionInfo, ServerName>> result =
      new AtomicReference<Pair<HRegionInfo, ServerName>>(null);
    final String encodedName = Bytes.toString(regionName);
    MetaScannerVisitor visitor = new MetaScannerVisitorBase() {
      @Override
      public boolean processRow(Result data) throws IOException {
        HRegionInfo info = HRegionInfo.getHRegionInfo(data);
        if (info == null) {
          LOG.warn("No serialized HRegionInfo in " + data);
          return true;
        }
        RegionLocations rl = MetaTableAccessor.getRegionLocations(data);
        boolean matched = false;
        ServerName sn = null;
        for (HRegionLocation h : rl.getRegionLocations()) {
          if (h != null && encodedName.equals(h.getRegionInfo().getEncodedName())) {
            sn = h.getServerName();
            info = h.getRegionInfo();
            matched = true;
          }
        }
        if (!matched) return true;
        result.set(new Pair<HRegionInfo, ServerName>(info, sn));
        return false; // found the region, stop
      }
    };

    MetaScanner.metaScan(connection, visitor, null);
    pair = result.get();
  }
  return pair;
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:49,代码来源:HBaseAdmin.java

示例9: updateStats

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
public static <T> T updateStats(T r, ServerStatisticTracker stats,
    HRegionLocation regionLocation) {
  byte[] regionName = null;
  ServerName server = null;
  if (regionLocation != null) {
    server = regionLocation.getServerName();
    regionName = regionLocation.getRegionInfo().getRegionName();
  }

  return updateStats(r, stats, server, regionName);
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:12,代码来源:ResultStatsUtil.java

示例10: checkTableInfo

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
void checkTableInfo(TableInfoModel model) {
  assertEquals(model.getName(), TABLE.getNameAsString());
  Iterator<TableRegionModel> regions = model.getRegions().iterator();
  assertTrue(regions.hasNext());
  while (regions.hasNext()) {
    TableRegionModel region = regions.next();
    boolean found = false;
    for (HRegionLocation e: regionMap) {
      HRegionInfo hri = e.getRegionInfo();
      String hriRegionName = hri.getRegionNameAsString();
      String regionName = region.getName();
      if (hriRegionName.equals(regionName)) {
        found = true;
        byte[] startKey = hri.getStartKey();
        byte[] endKey = hri.getEndKey();
        ServerName serverName = e.getServerName();
        InetSocketAddress sa =
            new InetSocketAddress(serverName.getHostname(), serverName.getPort());
        String location = sa.getHostName() + ":" +
          Integer.valueOf(sa.getPort());
        assertEquals(hri.getRegionId(), region.getId());
        assertTrue(Bytes.equals(startKey, region.getStartKey()));
        assertTrue(Bytes.equals(endKey, region.getEndKey()));
        assertEquals(location, region.getLocation());
        break;
      }
    }
    assertTrue(found);
  }
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:31,代码来源:TestTableResource.java

示例11: closeRegion

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
/**
 * Attempts to undeploy a region from a region server based in information in
 * META.  Any operations that modify the file system should make sure that
 * its corresponding region is not deployed to prevent data races.
 *
 * A separate call is required to update the master in-memory region state
 * kept in the AssignementManager.  Because disable uses this state instead of
 * that found in META, we can't seem to cleanly disable/delete tables that
 * have been hbck fixed.  When used on a version of HBase that does not have
 * the offline ipc call exposed on the master (<0.90.5, <0.92.0) a master
 * restart or failover may be required.
 */
private void closeRegion(HbckInfo hi) throws IOException, InterruptedException {
  if (hi.metaEntry == null && hi.hdfsEntry == null) {
    undeployRegions(hi);
    return;
  }

  // get assignment info and hregioninfo from meta.
  Get get = new Get(hi.getRegionName());
  get.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
  get.addColumn(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER);
  get.addColumn(HConstants.CATALOG_FAMILY, HConstants.STARTCODE_QUALIFIER);
  // also get the locations of the replicas to close if the primary region is being closed
  if (hi.getReplicaId() == HRegionInfo.DEFAULT_REPLICA_ID) {
    int numReplicas = admin.getTableDescriptor(hi.getTableName()).getRegionReplication();
    for (int i = 0; i < numReplicas; i++) {
      get.addColumn(HConstants.CATALOG_FAMILY, MetaTableAccessor.getServerColumn(i));
      get.addColumn(HConstants.CATALOG_FAMILY, MetaTableAccessor.getStartCodeColumn(i));
    }
  }
  Result r = meta.get(get);
  RegionLocations rl = MetaTableAccessor.getRegionLocations(r);
  if (rl == null) {
    LOG.warn("Unable to close region " + hi.getRegionNameAsString() +
        " since meta does not have handle to reach it");
    return;
  }
  for (HRegionLocation h : rl.getRegionLocations()) {
    ServerName serverName = h.getServerName();
    if (serverName == null) {
      errors.reportError("Unable to close region "
          + hi.getRegionNameAsString() +  " because meta does not "
          + "have handle to reach it.");
      continue;
    }
    HRegionInfo hri = h.getRegionInfo();
    if (hri == null) {
      LOG.warn("Unable to close region " + hi.getRegionNameAsString()
          + " because hbase:meta had invalid or missing "
          + HConstants.CATALOG_FAMILY_STR + ":"
          + Bytes.toString(HConstants.REGIONINFO_QUALIFIER)
          + " qualifier value.");
      continue;
    }
    // close the region -- close files and remove assignment
    HBaseFsckRepair.closeRegionSilentlyAndWait(connection, serverName, hri);
  }
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:60,代码来源:HBaseFsck.java

示例12: testGlobalAuthorizationForNewRegisteredRS

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
@Test (timeout=180000)
public void testGlobalAuthorizationForNewRegisteredRS() throws Exception {
  LOG.debug("Test for global authorization for a new registered RegionServer.");
  MiniHBaseCluster hbaseCluster = TEST_UTIL.getHBaseCluster();

  final Admin admin = TEST_UTIL.getHBaseAdmin();
  HTableDescriptor htd = new HTableDescriptor(TEST_TABLE2);
  htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
  createTable(TEST_UTIL, htd);

  // Starting a new RegionServer.
  JVMClusterUtil.RegionServerThread newRsThread = hbaseCluster
      .startRegionServer();
  final HRegionServer newRs = newRsThread.getRegionServer();

  // Move region to the new RegionServer.
  List<HRegionLocation> regions;
  try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE2)) {
    regions = locator.getAllRegionLocations();
  }
  HRegionLocation location = regions.get(0);
  final HRegionInfo hri = location.getRegionInfo();
  final ServerName server = location.getServerName();
  try (HTable table = (HTable) systemUserConnection.getTable(TEST_TABLE2)) {
    AccessTestAction moveAction = new AccessTestAction() {
      @Override
      public Object run() throws Exception {
        admin.move(hri.getEncodedNameAsBytes(),
          Bytes.toBytes(newRs.getServerName().getServerName()));
        return null;
      }
    };
    SUPERUSER.runAs(moveAction);

    final int RETRIES_LIMIT = 10;
    int retries = 0;
    while (newRs.getOnlineRegions(TEST_TABLE2).size() < 1 && retries < RETRIES_LIMIT) {
      LOG.debug("Waiting for region to be opened. Already retried " + retries
          + " times.");
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
      }
      retries++;
      if (retries == RETRIES_LIMIT - 1) {
        fail("Retry exhaust for waiting region to be opened.");
      }
    }
    // Verify write permission for user "admin2" who has the global
    // permissions.
    AccessTestAction putAction = new AccessTestAction() {
      @Override
      public Object run() throws Exception {
        Put put = new Put(Bytes.toBytes("test"));
        put.add(TEST_FAMILY, Bytes.toBytes("qual"), Bytes.toBytes("value"));
        table.put(put);
        return null;
      }
    };
    USER_ADMIN.runAs(putAction);
  }
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:63,代码来源:TestAccessController.java

示例13: testOnRegionMove

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
@Test
public void testOnRegionMove() throws Exception {
  // This test is doing near exactly the same thing that testOnRegionChange but avoiding the
  // potential to get a ConnectionClosingException. By moving the region, we can be certain that
  // the connection is still valid and that the implementation is correctly handling an invalid
  // Region cache (and not just tearing down the entire connection).
  TableName TABLE = TableName.valueOf("testOnRegionMove");
  final int NUM_REGIONS = 10;
  HTable htable = TEST_UTIL.createTable(TABLE, new byte[][] { FAMILY }, 3,
    Bytes.toBytes("aaaaa"), Bytes.toBytes("zzzzz"), NUM_REGIONS);

  HTableMultiplexer multiplexer = new HTableMultiplexer(TEST_UTIL.getConfiguration(),
    PER_REGIONSERVER_QUEUE_SIZE);

  final RegionLocator regionLocator = TEST_UTIL.getConnection().getRegionLocator(TABLE);
  Pair<byte[][],byte[][]> startEndRows = regionLocator.getStartEndKeys();
  byte[] row = startEndRows.getFirst()[1];
  assertTrue("2nd region should not start with empty row", row != null && row.length > 0);

  Put put = new Put(row).addColumn(FAMILY, QUALIFIER1, VALUE1);
  assertTrue("multiplexer.put returns", multiplexer.put(TABLE, put));

  checkExistence(htable, row, FAMILY, QUALIFIER1, VALUE1);

  final HRegionLocation loc = regionLocator.getRegionLocation(row);
  final MiniHBaseCluster hbaseCluster = TEST_UTIL.getHBaseCluster();
  // The current server for the region we're writing to
  final ServerName originalServer = loc.getServerName();
  ServerName newServer = null;
  // Find a new server to move that region to
  for (int i = 0; i < SLAVES; i++) {
    HRegionServer rs = hbaseCluster.getRegionServer(0);
    if (!rs.getServerName().equals(originalServer.getServerName())) {
      newServer = rs.getServerName();
      break;
    }
  }
  assertNotNull("Did not find a new RegionServer to use", newServer);

  // Move the region
  LOG.info("Moving " + loc.getRegionInfo().getEncodedName() + " from " + originalServer
      +  " to " + newServer);
  TEST_UTIL.getHBaseAdmin().move(loc.getRegionInfo().getEncodedNameAsBytes(),
      Bytes.toBytes(newServer.getServerName()));

  TEST_UTIL.waitUntilAllRegionsAssigned(TABLE);

  // Send a new Put
  put = new Put(row).addColumn(FAMILY, QUALIFIER2, VALUE2);
  assertTrue("multiplexer.put returns", multiplexer.put(TABLE, put));

  // We should see the update make it to the new server eventually
  checkExistence(htable, row, FAMILY, QUALIFIER2, VALUE2);
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:55,代码来源:TestHTableMultiplexerFlushCache.java

示例14: waitForAllRegionsOnline

import org.apache.hadoop.hbase.HRegionLocation; //导入方法依赖的package包/类
private void waitForAllRegionsOnline(final long deadlineTs)
    throws IOException, TimeoutException {
  final AtomicInteger actualRegCount = new AtomicInteger(0);
  final MetaScannerVisitor visitor = new MetaScannerVisitorBase() {
    @Override
    public boolean processRow(Result rowResult) throws IOException {
      RegionLocations list = MetaTableAccessor.getRegionLocations(rowResult);
      if (list == null) {
        LOG.warn("No serialized HRegionInfo in " + rowResult);
        return true;
      }
      HRegionLocation l = list.getRegionLocation();
      if (l == null) {
        return true;
      }
      if (!l.getRegionInfo().getTable().equals(desc.getTableName())) {
        return false;
      }
      if (l.getRegionInfo().isOffline() || l.getRegionInfo().isSplit()) return true;
      HRegionLocation[] locations = list.getRegionLocations();
      for (HRegionLocation location : locations) {
        if (location == null) continue;
        ServerName serverName = location.getServerName();
        // Make sure that regions are assigned to server
        if (serverName != null && serverName.getHostAndPort() != null) {
          actualRegCount.incrementAndGet();
        }
      }
      return true;
    }
  };

  int tries = 0;
  IOException serverEx = null;
  int numRegs = (splitKeys == null ? 1 : splitKeys.length + 1) * desc.getRegionReplication();
  while (EnvironmentEdgeManager.currentTime() < deadlineTs) {
    actualRegCount.set(0);
    MetaScanner.metaScan(getAdmin().getConnection(), visitor, desc.getTableName());
    if (actualRegCount.get() == numRegs) {
      // all the regions are online
      return;
    }

    try {
      Thread.sleep(getAdmin().getPauseTime(tries++));
    } catch (InterruptedException e) {
      throw new InterruptedIOException("Interrupted when opening" +
        " regions; " + actualRegCount.get() + " of " + numRegs +
        " regions processed so far");
    }
  }
  throw new TimeoutException("Only " + actualRegCount.get() +
          " of " + numRegs + " regions are online; retries exhausted.");
}
 
开发者ID:fengchen8086,项目名称:ditb,代码行数:55,代码来源:HBaseAdmin.java


注:本文中的org.apache.hadoop.hbase.HRegionLocation.getServerName方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。